go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/llx/builtin_array.go (about) 1 // Copyright (c) Mondoo, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package llx 5 6 import ( 7 "errors" 8 "strconv" 9 10 "go.mondoo.com/cnquery/types" 11 "go.mondoo.com/cnquery/utils/multierr" 12 ) 13 14 var arrayBlockType = types.Array(types.Block) 15 16 // arrayFunctions are all the handlers for builtin array methods 17 var arrayFunctions map[string]chunkHandlerV2 18 19 func arrayGetFirstIndexV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 20 if bind.Value == nil { 21 return &RawData{Type: bind.Type[1:]}, 0, nil 22 } 23 24 arr, ok := bind.Value.([]interface{}) 25 if !ok { 26 return nil, 0, errors.New("failed to typecast " + bind.Type.Label() + " into array") 27 } 28 29 if len(arr) == 0 { 30 return &RawData{Type: bind.Type[1:]}, 0, nil 31 } 32 33 return &RawData{ 34 Type: bind.Type[1:], 35 Value: arr[0], 36 }, 0, nil 37 } 38 39 func arrayGetLastIndexV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 40 if bind.Value == nil { 41 return &RawData{Type: bind.Type[1:]}, 0, nil 42 } 43 44 arr, ok := bind.Value.([]interface{}) 45 if !ok { 46 return nil, 0, errors.New("failed to typecast " + bind.Type.Label() + " into array") 47 } 48 49 if len(arr) == 0 { 50 return &RawData{Type: bind.Type[1:]}, 0, nil 51 } 52 53 return &RawData{ 54 Type: bind.Type[1:], 55 Value: arr[len(arr)-1], 56 }, 0, nil 57 } 58 59 func arrayGetIndexV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 60 if bind.Value == nil { 61 return &RawData{Type: bind.Type[1:]}, 0, nil 62 } 63 64 args := chunk.Function.Args 65 // TODO: all this needs to go into the compile phase 66 if len(args) < 1 { 67 return nil, 0, errors.New("Called [] with " + strconv.Itoa(len(args)) + " arguments, only 1 supported.") 68 } 69 if len(args) > 1 { 70 return nil, 0, errors.New("called [] with " + strconv.Itoa(len(args)) + " arguments, only 1 supported.") 71 } 72 t := types.Type(args[0].Type) 73 if t != types.Int { 74 return nil, 0, errors.New("called [] with wrong type " + t.Label()) 75 } 76 // ^^ TODO 77 78 key := int(bytes2int(args[0].Value)) 79 80 arr, ok := bind.Value.([]interface{}) 81 if !ok { 82 return nil, 0, errors.New("failed to typecast " + bind.Type.Label() + " into array") 83 } 84 85 if key < 0 { 86 if -key > len(arr) { 87 return nil, 0, errors.New("array index out of bound (trying to access element " + strconv.Itoa(key) + ", max: " + strconv.Itoa(len(arr)-1) + ")") 88 } 89 key = len(arr) + key 90 } 91 if key >= len(arr) { 92 return nil, 0, errors.New("array index out of bound (trying to access element " + strconv.Itoa(key) + ", max: " + strconv.Itoa(len(arr)-1) + ")") 93 } 94 95 return &RawData{ 96 Type: bind.Type[1:], 97 Value: arr[key], 98 }, 0, nil 99 } 100 101 func arrayBlockListV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 102 if bind.Value == nil { 103 return &RawData{Type: bind.Type[1:]}, 0, nil 104 } 105 106 arr, ok := bind.Value.([]interface{}) 107 if !ok { 108 return nil, 0, errors.New("failed to typecast " + bind.Type.Label() + " into array") 109 } 110 111 if len(arr) == 0 { 112 return &RawData{ 113 Type: arrayBlockType, 114 Value: []interface{}{}, 115 }, 0, nil 116 } 117 118 prim := chunk.Function.Args[0] 119 if !types.Type(prim.Type).IsFunction() { 120 return nil, 0, errors.New("called block with wrong function type") 121 } 122 fref, ok := prim.RefV2() 123 if !ok { 124 return nil, 0, errors.New("cannot retrieve function reference on block call") 125 } 126 block := e.ctx.code.Block(fref) 127 if block == nil { 128 return nil, 0, errors.New("block function is nil") 129 } 130 131 dref, err := e.ensureArgsResolved(chunk.Function.Args[1:], ref) 132 if dref != 0 || err != nil { 133 return nil, dref, err 134 } 135 136 argList := make([][]*RawData, len(arr)) 137 for i := range arr { 138 argList[i] = []*RawData{ 139 { 140 Type: bind.Type.Child(), 141 Value: arr[i], 142 }, 143 } 144 } 145 146 err = e.runFunctionBlocks(argList, fref, func(results []arrayBlockCallResult, errs []error) { 147 // This is quite heavy handed. If any of the block calls have an error, the whole 148 // thing becomes errored. If we don't do this, then we can have more fine grained 149 // errors. For example, if only one item in the list has errors, the block for that 150 // item will have an entrypoint with an error 151 var anyError multierr.Errors 152 anyError.Add(errs...) 153 154 allResults := make([]interface{}, len(arr)) 155 for i, rd := range results { 156 allResults[i] = rd.toRawData().Value 157 } 158 159 data := &RawData{ 160 Type: arrayBlockType, 161 Value: allResults, 162 Error: anyError.Deduplicate(), 163 } 164 e.cache.Store(ref, &stepCache{ 165 Result: data, 166 IsStatic: true, 167 }) 168 e.triggerChain(ref, data) 169 }) 170 171 if err != nil { 172 return nil, 0, err 173 } 174 175 return nil, 0, nil 176 } 177 178 func arrayBlockV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 179 prim := chunk.Function.Args[0] 180 if !types.Type(prim.Type).IsFunction() { 181 return nil, 0, errors.New("called block with wrong function type") 182 } 183 return e.runBlock(bind, prim, chunk.Function.Args[1:], ref) 184 } 185 186 func arrayLengthV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 187 if bind.Value == nil { 188 return &RawData{Type: types.Int, Error: bind.Error}, 0, nil 189 } 190 191 arr, ok := bind.Value.([]interface{}) 192 if !ok { 193 return nil, 0, errors.New("failed to typecast " + bind.Type.Label() + " into array") 194 } 195 return IntData(int64(len(arr))), 0, nil 196 } 197 198 func arrayNotEmptyV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 199 if bind.Value == nil { 200 return BoolFalse, 0, nil 201 } 202 203 arr, ok := bind.Value.([]interface{}) 204 if !ok { 205 return nil, 0, errors.New("failed to typecast " + bind.Type.Label() + " into array") 206 } 207 208 if len(arr) == 0 { 209 return BoolFalse, 0, nil 210 } 211 return BoolTrue, 0, nil 212 } 213 214 func _arrayWhereV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64, invert bool) (*RawData, uint64, error) { 215 // where(array, function) 216 itemsRef := chunk.Function.Args[0] 217 items, rref, err := e.resolveValue(itemsRef, ref) 218 if err != nil || rref > 0 { 219 return nil, rref, err 220 } 221 222 if items.Value == nil { 223 return &RawData{Type: items.Type}, 0, nil 224 } 225 226 list := items.Value.([]interface{}) 227 if len(list) == 0 { 228 return items, 0, nil 229 } 230 231 arg1 := chunk.Function.Args[1] 232 if types.Type(arg1.Type).Underlying() != types.FunctionLike { 233 right := arg1.RawData().Value 234 var res []interface{} 235 for i := range list { 236 left := list[i] 237 if left == right { 238 res = append(res, left) 239 } 240 } 241 242 return &RawData{ 243 Type: items.Type, 244 Value: res, 245 }, 0, nil 246 } 247 248 fref, ok := arg1.RefV2() 249 if !ok { 250 return nil, 0, errors.New("Failed to retrieve function reference of 'where' call") 251 } 252 253 dref, err := e.ensureArgsResolved(chunk.Function.Args[2:], ref) 254 if dref != 0 || err != nil { 255 return nil, dref, err 256 } 257 258 ct := items.Type.Child() 259 260 argsList := make([][]*RawData, len(list)) 261 for i := range list { 262 argsList[i] = []*RawData{ 263 { 264 Type: ct, 265 Value: list[i], 266 }, 267 } 268 } 269 err = e.runFunctionBlocks(argsList, fref, func(results []arrayBlockCallResult, errors []error) { 270 resList := []interface{}{} 271 for i, res := range results { 272 isTruthy := res.isTruthy() 273 if isTruthy == !invert { 274 resList = append(resList, list[i]) 275 } 276 } 277 278 data := &RawData{ 279 Type: bind.Type, 280 Value: resList, 281 } 282 e.cache.Store(ref, &stepCache{ 283 Result: data, 284 IsStatic: false, 285 }) 286 e.triggerChain(ref, data) 287 }) 288 289 if err != nil { 290 return nil, 0, err 291 } 292 293 return nil, 0, nil 294 } 295 296 func arrayWhereV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 297 return _arrayWhereV2(e, bind, chunk, ref, false) 298 } 299 300 func arrayWhereNotV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 301 return _arrayWhereV2(e, bind, chunk, ref, true) 302 } 303 304 func arrayAllV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 305 if bind.Value == nil { 306 return &RawData{Type: types.Bool, Error: errors.New("failed to validate all entries (list is null)")}, 0, nil 307 } 308 309 filteredList := bind.Value.([]interface{}) 310 311 if len(filteredList) != 0 { 312 return BoolFalse, 0, nil 313 } 314 return BoolTrue, 0, nil 315 } 316 317 func arrayNoneV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 318 if bind.Value == nil { 319 return &RawData{Type: types.Bool, Error: errors.New("failed to validate all entries (list is null)")}, 0, nil 320 } 321 322 filteredList := bind.Value.([]interface{}) 323 324 if len(filteredList) != 0 { 325 return BoolFalse, 0, nil 326 } 327 return BoolTrue, 0, nil 328 } 329 330 func arrayAnyV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 331 if bind.Value == nil { 332 return &RawData{Type: types.Bool, Error: errors.New("failed to validate all entries (list is null)")}, 0, nil 333 } 334 335 filteredList := bind.Value.([]interface{}) 336 337 if len(filteredList) == 0 { 338 return BoolFalse, 0, nil 339 } 340 return BoolTrue, 0, nil 341 } 342 343 func arrayOneV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 344 if bind.Value == nil { 345 return &RawData{Type: types.Bool, Error: errors.New("failed to validate all entries (list is null)")}, 0, nil 346 } 347 348 filteredList := bind.Value.([]interface{}) 349 350 if len(filteredList) != 1 { 351 return BoolFalse, 0, nil 352 } 353 return BoolTrue, 0, nil 354 } 355 356 func arrayMapV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 357 // map(array, function) 358 itemsRef := chunk.Function.Args[0] 359 items, rref, err := e.resolveValue(itemsRef, ref) 360 if err != nil || rref > 0 { 361 return nil, rref, err 362 } 363 364 if items.Value == nil { 365 return &RawData{Type: items.Type}, 0, nil 366 } 367 368 list := items.Value.([]interface{}) 369 if len(list) == 0 { 370 return items, 0, nil 371 } 372 373 arg1 := chunk.Function.Args[1] 374 fref, ok := arg1.RefV2() 375 if !ok { 376 return nil, 0, errors.New("Failed to retrieve function reference of 'map' call") 377 } 378 379 dref, err := e.ensureArgsResolved(chunk.Function.Args[2:], ref) 380 if dref != 0 || err != nil { 381 return nil, dref, err 382 } 383 384 ct := items.Type.Child() 385 386 argsList := make([][]*RawData, len(list)) 387 for i := range list { 388 argsList[i] = []*RawData{ 389 { 390 Type: ct, 391 Value: list[i], 392 }, 393 } 394 } 395 396 err = e.runFunctionBlocks(argsList, fref, func(results []arrayBlockCallResult, errs []error) { 397 mappedType := types.Unset 398 resList := []interface{}{} 399 f := e.ctx.code.Block(fref) 400 401 epChecksum := e.ctx.code.Checksums[f.Entrypoints[0]] 402 403 for _, res := range results { 404 if epValIface, ok := res.entrypoints[epChecksum]; ok { 405 epVal := epValIface.(*RawData) 406 mappedType = epVal.Type 407 resList = append(resList, epVal.Value) 408 } 409 } 410 411 data := &RawData{ 412 Type: types.Array(mappedType), 413 Value: resList, 414 } 415 e.cache.Store(ref, &stepCache{ 416 Result: data, 417 IsStatic: false, 418 }) 419 e.triggerChain(ref, data) 420 }) 421 422 if err != nil { 423 return nil, 0, err 424 } 425 426 return nil, 0, nil 427 } 428 429 func flatten(v interface{}) []interface{} { 430 list, ok := v.([]interface{}) 431 if !ok { 432 return []interface{}{v} 433 } 434 435 var res []interface{} 436 for i := range list { 437 res = append(res, flatten(list[i])...) 438 } 439 return res 440 } 441 442 func arrayFlat(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 443 if bind.Value == nil { 444 return &RawData{Type: bind.Type, Error: bind.Error}, 0, nil 445 } 446 447 list, ok := bind.Value.([]interface{}) 448 // this should not happen at this point 449 if !ok { 450 return &RawData{Type: bind.Type, Error: errors.New("incorrect type, no array data found")}, 0, nil 451 } 452 453 var res []interface{} 454 for i := range list { 455 res = append(res, flatten(list[i])...) 456 } 457 458 typ := bind.Type 459 for typ.IsArray() { 460 typ = typ.Child() 461 } 462 463 return &RawData{Type: types.Array(typ), Value: res}, 0, nil 464 } 465 466 // Take an array and separate it into a list of unique entries and another 467 // list of only duplicates. The latter list only has every entry appear only 468 // once. 469 func detectDupes(array interface{}, typ types.Type) ([]interface{}, []interface{}, error) { 470 if array == nil { 471 return nil, nil, nil 472 } 473 arr, ok := array.([]interface{}) 474 if !ok { 475 return nil, nil, errors.New("failed to typecast " + typ.Label() + " into array") 476 } 477 478 ct := typ.Child() 479 equalFunc, ok := types.Equal[ct] 480 if !ok { 481 return nil, nil, errors.New("cannot extract duplicates from array, must be a basic type. Try using a field argument.") 482 } 483 484 existing := []interface{}{} 485 duplicates := []interface{}{} 486 var found bool 487 for i := 0; i < len(arr); i++ { 488 left := arr[i] 489 490 for j := range existing { 491 if equalFunc(left, existing[j]) { 492 found = true 493 break 494 } 495 } 496 497 if !found { 498 existing = append(existing, left) 499 continue 500 } 501 502 found = false 503 for j := range duplicates { 504 if equalFunc(left, duplicates[j]) { 505 found = true 506 break 507 } 508 } 509 510 if found { 511 found = false 512 } else { 513 duplicates = append(duplicates, left) 514 } 515 } 516 517 return existing, duplicates, nil 518 } 519 520 // Takes an array of resources and a field, identify duplicates of that field value 521 // Result list is every resource that has duplicates 522 // (there will be at least resources 2 if there is a duplicate field value) 523 func arrayFieldDuplicatesV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 524 // where(array, function) 525 itemsRef := chunk.Function.Args[0] 526 items, rref, err := e.resolveValue(itemsRef, ref) 527 if err != nil || rref > 0 { 528 return nil, rref, err 529 } 530 531 if items.Value == nil { 532 return &RawData{Type: items.Type}, 0, nil 533 } 534 535 list := items.Value.([]interface{}) 536 if len(list) == 0 { 537 return items, 0, nil 538 } 539 540 arg1 := chunk.Function.Args[1] 541 if types.Type(arg1.Type).Underlying() != types.FunctionLike { 542 return nil, 0, errors.New("Expected resource field, unable to get field value from " + types.Type(arg1.Type).Label()) 543 } 544 545 fref, ok := arg1.RefV2() 546 if !ok { 547 return nil, 0, errors.New("Failed to retrieve function reference of 'field duplicates' call") 548 } 549 550 dref, err := e.ensureArgsResolved(chunk.Function.Args[2:], ref) 551 if dref != 0 || err != nil { 552 return nil, dref, err 553 } 554 555 ct := items.Type.Child() 556 557 argsList := make([][]*RawData, len(list)) 558 for i := range list { 559 argsList[i] = []*RawData{ 560 { 561 Type: ct, 562 Value: list[i], 563 }, 564 } 565 } 566 567 err = e.runFunctionBlocks(argsList, fref, func(results []arrayBlockCallResult, errs []error) { 568 f := e.ctx.code.Block(fref) 569 epChecksum := e.ctx.code.Checksums[f.Entrypoints[0]] 570 filteredList := map[int]*RawData{} 571 572 for i, res := range results { 573 rd := res.toRawData() 574 if rd.Error != nil { 575 filteredList[i] = &RawData{ 576 Error: rd.Error, 577 } 578 } else { 579 epVal := res.entrypoints[epChecksum].(*RawData) 580 filteredList[i] = epVal 581 } 582 } 583 584 resList := []interface{}{} 585 586 equalFunc, ok := types.Equal[filteredList[0].Type] 587 if !ok { 588 data := &RawData{ 589 Type: items.Type, 590 Error: errors.New("cannot extract duplicates from array, field must be a basic type"), 591 } 592 e.cache.Store(ref, &stepCache{ 593 Result: data, 594 IsStatic: false, 595 }) 596 e.triggerChain(ref, data) 597 return 598 } 599 600 arr := make([]*RawData, len(list)) 601 for k, v := range filteredList { 602 arr[k] = v 603 } 604 605 // to track values of fields 606 existing := make(map[int]interface{}) 607 // to track index of duplicate resources 608 duplicateIndices := []int{} 609 var found bool 610 var added bool 611 for i := 0; i < len(arr); i++ { 612 left := arr[i].Value 613 614 for j, v := range existing { 615 if equalFunc(left, v) { 616 found = true 617 // Track the index so that we can get the whole resource 618 duplicateIndices = append(duplicateIndices, i) 619 // check if j was already added to our list of indices 620 for di := range duplicateIndices { 621 if j == duplicateIndices[di] { 622 added = true 623 } 624 } 625 if added == false { 626 duplicateIndices = append(duplicateIndices, j) 627 } 628 break 629 } 630 } 631 632 // value not found so we add it to list of things to check for dupes 633 if !found { 634 existing[i] = left 635 } 636 } 637 638 // Once we collect duplicate indices, make a list of resources 639 for i := range duplicateIndices { 640 idx := duplicateIndices[i] 641 resList = append(resList, list[idx]) 642 } 643 644 data := &RawData{ 645 Type: bind.Type, 646 Value: resList, 647 } 648 e.cache.Store(ref, &stepCache{ 649 Result: data, 650 IsStatic: false, 651 }) 652 e.triggerChain(ref, data) 653 }) 654 655 if err != nil { 656 return nil, 0, err 657 } 658 659 return nil, 0, nil 660 } 661 662 func arrayDuplicatesV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 663 if bind.Value == nil { 664 return &RawData{Type: bind.Type, Error: bind.Error}, 0, nil 665 } 666 667 _, dupes, err := detectDupes(bind.Value, bind.Type) 668 if err != nil { 669 return nil, 0, err 670 } 671 672 return &RawData{Type: bind.Type, Value: dupes}, 0, nil 673 } 674 675 func arrayUniqueV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 676 if bind.Value == nil { 677 return &RawData{Type: bind.Type, Error: bind.Error}, 0, nil 678 } 679 680 unique, _, err := detectDupes(bind.Value, bind.Type) 681 if err != nil { 682 return nil, 0, err 683 } 684 685 return &RawData{Type: bind.Type, Value: unique}, 0, nil 686 } 687 688 func arrayDifferenceV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 689 if bind.Value == nil { 690 return &RawData{Type: bind.Type, Error: bind.Error}, 0, nil 691 } 692 693 args := chunk.Function.Args 694 // TODO: all this needs to go into the compile phase 695 if len(args) < 1 { 696 return nil, 0, errors.New("Called `difference` with " + strconv.Itoa(len(args)) + " arguments, only 1 supported.") 697 } 698 if len(args) > 1 { 699 return nil, 0, errors.New("called `difference` with " + strconv.Itoa(len(args)) + " arguments, only 1 supported.") 700 } 701 // ^^ TODO 702 703 argRef := args[0] 704 arg, rref, err := e.resolveValue(argRef, ref) 705 if err != nil || rref > 0 { 706 return nil, rref, err 707 } 708 709 t := types.Type(arg.Type) 710 if t != bind.Type { 711 return nil, 0, errors.New("called `difference` with wrong type (got: " + t.Label() + ", expected:" + bind.Type.Label() + ")") 712 } 713 714 ct := bind.Type.Child() 715 equalFunc, ok := types.Equal[ct] 716 if !ok { 717 return nil, 0, errors.New("cannot compare array entries") 718 } 719 720 org := bind.Value.([]interface{}) 721 filters := arg.Value.([]interface{}) 722 723 var res []interface{} 724 var skip bool 725 for i := range org { 726 skip = false 727 for j := range filters { 728 if equalFunc(org[i], filters[j]) { 729 skip = true 730 break 731 } 732 } 733 734 if !skip { 735 res = append(res, org[i]) 736 } 737 } 738 739 return &RawData{Type: bind.Type, Value: res}, 0, nil 740 } 741 742 func arrayContainsNoneV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 743 if bind.Value == nil { 744 return &RawData{Type: bind.Type, Error: bind.Error}, 0, nil 745 } 746 747 args := chunk.Function.Args 748 // TODO: all this needs to go into the compile phase 749 if len(args) < 1 { 750 return nil, 0, errors.New("Called `arrayContainsNone` with " + strconv.Itoa(len(args)) + " arguments, only 1 supported.") 751 } 752 if len(args) > 1 { 753 return nil, 0, errors.New("called `arrayContainsNone` with " + strconv.Itoa(len(args)) + " arguments, only 1 supported.") 754 } 755 // ^^ TODO 756 757 argRef := args[0] 758 arg, rref, err := e.resolveValue(argRef, ref) 759 if err != nil || rref > 0 { 760 return nil, rref, err 761 } 762 763 t := types.Type(arg.Type) 764 if t != bind.Type { 765 return nil, 0, errors.New("called `arrayNone` with wrong type (got: " + t.Label() + ", expected:" + bind.Type.Label() + ")") 766 } 767 768 ct := bind.Type.Child() 769 equalFunc, ok := types.Equal[ct] 770 if !ok { 771 return nil, 0, errors.New("cannot compare array entries") 772 } 773 774 org := bind.Value.([]interface{}) 775 filters := arg.Value.([]interface{}) 776 777 var res []interface{} 778 for i := range org { 779 for j := range filters { 780 if equalFunc(org[i], filters[j]) { 781 res = append(res, org[i]) 782 } 783 } 784 } 785 786 return &RawData{Type: bind.Type, Value: res}, 0, nil 787 } 788 789 func compileArrayOpArray(op string) func(types.Type, types.Type) (string, error) { 790 return func(left types.Type, right types.Type) (string, error) { 791 name := string(left.Child()) + op + string(right) 792 af := BuiltinFunctionsV2[types.ArrayLike] 793 if _, ok := af[name]; ok { 794 return name, nil 795 } 796 797 if right.IsArray() { 798 return op, nil 799 } 800 801 if right == types.Nil { 802 return op + string(types.Nil), nil 803 } 804 805 return "", errors.New("don't know how to compile " + left.Label() + " " + op + " " + right.Label()) 806 } 807 } 808 809 func compileLogicalArrayOp(underlying types.Type, op string) func(types.Type, types.Type) (string, error) { 810 return func(left types.Type, right types.Type) (string, error) { 811 name := string(types.Any) + op + string(right.Underlying()) 812 af := BuiltinFunctionsV2[underlying] 813 if _, ok := af[name]; ok { 814 return name, nil 815 } 816 817 return "", errors.New("cannot find operation for " + left.Label() + " " + op + " " + right.Label()) 818 } 819 } 820 821 func cmpArrays(left *RawData, right *RawData, f func(interface{}, interface{}) bool) bool { 822 if left.Value == nil { 823 if right.Value == nil { 824 return true 825 } 826 return false 827 } 828 if right == nil || right.Value == nil { 829 return false 830 } 831 832 l := left.Value.([]interface{}) 833 r := right.Value.([]interface{}) 834 835 if len(l) != len(r) { 836 return false 837 } 838 839 for i := range l { 840 if !f(l[i], r[i]) { 841 return false 842 } 843 } 844 845 return true 846 } 847 848 func cmpArrayOne(leftArray *RawData, right *RawData, f func(interface{}, interface{}) bool) bool { 849 l := leftArray.Value.([]interface{}) 850 if len(l) != 1 { 851 return false 852 } 853 return f(l[0], right.Value) 854 } 855 856 // []T -- []T 857 858 func tArrayCmp(left *RawData, right *RawData) func(interface{}, interface{}) bool { 859 return func(a interface{}, b interface{}) bool { 860 if left.Type.Child() != right.Type.Child() { 861 return false 862 } 863 return a == b 864 } 865 } 866 867 func tarrayCmpTarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 868 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 869 return cmpArrays(left, right, tArrayCmp(left, right)) 870 }) 871 } 872 873 func tarrayNotTarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 874 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 875 return cmpArrays(left, right, tArrayCmp(left, right)) 876 }) 877 } 878 879 func tarrayConcatTarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 880 itemsRef := chunk.Function.Args[0] 881 items, rref, err := e.resolveValue(itemsRef, ref) 882 if err != nil || rref > 0 { 883 return nil, rref, err 884 } 885 886 if items.Value == nil { 887 return &RawData{Type: items.Type}, 0, nil 888 } 889 890 v, _ := bind.Value.([]interface{}) 891 if v == nil { 892 if items.Value == nil { 893 return &RawData{Type: bind.Type}, 0, nil 894 } 895 return nil, 0, errors.New("cannot add arrays to null") 896 } 897 898 list := items.Value.([]interface{}) 899 if len(list) == 0 { 900 return items, 0, nil 901 } 902 903 res := make([]interface{}, len(v)+len(list)) 904 var idx int 905 for i := range v { 906 res[idx] = v[i] 907 idx++ 908 } 909 for i := range list { 910 res[idx] = list[i] 911 idx++ 912 } 913 914 return &RawData{ 915 Type: bind.Type, 916 Value: res, 917 }, 0, nil 918 } 919 920 func tarrayDeleteTarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 921 itemsRef := chunk.Function.Args[0] 922 items, rref, err := e.resolveValue(itemsRef, ref) 923 if err != nil || rref > 0 { 924 return nil, rref, err 925 } 926 927 if items.Value == nil { 928 return &RawData{Type: items.Type}, 0, nil 929 } 930 931 v, _ := bind.Value.([]interface{}) 932 if v == nil { 933 if items.Value == nil { 934 return &RawData{Type: bind.Type}, 0, nil 935 } 936 return nil, 0, errors.New("cannot add arrays to null") 937 } 938 939 list := items.Value.([]interface{}) 940 if len(list) == 0 { 941 return items, 0, nil 942 } 943 944 // TODO: We can optimize the way the deletion works, but need to map to 945 // recognized types to do so. Common example: strings an numbers. 946 947 res := []interface{}{} 948 for i := range v { 949 found := false 950 for j := range list { 951 if v[i] == list[j] { 952 found = true 953 break 954 } 955 } 956 957 if !found { 958 res = append(res, v[i]) 959 } 960 } 961 962 return &RawData{ 963 Type: bind.Type, 964 Value: res, 965 }, 0, nil 966 } 967 968 func boolarrayCmpBoolarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 969 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 970 return cmpArrays(left, right, opBoolCmpBool) 971 }) 972 } 973 974 func intarrayCmpIntarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 975 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 976 return cmpArrays(left, right, opIntCmpInt) 977 }) 978 } 979 980 func floatarrayCmpFloatarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 981 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 982 return cmpArrays(left, right, opFloatCmpFloat) 983 }) 984 } 985 986 func stringarrayCmpStringarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 987 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 988 return cmpArrays(left, right, opStringCmpString) 989 }) 990 } 991 992 func boolarrayNotBoolarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 993 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 994 return cmpArrays(left, right, opBoolCmpBool) 995 }) 996 } 997 998 func intarrayNotIntarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 999 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1000 return cmpArrays(left, right, opIntCmpInt) 1001 }) 1002 } 1003 1004 func floatarrayNotFloatarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1005 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1006 return cmpArrays(left, right, opFloatCmpFloat) 1007 }) 1008 } 1009 1010 func stringarrayNotStringarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1011 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1012 return cmpArrays(left, right, opStringCmpString) 1013 }) 1014 } 1015 1016 // []T -- T 1017 1018 func arrayCmpNilV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1019 if bind.Value == nil { 1020 return BoolTrue, 0, nil 1021 } 1022 v := bind.Value.([]interface{}) 1023 if v == nil { 1024 return BoolTrue, 0, nil 1025 } 1026 return BoolFalse, 0, nil 1027 } 1028 1029 func arrayNotNilV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1030 if bind.Value == nil { 1031 return BoolFalse, 0, nil 1032 } 1033 v := bind.Value.([]interface{}) 1034 if v == nil { 1035 return BoolFalse, 0, nil 1036 } 1037 return BoolTrue, 0, nil 1038 } 1039 1040 func arrayCmpEmpty(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1041 if bind.Value == nil { 1042 return BoolTrue, 0, nil 1043 } 1044 v := bind.Value.([]interface{}) 1045 if v == nil { 1046 return BoolTrue, 0, nil 1047 } 1048 return BoolData(len(v) == 0), 0, nil 1049 } 1050 1051 func arrayNotEmpty(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1052 if bind.Value == nil { 1053 return BoolFalse, 0, nil 1054 } 1055 v := bind.Value.([]interface{}) 1056 if v == nil { 1057 return BoolFalse, 0, nil 1058 } 1059 return BoolData(len(v) != 0), 0, nil 1060 } 1061 1062 func boolarrayCmpBoolV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1063 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1064 return cmpArrayOne(left, right, opBoolCmpBool) 1065 }) 1066 } 1067 1068 func boolarrayNotBoolV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1069 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1070 return cmpArrayOne(left, right, opBoolCmpBool) 1071 }) 1072 } 1073 1074 func intarrayCmpIntV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1075 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1076 return cmpArrayOne(left, right, opIntCmpInt) 1077 }) 1078 } 1079 1080 func intarrayNotIntV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1081 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1082 return cmpArrayOne(left, right, opIntCmpInt) 1083 }) 1084 } 1085 1086 func floatarrayCmpFloatV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1087 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1088 return cmpArrayOne(left, right, opFloatCmpFloat) 1089 }) 1090 } 1091 1092 func floatarrayNotFloatV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1093 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1094 return cmpArrayOne(left, right, opFloatCmpFloat) 1095 }) 1096 } 1097 1098 func stringarrayCmpStringV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1099 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1100 return cmpArrayOne(left, right, opStringCmpString) 1101 }) 1102 } 1103 1104 func stringarrayNotStringV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1105 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1106 return cmpArrayOne(left, right, opStringCmpString) 1107 }) 1108 } 1109 1110 // T -- []T 1111 1112 func boolCmpBoolarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1113 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1114 return cmpArrayOne(right, left, opBoolCmpBool) 1115 }) 1116 } 1117 1118 func boolNotBoolarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1119 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1120 return cmpArrayOne(right, left, opBoolCmpBool) 1121 }) 1122 } 1123 1124 func intCmpIntarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1125 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1126 return cmpArrayOne(right, left, opIntCmpInt) 1127 }) 1128 } 1129 1130 func intNotIntarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1131 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1132 return cmpArrayOne(right, left, opIntCmpInt) 1133 }) 1134 } 1135 1136 func floatCmpFloatarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1137 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1138 return cmpArrayOne(right, left, opFloatCmpFloat) 1139 }) 1140 } 1141 1142 func floatNotFloatarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1143 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1144 return cmpArrayOne(right, left, opFloatCmpFloat) 1145 }) 1146 } 1147 1148 func stringCmpStringarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1149 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1150 return cmpArrayOne(right, left, opStringCmpString) 1151 }) 1152 } 1153 1154 func stringNotStringarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1155 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1156 return cmpArrayOne(right, left, opStringCmpString) 1157 }) 1158 } 1159 1160 // int/float -- []T 1161 1162 func intCmpFloatarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1163 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1164 return cmpArrayOne(right, left, opFloatCmpInt) 1165 }) 1166 } 1167 1168 func intNotFloatarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1169 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1170 return cmpArrayOne(right, left, opFloatCmpInt) 1171 }) 1172 } 1173 1174 func floatCmpIntarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1175 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1176 return cmpArrayOne(right, left, opIntCmpFloat) 1177 }) 1178 } 1179 1180 func floatNotIntarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1181 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1182 return cmpArrayOne(right, left, opIntCmpFloat) 1183 }) 1184 } 1185 1186 func intarrayCmpFloatV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1187 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1188 return cmpArrayOne(left, right, opIntCmpFloat) 1189 }) 1190 } 1191 1192 func intarrayNotFloatV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1193 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1194 return cmpArrayOne(left, right, opIntCmpFloat) 1195 }) 1196 } 1197 1198 func floatarrayCmpIntV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1199 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1200 return cmpArrayOne(left, right, opFloatCmpInt) 1201 }) 1202 } 1203 1204 func floatarrayNotIntV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1205 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1206 return cmpArrayOne(left, right, opFloatCmpInt) 1207 }) 1208 } 1209 1210 // string -- []T 1211 1212 func stringCmpBoolarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1213 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1214 return cmpArrayOne(right, left, opBoolCmpString) 1215 }) 1216 } 1217 1218 func stringNotBoolarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1219 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1220 return cmpArrayOne(right, left, opBoolCmpString) 1221 }) 1222 } 1223 1224 func boolarrayCmpStringV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1225 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1226 return cmpArrayOne(left, right, opBoolCmpString) 1227 }) 1228 } 1229 1230 func boolarrayNotStringV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1231 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1232 return cmpArrayOne(left, right, opBoolCmpString) 1233 }) 1234 } 1235 1236 func stringCmpIntarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1237 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1238 return cmpArrayOne(right, left, opIntCmpString) 1239 }) 1240 } 1241 1242 func stringNotIntarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1243 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1244 return cmpArrayOne(right, left, opIntCmpString) 1245 }) 1246 } 1247 1248 func intarrayCmpStringV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1249 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1250 return cmpArrayOne(left, right, opIntCmpString) 1251 }) 1252 } 1253 1254 func intarrayNotStringV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1255 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1256 return cmpArrayOne(left, right, opIntCmpString) 1257 }) 1258 } 1259 1260 func stringCmpFloatarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1261 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1262 return cmpArrayOne(right, left, opFloatCmpString) 1263 }) 1264 } 1265 1266 func stringNotFloatarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1267 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1268 return cmpArrayOne(right, left, opFloatCmpString) 1269 }) 1270 } 1271 1272 func floatarrayCmpStringV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1273 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1274 return cmpArrayOne(left, right, opFloatCmpString) 1275 }) 1276 } 1277 1278 func floatarrayNotStringV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1279 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1280 return cmpArrayOne(left, right, opFloatCmpString) 1281 }) 1282 } 1283 1284 // bool -- []string 1285 1286 func boolCmpStringarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1287 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1288 return cmpArrayOne(right, left, opStringCmpBool) 1289 }) 1290 } 1291 1292 func boolNotStringarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1293 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1294 return cmpArrayOne(right, left, opStringCmpBool) 1295 }) 1296 } 1297 1298 func stringarrayCmpBoolV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1299 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1300 return cmpArrayOne(left, right, opStringCmpBool) 1301 }) 1302 } 1303 1304 func stringarrayNotBoolV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1305 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1306 return cmpArrayOne(left, right, opStringCmpBool) 1307 }) 1308 } 1309 1310 // int -- []string 1311 1312 func intCmpStringarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1313 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1314 return cmpArrayOne(right, left, opStringCmpInt) 1315 }) 1316 } 1317 1318 func intNotStringarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1319 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1320 return cmpArrayOne(right, left, opStringCmpInt) 1321 }) 1322 } 1323 1324 func stringarrayCmpIntV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1325 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1326 return cmpArrayOne(left, right, opStringCmpInt) 1327 }) 1328 } 1329 1330 func stringarrayNotIntV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1331 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1332 return cmpArrayOne(left, right, opStringCmpInt) 1333 }) 1334 } 1335 1336 // float -- []string 1337 1338 func floatCmpStringarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1339 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1340 return cmpArrayOne(right, left, opStringCmpFloat) 1341 }) 1342 } 1343 1344 func floatNotStringarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1345 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1346 return cmpArrayOne(right, left, opStringCmpFloat) 1347 }) 1348 } 1349 1350 func stringarrayCmpFloatV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1351 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1352 return cmpArrayOne(left, right, opStringCmpFloat) 1353 }) 1354 } 1355 1356 func stringarrayNotFloatV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1357 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1358 return cmpArrayOne(left, right, opStringCmpFloat) 1359 }) 1360 } 1361 1362 // regex -- []T 1363 1364 func regexCmpStringarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1365 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1366 return cmpArrayOne(right, left, opStringCmpRegex) 1367 }) 1368 } 1369 1370 func regexNotStringarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1371 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1372 return cmpArrayOne(right, left, opStringCmpRegex) 1373 }) 1374 } 1375 1376 func stringarrayCmpRegexV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1377 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1378 return cmpArrayOne(left, right, opStringCmpRegex) 1379 }) 1380 } 1381 1382 func stringarrayNotRegexV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1383 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1384 return cmpArrayOne(left, right, opStringCmpRegex) 1385 }) 1386 } 1387 1388 func regexCmpIntarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1389 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1390 return cmpArrayOne(right, left, opIntCmpRegex) 1391 }) 1392 } 1393 1394 func regexNotIntarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1395 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1396 return cmpArrayOne(right, left, opIntCmpRegex) 1397 }) 1398 } 1399 1400 func intarrayCmpRegexV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1401 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1402 return cmpArrayOne(left, right, opIntCmpRegex) 1403 }) 1404 } 1405 1406 func intarrayNotRegexV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1407 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1408 return cmpArrayOne(left, right, opIntCmpRegex) 1409 }) 1410 } 1411 1412 func regexCmpFloatarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1413 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1414 return cmpArrayOne(right, left, opFloatCmpRegex) 1415 }) 1416 } 1417 1418 func regexNotFloatarrayV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1419 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1420 return cmpArrayOne(right, left, opFloatCmpRegex) 1421 }) 1422 } 1423 1424 func floatarrayCmpRegexV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1425 return rawboolOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1426 return cmpArrayOne(left, right, opFloatCmpRegex) 1427 }) 1428 } 1429 1430 func floatarrayNotRegexV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) { 1431 return rawboolNotOpV2(e, bind, chunk, ref, func(left *RawData, right *RawData) bool { 1432 return cmpArrayOne(left, right, opFloatCmpRegex) 1433 }) 1434 }