github.com/mithrandie/csvq@v1.18.1/lib/query/eval_test.go (about) 1 package query 2 3 import ( 4 "context" 5 "math" 6 "os" 7 "reflect" 8 "sync" 9 "testing" 10 "time" 11 12 "github.com/mithrandie/csvq/lib/parser" 13 "github.com/mithrandie/csvq/lib/value" 14 "github.com/mithrandie/ternary" 15 ) 16 17 var evaluateTests = []struct { 18 Name string 19 Scope *ReferenceScope 20 Expr parser.QueryExpression 21 ReplaceValues *ReplaceValues 22 Result value.Primary 23 Error string 24 }{ 25 { 26 Name: "nil", 27 Expr: nil, 28 Result: value.NewTernary(ternary.TRUE), 29 }, 30 { 31 Name: "PrimitiveType", 32 Expr: parser.NewStringValue("str"), 33 Result: value.NewString("str"), 34 }, 35 { 36 Name: "Invalid Value Error", 37 Expr: parser.AllColumns{}, 38 Error: "*: cannot evaluate as a value", 39 }, 40 { 41 Name: "Parentheses", 42 Expr: parser.Parentheses{ 43 Expr: parser.NewStringValue("str"), 44 }, 45 Result: value.NewString("str"), 46 }, 47 { 48 Name: "FieldReference", 49 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 50 { 51 view: &View{ 52 Header: NewHeaderWithId("table1", []string{"column1", "column2"}), 53 RecordSet: []Record{ 54 NewRecordWithId(1, []value.Primary{ 55 value.NewInteger(1), 56 value.NewString("str"), 57 }), 58 NewRecordWithId(2, []value.Primary{ 59 value.NewInteger(2), 60 value.NewString("strstr"), 61 }), 62 }, 63 }, 64 recordIndex: 1, 65 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 66 }, 67 }), 68 Expr: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}, 69 Result: value.NewString("strstr"), 70 }, 71 { 72 Name: "FieldReference ColumnNotExist Error", 73 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 74 { 75 view: &View{ 76 Header: NewHeaderWithId("table1", []string{"column1", "column2"}), 77 RecordSet: []Record{ 78 NewRecordWithId(1, []value.Primary{ 79 value.NewInteger(1), 80 value.NewString("str"), 81 }), 82 NewRecordWithId(2, []value.Primary{ 83 value.NewInteger(2), 84 value.NewString("strstr"), 85 }), 86 }, 87 }, 88 recordIndex: 1, 89 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 90 }, 91 }), 92 Expr: parser.FieldReference{Column: parser.Identifier{Literal: "column3"}}, 93 Error: "field column3 does not exist", 94 }, 95 { 96 Name: "FieldReference FieldAmbigous Error", 97 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 98 { 99 view: &View{ 100 Header: NewHeaderWithId("table1", []string{"column1", "column1"}), 101 RecordSet: []Record{ 102 NewRecordWithId(1, []value.Primary{ 103 value.NewInteger(1), 104 value.NewString("str"), 105 }), 106 NewRecordWithId(2, []value.Primary{ 107 value.NewInteger(2), 108 value.NewString("strstr"), 109 }), 110 }, 111 }, 112 recordIndex: 1, 113 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 114 }, 115 }), 116 Expr: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}, 117 Error: "field column1 is ambiguous", 118 }, 119 { 120 Name: "FieldReference Not Group Key Error", 121 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 122 { 123 view: &View{ 124 Header: []HeaderField{ 125 { 126 View: "table1", 127 Column: "column1", 128 IsFromTable: true, 129 }, 130 { 131 View: "table1", 132 Column: "column2", 133 }, 134 }, 135 RecordSet: []Record{ 136 { 137 NewGroupCell([]value.Primary{ 138 value.NewInteger(1), 139 value.NewInteger(2), 140 }), 141 }, 142 { 143 NewGroupCell([]value.Primary{ 144 value.NewString("str1"), 145 value.NewString("str2"), 146 }), 147 }, 148 }, 149 isGrouped: true, 150 }, 151 recordIndex: 0, 152 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 153 }, 154 }), 155 Expr: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}, 156 Error: "field column1 is not a group key", 157 }, 158 { 159 Name: "ColumnNumber", 160 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 161 { 162 view: &View{ 163 Header: NewHeaderWithId("table1", []string{"column1", "column2"}), 164 RecordSet: []Record{ 165 NewRecordWithId(1, []value.Primary{ 166 value.NewInteger(1), 167 value.NewString("str"), 168 }), 169 NewRecordWithId(2, []value.Primary{ 170 value.NewInteger(2), 171 value.NewString("strstr"), 172 }), 173 }, 174 }, 175 recordIndex: 1, 176 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 177 }, 178 }), 179 Expr: parser.ColumnNumber{View: parser.Identifier{Literal: "table1"}, Number: value.NewInteger(2)}, 180 Result: value.NewString("strstr"), 181 }, 182 { 183 Name: "ColumnNumber Not Exist Error", 184 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 185 { 186 view: &View{ 187 Header: NewHeaderWithId("table1", []string{"column1", "column2"}), 188 RecordSet: []Record{ 189 NewRecordWithId(1, []value.Primary{ 190 value.NewInteger(1), 191 value.NewString("str"), 192 }), 193 NewRecordWithId(2, []value.Primary{ 194 value.NewInteger(2), 195 value.NewString("strstr"), 196 }), 197 }, 198 }, 199 recordIndex: 1, 200 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 201 }, 202 }), 203 Expr: parser.ColumnNumber{View: parser.Identifier{Literal: "table1"}, Number: value.NewInteger(9)}, 204 Error: "field table1.9 does not exist", 205 }, 206 { 207 Name: "ColumnNumber Not Group Key Error", 208 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 209 { 210 view: &View{ 211 Header: []HeaderField{ 212 { 213 View: "table1", 214 Column: "column1", 215 Number: 1, 216 IsFromTable: true, 217 }, 218 { 219 View: "table1", 220 Column: "column2", 221 Number: 2, 222 IsFromTable: true, 223 IsGroupKey: true, 224 }, 225 }, 226 RecordSet: []Record{ 227 { 228 NewGroupCell([]value.Primary{ 229 value.NewInteger(1), 230 value.NewInteger(2), 231 }), 232 }, 233 { 234 NewGroupCell([]value.Primary{ 235 value.NewString("str1"), 236 value.NewString("str2"), 237 }), 238 }, 239 }, 240 isGrouped: true, 241 }, 242 recordIndex: 0, 243 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 244 }, 245 }), 246 Expr: parser.ColumnNumber{View: parser.Identifier{Literal: "table1"}, Number: value.NewInteger(1)}, 247 Error: "field table1.1 is not a group key", 248 }, 249 { 250 Name: "Arithmetic", 251 Expr: parser.Arithmetic{ 252 LHS: parser.NewIntegerValue(1), 253 RHS: parser.NewIntegerValue(2), 254 Operator: parser.Token{Token: '+', Literal: "+"}, 255 }, 256 Result: value.NewInteger(3), 257 }, 258 { 259 Name: "Arithmetic LHS Error", 260 Expr: parser.Arithmetic{ 261 LHS: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 262 RHS: parser.NewIntegerValue(2), 263 Operator: parser.Token{Token: '+', Literal: "+"}, 264 }, 265 Error: "field notexist does not exist", 266 }, 267 { 268 Name: "Arithmetic LHS Is Null", 269 Expr: parser.Arithmetic{ 270 LHS: parser.NewNullValue(), 271 RHS: parser.NewIntegerValue(2), 272 Operator: parser.Token{Token: '+', Literal: "+"}, 273 }, 274 Result: value.NewNull(), 275 }, 276 { 277 Name: "Arithmetic RHS Error", 278 Expr: parser.Arithmetic{ 279 LHS: parser.NewIntegerValue(1), 280 RHS: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 281 Operator: parser.Token{Token: '+', Literal: "+"}, 282 }, 283 Error: "field notexist does not exist", 284 }, 285 { 286 Name: "Arithmetic Division by Zero Error", 287 Expr: parser.Arithmetic{ 288 LHS: parser.NewIntegerValue(1), 289 RHS: parser.NewIntegerValue(0), 290 Operator: parser.Token{Token: '/', Literal: "/"}, 291 }, 292 Error: "integer divided by zero", 293 }, 294 { 295 Name: "UnaryArithmetic Integer", 296 Expr: parser.UnaryArithmetic{ 297 Operand: parser.NewIntegerValue(1), 298 Operator: parser.Token{Token: '-', Literal: "-"}, 299 }, 300 Result: value.NewInteger(-1), 301 }, 302 { 303 Name: "UnaryArithmetic Float", 304 Expr: parser.UnaryArithmetic{ 305 Operand: parser.NewFloatValue(1.234), 306 Operator: parser.Token{Token: '-', Literal: "-"}, 307 }, 308 Result: value.NewFloat(-1.234), 309 }, 310 { 311 Name: "UnaryArithmetic Operand Error", 312 Expr: parser.UnaryArithmetic{ 313 Operand: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 314 Operator: parser.Token{Token: '-', Literal: "-"}, 315 }, 316 Error: "field notexist does not exist", 317 }, 318 { 319 Name: "UnaryArithmetic Cast Failure", 320 Expr: parser.UnaryArithmetic{ 321 Operand: parser.NewStringValue("str"), 322 Operator: parser.Token{Token: '-', Literal: "-"}, 323 }, 324 Result: value.NewNull(), 325 }, 326 { 327 Name: "Concat", 328 Expr: parser.Concat{ 329 Items: []parser.QueryExpression{ 330 parser.NewStringValue("a"), 331 parser.NewStringValue("b"), 332 parser.NewStringValue("c"), 333 }, 334 }, 335 Result: value.NewString("abc"), 336 }, 337 { 338 Name: "Concat FieldNotExist Error", 339 Expr: parser.Concat{ 340 Items: []parser.QueryExpression{ 341 parser.NewStringValue("a"), 342 parser.NewStringValue("b"), 343 parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 344 }, 345 }, 346 Error: "field notexist does not exist", 347 }, 348 { 349 Name: "Concat Including Null", 350 Expr: parser.Concat{ 351 Items: []parser.QueryExpression{ 352 parser.NewStringValue("a"), 353 parser.NewNullValue(), 354 parser.NewStringValue("c"), 355 }, 356 }, 357 Result: value.NewNull(), 358 }, 359 { 360 Name: "Comparison", 361 Expr: parser.Comparison{ 362 LHS: parser.NewIntegerValue(1), 363 RHS: parser.NewIntegerValue(2), 364 Operator: parser.Token{Token: '=', Literal: "="}, 365 }, 366 Result: value.NewTernary(ternary.FALSE), 367 }, 368 { 369 Name: "Comparison With Single RowValue", 370 Expr: parser.Comparison{ 371 LHS: parser.RowValue{Value: parser.ValueList{Values: []parser.QueryExpression{parser.NewStringValue("2")}}}, 372 RHS: parser.NewIntegerValue(2), 373 Operator: parser.Token{Token: '=', Literal: "="}, 374 }, 375 Result: value.NewTernary(ternary.TRUE), 376 }, 377 { 378 Name: "Comparison LHS Error", 379 Expr: parser.Comparison{ 380 LHS: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 381 RHS: parser.NewIntegerValue(2), 382 Operator: parser.Token{Token: '=', Literal: "="}, 383 }, 384 Error: "field notexist does not exist", 385 }, 386 { 387 Name: "Comparison LHS Is Null", 388 Expr: parser.Comparison{ 389 LHS: parser.NewNullValue(), 390 RHS: parser.NewIntegerValue(2), 391 Operator: parser.Token{Token: '=', Literal: "="}, 392 }, 393 Result: value.NewTernary(ternary.UNKNOWN), 394 }, 395 { 396 Name: "Comparison RHS Error", 397 Expr: parser.Comparison{ 398 LHS: parser.NewIntegerValue(1), 399 RHS: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 400 Operator: parser.Token{Token: '=', Literal: "="}, 401 }, 402 Error: "field notexist does not exist", 403 }, 404 { 405 Name: "Comparison with Row Values", 406 Expr: parser.Comparison{ 407 LHS: parser.RowValue{ 408 Value: parser.ValueList{ 409 Values: []parser.QueryExpression{ 410 parser.NewIntegerValue(1), 411 parser.NewIntegerValue(2), 412 }, 413 }, 414 }, 415 RHS: parser.RowValue{ 416 Value: parser.ValueList{ 417 Values: []parser.QueryExpression{ 418 parser.NewIntegerValue(1), 419 parser.NewIntegerValue(2), 420 }, 421 }, 422 }, 423 Operator: parser.Token{Token: '=', Literal: "="}, 424 }, 425 Result: value.NewTernary(ternary.TRUE), 426 }, 427 { 428 Name: "Comparison with Row Value and Subquery", 429 Expr: parser.Comparison{ 430 LHS: parser.RowValue{ 431 Value: parser.ValueList{ 432 Values: []parser.QueryExpression{ 433 parser.NewStringValue("1"), 434 parser.NewStringValue("str1"), 435 }, 436 }, 437 }, 438 RHS: parser.RowValue{ 439 Value: parser.Subquery{ 440 Query: parser.SelectQuery{ 441 SelectEntity: parser.SelectEntity{ 442 SelectClause: parser.SelectClause{ 443 Fields: []parser.QueryExpression{ 444 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 445 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}}, 446 }, 447 }, 448 FromClause: parser.FromClause{ 449 Tables: []parser.QueryExpression{ 450 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 451 }, 452 }, 453 WhereClause: parser.WhereClause{ 454 Filter: parser.Comparison{ 455 LHS: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}, 456 RHS: parser.NewIntegerValue(1), 457 Operator: parser.Token{Token: '=', Literal: "="}, 458 }, 459 }, 460 }, 461 }, 462 }, 463 }, 464 Operator: parser.Token{Token: '=', Literal: "="}, 465 }, 466 Result: value.NewTernary(ternary.TRUE), 467 }, 468 { 469 Name: "Comparison with Row Values LHS Error", 470 Expr: parser.Comparison{ 471 LHS: parser.RowValue{ 472 Value: parser.ValueList{ 473 Values: []parser.QueryExpression{ 474 parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 475 parser.NewIntegerValue(2), 476 }, 477 }, 478 }, 479 RHS: parser.RowValue{ 480 Value: parser.ValueList{ 481 Values: []parser.QueryExpression{ 482 parser.NewIntegerValue(1), 483 parser.NewIntegerValue(2), 484 }, 485 }, 486 }, 487 Operator: parser.Token{Token: '=', Literal: "="}, 488 }, 489 Error: "field notexist does not exist", 490 }, 491 { 492 Name: "Comparison with Row Value and Subquery Returns No Record", 493 Expr: parser.Comparison{ 494 LHS: parser.RowValue{ 495 Value: parser.ValueList{ 496 Values: []parser.QueryExpression{ 497 parser.NewStringValue("1"), 498 parser.NewStringValue("str1"), 499 }, 500 }, 501 }, 502 RHS: parser.RowValue{ 503 Value: parser.Subquery{ 504 Query: parser.SelectQuery{ 505 SelectEntity: parser.SelectEntity{ 506 SelectClause: parser.SelectClause{ 507 Fields: []parser.QueryExpression{ 508 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 509 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}}, 510 }, 511 }, 512 FromClause: parser.FromClause{ 513 Tables: []parser.QueryExpression{ 514 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 515 }, 516 }, 517 WhereClause: parser.WhereClause{ 518 Filter: parser.NewTernaryValue(ternary.FALSE), 519 }, 520 }, 521 }, 522 }, 523 }, 524 Operator: parser.Token{Token: '=', Literal: "="}, 525 }, 526 Result: value.NewTernary(ternary.UNKNOWN), 527 }, 528 { 529 Name: "Comparison with Row Value and LHS Subquery Returns No Record", 530 Expr: parser.Comparison{ 531 LHS: parser.RowValue{ 532 Value: parser.Subquery{ 533 Query: parser.SelectQuery{ 534 SelectEntity: parser.SelectEntity{ 535 SelectClause: parser.SelectClause{ 536 Fields: []parser.QueryExpression{ 537 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 538 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}}, 539 }, 540 }, 541 FromClause: parser.FromClause{ 542 Tables: []parser.QueryExpression{ 543 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 544 }, 545 }, 546 WhereClause: parser.WhereClause{ 547 Filter: parser.NewTernaryValue(ternary.FALSE), 548 }, 549 }, 550 }, 551 }, 552 }, 553 RHS: parser.RowValue{ 554 Value: parser.Subquery{ 555 Query: parser.SelectQuery{ 556 SelectEntity: parser.SelectEntity{ 557 SelectClause: parser.SelectClause{ 558 Fields: []parser.QueryExpression{ 559 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 560 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}}, 561 }, 562 }, 563 FromClause: parser.FromClause{ 564 Tables: []parser.QueryExpression{ 565 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 566 }, 567 }, 568 WhereClause: parser.WhereClause{ 569 Filter: parser.NewTernaryValue(ternary.FALSE), 570 }, 571 }, 572 }, 573 }, 574 }, 575 Operator: parser.Token{Token: '=', Literal: "="}, 576 }, 577 Result: value.NewTernary(ternary.UNKNOWN), 578 }, 579 { 580 Name: "Comparison with Row Value and Subquery Query Error", 581 Expr: parser.Comparison{ 582 LHS: parser.RowValue{ 583 Value: parser.ValueList{ 584 Values: []parser.QueryExpression{ 585 parser.NewStringValue("1"), 586 parser.NewStringValue("str1"), 587 }, 588 }, 589 }, 590 RHS: parser.RowValue{ 591 Value: parser.Subquery{ 592 Query: parser.SelectQuery{ 593 SelectEntity: parser.SelectEntity{ 594 SelectClause: parser.SelectClause{ 595 Fields: []parser.QueryExpression{ 596 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 597 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}}, 598 }, 599 }, 600 FromClause: parser.FromClause{ 601 Tables: []parser.QueryExpression{ 602 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 603 }, 604 }, 605 }, 606 }, 607 }, 608 }, 609 Operator: parser.Token{Token: '=', Literal: "="}, 610 }, 611 Error: "field notexist does not exist", 612 }, 613 { 614 Name: "Comparison with Row Values RHS Error", 615 Expr: parser.Comparison{ 616 LHS: parser.RowValue{ 617 Value: parser.ValueList{ 618 Values: []parser.QueryExpression{ 619 parser.NewIntegerValue(1), 620 parser.NewIntegerValue(2), 621 }, 622 }, 623 }, 624 RHS: parser.RowValue{ 625 Value: parser.Subquery{ 626 Query: parser.SelectQuery{ 627 SelectEntity: parser.SelectEntity{ 628 SelectClause: parser.SelectClause{ 629 Fields: []parser.QueryExpression{ 630 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 631 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}}, 632 }, 633 }, 634 FromClause: parser.FromClause{ 635 Tables: []parser.QueryExpression{ 636 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 637 }, 638 }, 639 }, 640 }, 641 }, 642 }, 643 Operator: parser.Token{Token: '=', Literal: "="}, 644 }, 645 Error: "subquery returns too many records, should return only one record", 646 }, 647 { 648 Name: "Comparison with Row Values Value Length Not Match Error", 649 Expr: parser.Comparison{ 650 LHS: parser.RowValue{ 651 Value: parser.ValueList{ 652 Values: []parser.QueryExpression{ 653 parser.NewIntegerValue(1), 654 parser.NewIntegerValue(2), 655 }, 656 }, 657 }, 658 RHS: parser.RowValue{ 659 Value: parser.ValueList{ 660 Values: []parser.QueryExpression{ 661 parser.NewIntegerValue(1), 662 }, 663 }, 664 }, 665 Operator: parser.Token{Token: '=', Literal: "="}, 666 }, 667 Error: "row value should contain exactly 2 values", 668 }, 669 { 670 Name: "Comparison with Row Value and JsonQuery", 671 Expr: parser.Comparison{ 672 LHS: parser.RowValue{ 673 Value: parser.ValueList{ 674 Values: []parser.QueryExpression{ 675 parser.NewStringValue("1"), 676 parser.NewStringValue("str1"), 677 }, 678 }, 679 }, 680 RHS: parser.RowValue{ 681 Value: parser.JsonQuery{ 682 Query: parser.NewStringValue("key{key2, key3}"), 683 JsonText: parser.NewStringValue("{\"key\": {\"key2\": 1, \"key3\": \"str1\"}}"), 684 }, 685 }, 686 Operator: parser.Token{Token: '=', Literal: "="}, 687 }, 688 Result: value.NewTernary(ternary.TRUE), 689 }, 690 { 691 Name: "Comparison with Row Value and JsonQuery Query Evaluation Error", 692 Expr: parser.Comparison{ 693 LHS: parser.RowValue{ 694 Value: parser.ValueList{ 695 Values: []parser.QueryExpression{ 696 parser.NewStringValue("1"), 697 parser.NewStringValue("str1"), 698 }, 699 }, 700 }, 701 RHS: parser.RowValue{ 702 Value: parser.JsonQuery{ 703 Query: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 704 JsonText: parser.NewStringValue("{\"key\": {\"key2\": 1, \"key3\": \"str1\"}}"), 705 }, 706 }, 707 Operator: parser.Token{Token: '=', Literal: "="}, 708 }, 709 Error: "field notexist does not exist", 710 }, 711 { 712 Name: "Comparison with Row Value and JsonQuery Query is Null", 713 Expr: parser.Comparison{ 714 LHS: parser.RowValue{ 715 Value: parser.ValueList{ 716 Values: []parser.QueryExpression{ 717 parser.NewStringValue("1"), 718 parser.NewStringValue("str1"), 719 }, 720 }, 721 }, 722 RHS: parser.RowValue{ 723 Value: parser.JsonQuery{ 724 Query: parser.NewNullValue(), 725 JsonText: parser.NewStringValue("{\"key\": {\"key2\": 1, \"key3\": \"str1\"}}"), 726 }, 727 }, 728 Operator: parser.Token{Token: '=', Literal: "="}, 729 }, 730 Result: value.NewTernary(ternary.UNKNOWN), 731 }, 732 { 733 Name: "Comparison with Row Value and JsonQuery Type Error", 734 Expr: parser.Comparison{ 735 LHS: parser.RowValue{ 736 Value: parser.ValueList{ 737 Values: []parser.QueryExpression{ 738 parser.NewStringValue("1"), 739 parser.NewStringValue("str1"), 740 }, 741 }, 742 }, 743 RHS: parser.RowValue{ 744 Value: parser.JsonQuery{ 745 Query: parser.NewStringValue("key[]"), 746 JsonText: parser.NewStringValue("{\"key\": {\"key2\": 1, \"key3\": \"str1\"}}"), 747 }, 748 }, 749 Operator: parser.Token{Token: '=', Literal: "="}, 750 }, 751 Error: "json loading error: json value must be an array", 752 }, 753 { 754 Name: "Comparison with Row Value and JsonQuery Empty Result Set", 755 Expr: parser.Comparison{ 756 LHS: parser.RowValue{ 757 Value: parser.ValueList{ 758 Values: []parser.QueryExpression{ 759 parser.NewStringValue("1"), 760 parser.NewStringValue("str1"), 761 }, 762 }, 763 }, 764 RHS: parser.RowValue{ 765 Value: parser.JsonQuery{ 766 Query: parser.NewStringValue("key{}"), 767 JsonText: parser.NewStringValue("{\"key\": []}"), 768 }, 769 }, 770 Operator: parser.Token{Token: '=', Literal: "="}, 771 }, 772 Result: value.NewTernary(ternary.UNKNOWN), 773 }, 774 { 775 Name: "Comparison with Row Value and JsonQuery Too Many Records", 776 Expr: parser.Comparison{ 777 LHS: parser.RowValue{ 778 Value: parser.ValueList{ 779 Values: []parser.QueryExpression{ 780 parser.NewStringValue("1"), 781 parser.NewStringValue("str1"), 782 }, 783 }, 784 }, 785 RHS: parser.RowValue{ 786 Value: parser.JsonQuery{ 787 Query: parser.NewStringValue("key{key2, key3}"), 788 JsonText: parser.NewStringValue("{\"key\": [{\"key2\": 1, \"key3\": \"str1\"}, {\"key2\": 1, \"key3\": \"str1\"}] }"), 789 }, 790 }, 791 Operator: parser.Token{Token: '=', Literal: "="}, 792 }, 793 Error: "json query returns too many records, should return only one record", 794 }, 795 { 796 Name: "Is", 797 Expr: parser.Is{ 798 LHS: parser.NewIntegerValue(1), 799 RHS: parser.NewNullValue(), 800 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 801 }, 802 Result: value.NewTernary(ternary.TRUE), 803 }, 804 { 805 Name: "Is LHS Error", 806 Expr: parser.Is{ 807 LHS: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 808 RHS: parser.NewNullValue(), 809 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 810 }, 811 Error: "field notexist does not exist", 812 }, 813 { 814 Name: "Is RHS Error", 815 Expr: parser.Is{ 816 LHS: parser.NewIntegerValue(1), 817 RHS: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 818 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 819 }, 820 Error: "field notexist does not exist", 821 }, 822 { 823 Name: "Between", 824 Expr: parser.Between{ 825 LHS: parser.NewIntegerValue(2), 826 Low: parser.NewIntegerValue(1), 827 High: parser.NewIntegerValue(3), 828 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 829 }, 830 Result: value.NewTernary(ternary.FALSE), 831 }, 832 { 833 Name: "Between LHS Error", 834 Expr: parser.Between{ 835 LHS: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 836 Low: parser.NewIntegerValue(1), 837 High: parser.NewIntegerValue(3), 838 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 839 }, 840 Error: "field notexist does not exist", 841 }, 842 { 843 Name: "Between LHS Is Null", 844 Expr: parser.Between{ 845 LHS: parser.NewNullValue(), 846 Low: parser.NewIntegerValue(1), 847 High: parser.NewIntegerValue(3), 848 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 849 }, 850 Result: value.NewTernary(ternary.UNKNOWN), 851 }, 852 { 853 Name: "Between Low Error", 854 Expr: parser.Between{ 855 LHS: parser.NewIntegerValue(2), 856 Low: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 857 High: parser.NewIntegerValue(3), 858 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 859 }, 860 Error: "field notexist does not exist", 861 }, 862 { 863 Name: "Between Low Comparison False", 864 Expr: parser.Between{ 865 LHS: parser.NewIntegerValue(2), 866 Low: parser.NewIntegerValue(3), 867 High: parser.NewIntegerValue(5), 868 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 869 }, 870 Result: value.NewTernary(ternary.TRUE), 871 }, 872 { 873 Name: "Between High Error", 874 Expr: parser.Between{ 875 LHS: parser.NewIntegerValue(2), 876 Low: parser.NewIntegerValue(1), 877 High: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 878 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 879 }, 880 Error: "field notexist does not exist", 881 }, 882 { 883 Name: "Between with Row Values", 884 Expr: parser.Between{ 885 LHS: parser.RowValue{ 886 Value: parser.ValueList{ 887 Values: []parser.QueryExpression{ 888 parser.NewIntegerValue(1), 889 parser.NewIntegerValue(2), 890 }, 891 }, 892 }, 893 Low: parser.RowValue{ 894 Value: parser.ValueList{ 895 Values: []parser.QueryExpression{ 896 parser.NewIntegerValue(1), 897 parser.NewIntegerValue(1), 898 }, 899 }, 900 }, 901 High: parser.RowValue{ 902 Value: parser.ValueList{ 903 Values: []parser.QueryExpression{ 904 parser.NewIntegerValue(1), 905 parser.NewIntegerValue(3), 906 }, 907 }, 908 }, 909 }, 910 Result: value.NewTernary(ternary.TRUE), 911 }, 912 { 913 Name: "Between with LHS Subquery Returns No Records", 914 Expr: parser.Between{ 915 LHS: parser.RowValue{ 916 Value: parser.Subquery{ 917 Query: parser.SelectQuery{ 918 SelectEntity: parser.SelectEntity{ 919 SelectClause: parser.SelectClause{ 920 Fields: []parser.QueryExpression{ 921 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 922 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}}, 923 }, 924 }, 925 FromClause: parser.FromClause{ 926 Tables: []parser.QueryExpression{ 927 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 928 }, 929 }, 930 WhereClause: parser.WhereClause{ 931 Filter: parser.NewTernaryValue(ternary.FALSE), 932 }, 933 }, 934 }, 935 }, 936 }, 937 Low: parser.RowValue{ 938 Value: parser.ValueList{ 939 Values: []parser.QueryExpression{ 940 parser.NewIntegerValue(1), 941 parser.NewIntegerValue(1), 942 }, 943 }, 944 }, 945 High: parser.RowValue{ 946 Value: parser.ValueList{ 947 Values: []parser.QueryExpression{ 948 parser.NewIntegerValue(1), 949 parser.NewIntegerValue(3), 950 }, 951 }, 952 }, 953 }, 954 Result: value.NewTernary(ternary.UNKNOWN), 955 }, 956 { 957 Name: "Between with Row Values LHS Error", 958 Expr: parser.Between{ 959 LHS: parser.RowValue{ 960 Value: parser.ValueList{ 961 Values: []parser.QueryExpression{ 962 parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 963 parser.NewIntegerValue(2), 964 }, 965 }, 966 }, 967 Low: parser.RowValue{ 968 Value: parser.ValueList{ 969 Values: []parser.QueryExpression{ 970 parser.NewIntegerValue(1), 971 parser.NewIntegerValue(1), 972 }, 973 }, 974 }, 975 High: parser.RowValue{ 976 Value: parser.ValueList{ 977 Values: []parser.QueryExpression{ 978 parser.NewIntegerValue(1), 979 parser.NewIntegerValue(3), 980 }, 981 }, 982 }, 983 }, 984 Error: "field notexist does not exist", 985 }, 986 { 987 Name: "Between with Row Values Low Error", 988 Expr: parser.Between{ 989 LHS: parser.RowValue{ 990 Value: parser.ValueList{ 991 Values: []parser.QueryExpression{ 992 parser.NewIntegerValue(1), 993 parser.NewIntegerValue(2), 994 }, 995 }, 996 }, 997 Low: parser.RowValue{ 998 Value: parser.ValueList{ 999 Values: []parser.QueryExpression{ 1000 parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 1001 parser.NewIntegerValue(1), 1002 }, 1003 }, 1004 }, 1005 High: parser.RowValue{ 1006 Value: parser.ValueList{ 1007 Values: []parser.QueryExpression{ 1008 parser.NewIntegerValue(1), 1009 parser.NewIntegerValue(3), 1010 }, 1011 }, 1012 }, 1013 }, 1014 Error: "field notexist does not exist", 1015 }, 1016 { 1017 Name: "Between with Row Values Low Comparison False", 1018 Expr: parser.Between{ 1019 LHS: parser.RowValue{ 1020 Value: parser.ValueList{ 1021 Values: []parser.QueryExpression{ 1022 parser.NewIntegerValue(1), 1023 parser.NewIntegerValue(2), 1024 }, 1025 }, 1026 }, 1027 Low: parser.RowValue{ 1028 Value: parser.ValueList{ 1029 Values: []parser.QueryExpression{ 1030 parser.NewIntegerValue(1), 1031 parser.NewIntegerValue(3), 1032 }, 1033 }, 1034 }, 1035 High: parser.RowValue{ 1036 Value: parser.ValueList{ 1037 Values: []parser.QueryExpression{ 1038 parser.NewIntegerValue(1), 1039 parser.NewIntegerValue(5), 1040 }, 1041 }, 1042 }, 1043 }, 1044 Result: value.NewTernary(ternary.FALSE), 1045 }, 1046 { 1047 Name: "Between with Row Values High Error", 1048 Expr: parser.Between{ 1049 LHS: parser.RowValue{ 1050 Value: parser.ValueList{ 1051 Values: []parser.QueryExpression{ 1052 parser.NewIntegerValue(1), 1053 parser.NewIntegerValue(2), 1054 }, 1055 }, 1056 }, 1057 Low: parser.RowValue{ 1058 Value: parser.ValueList{ 1059 Values: []parser.QueryExpression{ 1060 parser.NewIntegerValue(1), 1061 parser.NewIntegerValue(1), 1062 }, 1063 }, 1064 }, 1065 High: parser.RowValue{ 1066 Value: parser.ValueList{ 1067 Values: []parser.QueryExpression{ 1068 parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 1069 parser.NewIntegerValue(3), 1070 }, 1071 }, 1072 }, 1073 }, 1074 Error: "field notexist does not exist", 1075 }, 1076 { 1077 Name: "Between with Row Values Low Comparison Error", 1078 Expr: parser.Between{ 1079 LHS: parser.RowValue{ 1080 Value: parser.ValueList{ 1081 Values: []parser.QueryExpression{ 1082 parser.NewIntegerValue(1), 1083 parser.NewIntegerValue(2), 1084 }, 1085 }, 1086 }, 1087 Low: parser.RowValue{ 1088 Value: parser.ValueList{ 1089 Values: []parser.QueryExpression{ 1090 parser.NewIntegerValue(1), 1091 }, 1092 }, 1093 }, 1094 High: parser.RowValue{ 1095 Value: parser.ValueList{ 1096 Values: []parser.QueryExpression{ 1097 parser.NewIntegerValue(1), 1098 parser.NewIntegerValue(3), 1099 }, 1100 }, 1101 }, 1102 }, 1103 Error: "row value should contain exactly 2 values", 1104 }, 1105 { 1106 Name: "Between with Row Values High Comparison Error", 1107 Expr: parser.Between{ 1108 LHS: parser.RowValue{ 1109 Value: parser.ValueList{ 1110 Values: []parser.QueryExpression{ 1111 parser.NewIntegerValue(1), 1112 parser.NewIntegerValue(2), 1113 }, 1114 }, 1115 }, 1116 Low: parser.RowValue{ 1117 Value: parser.ValueList{ 1118 Values: []parser.QueryExpression{ 1119 parser.NewIntegerValue(1), 1120 parser.NewIntegerValue(1), 1121 }, 1122 }, 1123 }, 1124 High: parser.RowValue{ 1125 Value: parser.ValueList{ 1126 Values: []parser.QueryExpression{ 1127 parser.NewIntegerValue(3), 1128 }, 1129 }, 1130 }, 1131 }, 1132 Error: "row value should contain exactly 2 values", 1133 }, 1134 { 1135 Name: "In", 1136 Expr: parser.In{ 1137 LHS: parser.NewIntegerValue(2), 1138 Values: parser.RowValue{ 1139 Value: parser.ValueList{ 1140 Values: []parser.QueryExpression{ 1141 parser.NewIntegerValue(1), 1142 parser.NewIntegerValue(2), 1143 parser.NewIntegerValue(3), 1144 }, 1145 }, 1146 }, 1147 }, 1148 Result: value.NewTernary(ternary.TRUE), 1149 }, 1150 { 1151 Name: "Not In", 1152 Expr: parser.In{ 1153 LHS: parser.NewIntegerValue(2), 1154 Values: parser.RowValue{ 1155 Value: parser.ValueList{ 1156 Values: []parser.QueryExpression{ 1157 parser.NewIntegerValue(1), 1158 parser.NewIntegerValue(2), 1159 parser.NewNullValue(), 1160 }, 1161 }, 1162 }, 1163 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 1164 }, 1165 Result: value.NewTernary(ternary.FALSE), 1166 }, 1167 { 1168 Name: "Not In UNKNOWN", 1169 Expr: parser.In{ 1170 LHS: parser.NewIntegerValue(2), 1171 Values: parser.RowValue{ 1172 Value: parser.ValueList{ 1173 Values: []parser.QueryExpression{ 1174 parser.NewIntegerValue(3), 1175 parser.NewIntegerValue(4), 1176 parser.NewNullValue(), 1177 }, 1178 }, 1179 }, 1180 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 1181 }, 1182 Result: value.NewTernary(ternary.UNKNOWN), 1183 }, 1184 { 1185 Name: "In LHS Error", 1186 Expr: parser.In{ 1187 LHS: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 1188 Values: parser.RowValue{ 1189 Value: parser.ValueList{ 1190 Values: []parser.QueryExpression{ 1191 parser.NewIntegerValue(1), 1192 parser.NewIntegerValue(2), 1193 parser.NewIntegerValue(3), 1194 }, 1195 }, 1196 }, 1197 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 1198 }, 1199 Error: "field notexist does not exist", 1200 }, 1201 { 1202 Name: "In List Error", 1203 Expr: parser.In{ 1204 LHS: parser.NewIntegerValue(2), 1205 Values: parser.RowValue{ 1206 Value: parser.ValueList{ 1207 Values: []parser.QueryExpression{ 1208 parser.NewIntegerValue(1), 1209 parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 1210 parser.NewIntegerValue(3), 1211 }, 1212 }, 1213 }, 1214 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 1215 }, 1216 Error: "field notexist does not exist", 1217 }, 1218 { 1219 Name: "In Subquery", 1220 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 1221 { 1222 view: &View{ 1223 Header: NewHeaderWithId("table2", []string{"column3", "column4"}), 1224 RecordSet: []Record{ 1225 NewRecordWithId(1, []value.Primary{ 1226 value.NewInteger(1), 1227 value.NewString("str2"), 1228 }), 1229 }, 1230 }, 1231 recordIndex: 0, 1232 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 1233 }, 1234 }), 1235 Expr: parser.In{ 1236 LHS: parser.NewIntegerValue(2), 1237 Values: parser.RowValue{ 1238 Value: parser.Subquery{ 1239 Query: parser.SelectQuery{ 1240 SelectEntity: parser.SelectEntity{ 1241 SelectClause: parser.SelectClause{ 1242 Fields: []parser.QueryExpression{ 1243 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 1244 }, 1245 }, 1246 FromClause: parser.FromClause{ 1247 Tables: []parser.QueryExpression{ 1248 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 1249 }, 1250 }, 1251 WhereClause: parser.WhereClause{ 1252 Filter: parser.Comparison{ 1253 LHS: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}, 1254 RHS: parser.FieldReference{View: parser.Identifier{Literal: "table2"}, Column: parser.Identifier{Literal: "column4"}}, 1255 Operator: parser.Token{Token: '=', Literal: "="}, 1256 }, 1257 }, 1258 }, 1259 }, 1260 }, 1261 }, 1262 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 1263 }, 1264 Result: value.NewTernary(ternary.FALSE), 1265 }, 1266 { 1267 Name: "In Subquery Execution Error", 1268 Expr: parser.In{ 1269 LHS: parser.NewIntegerValue(2), 1270 Values: parser.RowValue{ 1271 Value: parser.Subquery{ 1272 Query: parser.SelectQuery{ 1273 SelectEntity: parser.SelectEntity{ 1274 SelectClause: parser.SelectClause{ 1275 Fields: []parser.QueryExpression{ 1276 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 1277 }, 1278 }, 1279 FromClause: parser.FromClause{ 1280 Tables: []parser.QueryExpression{ 1281 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 1282 }, 1283 }, 1284 WhereClause: parser.WhereClause{ 1285 Filter: parser.Comparison{ 1286 LHS: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 1287 RHS: parser.FieldReference{View: parser.Identifier{Literal: "table2"}, Column: parser.Identifier{Literal: "column4"}}, 1288 Operator: parser.Token{Token: '=', Literal: "="}, 1289 }, 1290 }, 1291 }, 1292 }, 1293 }, 1294 }, 1295 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 1296 }, 1297 Error: "field notexist does not exist", 1298 }, 1299 { 1300 Name: "In Subquery Too Many Field Error", 1301 Expr: parser.In{ 1302 LHS: parser.NewIntegerValue(2), 1303 Values: parser.RowValue{ 1304 Value: parser.Subquery{ 1305 Query: parser.SelectQuery{ 1306 SelectEntity: parser.SelectEntity{ 1307 SelectClause: parser.SelectClause{ 1308 Fields: []parser.QueryExpression{ 1309 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 1310 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}}, 1311 }, 1312 }, 1313 FromClause: parser.FromClause{ 1314 Tables: []parser.QueryExpression{ 1315 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 1316 }, 1317 }, 1318 }, 1319 }, 1320 }, 1321 }, 1322 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 1323 }, 1324 Error: "subquery returns too many fields, should return only one field", 1325 }, 1326 { 1327 Name: "In Subquery Returns No Record", 1328 Expr: parser.In{ 1329 LHS: parser.NewIntegerValue(2), 1330 Values: parser.RowValue{ 1331 Value: parser.Subquery{ 1332 Query: parser.SelectQuery{ 1333 SelectEntity: parser.SelectEntity{ 1334 SelectClause: parser.SelectClause{ 1335 Fields: []parser.QueryExpression{ 1336 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 1337 }, 1338 }, 1339 FromClause: parser.FromClause{ 1340 Tables: []parser.QueryExpression{ 1341 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 1342 }, 1343 }, 1344 WhereClause: parser.WhereClause{ 1345 Filter: parser.NewTernaryValue(ternary.FALSE), 1346 }, 1347 }, 1348 }, 1349 }, 1350 }, 1351 }, 1352 Result: value.NewTernary(ternary.FALSE), 1353 }, 1354 { 1355 Name: "In JsonArray", 1356 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 1357 { 1358 view: &View{ 1359 Header: NewHeaderWithId("table2", []string{"column3", "column4"}), 1360 RecordSet: []Record{ 1361 NewRecordWithId(1, []value.Primary{ 1362 value.NewInteger(1), 1363 value.NewString("str2"), 1364 }), 1365 }, 1366 }, 1367 recordIndex: 0, 1368 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 1369 }, 1370 }), 1371 Expr: parser.In{ 1372 LHS: parser.NewIntegerValue(2), 1373 Values: parser.RowValue{ 1374 Value: parser.JsonQuery{ 1375 Query: parser.NewStringValue("key[]"), 1376 JsonText: parser.NewStringValue("{\"key\":[2, 3]}"), 1377 }, 1378 }, 1379 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 1380 }, 1381 Result: value.NewTernary(ternary.FALSE), 1382 }, 1383 { 1384 Name: "In JsonArray Query is Null", 1385 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 1386 { 1387 view: &View{ 1388 Header: NewHeaderWithId("table2", []string{"column3", "column4"}), 1389 RecordSet: []Record{ 1390 NewRecordWithId(1, []value.Primary{ 1391 value.NewInteger(1), 1392 value.NewString("str2"), 1393 }), 1394 }, 1395 }, 1396 recordIndex: 0, 1397 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 1398 }, 1399 }), 1400 Expr: parser.In{ 1401 LHS: parser.NewIntegerValue(2), 1402 Values: parser.RowValue{ 1403 Value: parser.JsonQuery{ 1404 Query: parser.NewNullValue(), 1405 JsonText: parser.NewStringValue("{\"key\":[2, 3]}"), 1406 }, 1407 }, 1408 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 1409 }, 1410 Result: value.NewTernary(ternary.TRUE), 1411 }, 1412 { 1413 Name: "In JsonArray Query Evaluation Error", 1414 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 1415 { 1416 view: &View{ 1417 Header: NewHeaderWithId("table2", []string{"column3", "column4"}), 1418 RecordSet: []Record{ 1419 NewRecordWithId(1, []value.Primary{ 1420 value.NewInteger(1), 1421 value.NewString("str2"), 1422 }), 1423 }, 1424 }, 1425 recordIndex: 0, 1426 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 1427 }, 1428 }), 1429 Expr: parser.In{ 1430 LHS: parser.NewIntegerValue(2), 1431 Values: parser.RowValue{ 1432 Value: parser.JsonQuery{ 1433 Query: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 1434 JsonText: parser.NewStringValue("{\"key\":[2, 3]}"), 1435 }, 1436 }, 1437 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 1438 }, 1439 Error: "field notexist does not exist", 1440 }, 1441 { 1442 Name: "In JsonArray JsonText Evaluation Error", 1443 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 1444 { 1445 view: &View{ 1446 Header: NewHeaderWithId("table2", []string{"column3", "column4"}), 1447 RecordSet: []Record{ 1448 NewRecordWithId(1, []value.Primary{ 1449 value.NewInteger(1), 1450 value.NewString("str2"), 1451 }), 1452 }, 1453 }, 1454 recordIndex: 0, 1455 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 1456 }, 1457 }), 1458 Expr: parser.In{ 1459 LHS: parser.NewIntegerValue(2), 1460 Values: parser.RowValue{ 1461 Value: parser.JsonQuery{ 1462 Query: parser.NewStringValue("key"), 1463 JsonText: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 1464 }, 1465 }, 1466 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 1467 }, 1468 Error: "field notexist does not exist", 1469 }, 1470 { 1471 Name: "In JsonArray Query Load Error", 1472 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 1473 { 1474 view: &View{ 1475 Header: NewHeaderWithId("table2", []string{"column3", "column4"}), 1476 RecordSet: []Record{ 1477 NewRecordWithId(1, []value.Primary{ 1478 value.NewInteger(1), 1479 value.NewString("str2"), 1480 }), 1481 }, 1482 }, 1483 recordIndex: 0, 1484 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 1485 }, 1486 }), 1487 Expr: parser.In{ 1488 LHS: parser.NewIntegerValue(2), 1489 Values: parser.RowValue{ 1490 Value: parser.JsonQuery{ 1491 Query: parser.NewStringValue("'key"), 1492 JsonText: parser.NewStringValue("{\"key\":[2, 3]}"), 1493 }, 1494 }, 1495 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 1496 }, 1497 Error: "json loading error: column 4: string not terminated", 1498 }, 1499 { 1500 Name: "In JsonArray Empty Result Set", 1501 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 1502 { 1503 view: &View{ 1504 Header: NewHeaderWithId("table2", []string{"column3", "column4"}), 1505 RecordSet: []Record{ 1506 NewRecordWithId(1, []value.Primary{ 1507 value.NewInteger(1), 1508 value.NewString("str2"), 1509 }), 1510 }, 1511 }, 1512 recordIndex: 0, 1513 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 1514 }, 1515 }), 1516 Expr: parser.In{ 1517 LHS: parser.NewIntegerValue(2), 1518 Values: parser.RowValue{ 1519 Value: parser.JsonQuery{ 1520 Query: parser.NewStringValue("key[]"), 1521 JsonText: parser.NewStringValue("{\"key\":[]}"), 1522 }, 1523 }, 1524 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 1525 }, 1526 Result: value.NewTernary(ternary.TRUE), 1527 }, 1528 { 1529 Name: "In with Row Values", 1530 Expr: parser.In{ 1531 LHS: parser.RowValue{ 1532 Value: parser.ValueList{ 1533 Values: []parser.QueryExpression{ 1534 parser.NewIntegerValue(1), 1535 parser.NewIntegerValue(2), 1536 }, 1537 }, 1538 }, 1539 Values: parser.RowValueList{ 1540 RowValues: []parser.QueryExpression{ 1541 parser.RowValue{ 1542 Value: parser.ValueList{ 1543 Values: []parser.QueryExpression{ 1544 parser.NewIntegerValue(1), 1545 parser.NewIntegerValue(1), 1546 }, 1547 }, 1548 }, 1549 parser.RowValue{ 1550 Value: parser.ValueList{ 1551 Values: []parser.QueryExpression{ 1552 parser.NewIntegerValue(1), 1553 parser.NewIntegerValue(2), 1554 }, 1555 }, 1556 }, 1557 }, 1558 }, 1559 }, 1560 Result: value.NewTernary(ternary.TRUE), 1561 }, 1562 { 1563 Name: "In with Row Value and Subquery", 1564 Expr: parser.In{ 1565 LHS: parser.RowValue{ 1566 Value: parser.ValueList{ 1567 Values: []parser.QueryExpression{ 1568 parser.NewStringValue("2"), 1569 parser.NewStringValue("str2"), 1570 }, 1571 }, 1572 }, 1573 Values: parser.Subquery{ 1574 Query: parser.SelectQuery{ 1575 SelectEntity: parser.SelectEntity{ 1576 SelectClause: parser.SelectClause{ 1577 Fields: []parser.QueryExpression{ 1578 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 1579 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}}, 1580 }, 1581 }, 1582 FromClause: parser.FromClause{ 1583 Tables: []parser.QueryExpression{ 1584 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 1585 }, 1586 }, 1587 }, 1588 }, 1589 }, 1590 }, 1591 Result: value.NewTernary(ternary.TRUE), 1592 }, 1593 { 1594 Name: "In with Row Value and JsonQuery", 1595 Expr: parser.In{ 1596 LHS: parser.RowValue{ 1597 Value: parser.ValueList{ 1598 Values: []parser.QueryExpression{ 1599 parser.NewStringValue("2"), 1600 parser.NewStringValue("str2"), 1601 }, 1602 }, 1603 }, 1604 Values: parser.JsonQuery{ 1605 Query: parser.NewStringValue("key{key2, key3}"), 1606 JsonText: parser.NewStringValue("{\"key\":{\"key2\":2, \"key3\":\"str2\"}}"), 1607 }, 1608 }, 1609 Result: value.NewTernary(ternary.TRUE), 1610 }, 1611 { 1612 Name: "In with Row Values LHS Error", 1613 Expr: parser.In{ 1614 LHS: parser.RowValue{ 1615 Value: parser.ValueList{ 1616 Values: []parser.QueryExpression{ 1617 parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 1618 parser.NewIntegerValue(2), 1619 }, 1620 }, 1621 }, 1622 Values: parser.RowValueList{ 1623 RowValues: []parser.QueryExpression{ 1624 parser.RowValue{ 1625 Value: parser.ValueList{ 1626 Values: []parser.QueryExpression{ 1627 parser.NewIntegerValue(1), 1628 parser.NewIntegerValue(1), 1629 }, 1630 }, 1631 }, 1632 parser.RowValue{ 1633 Value: parser.ValueList{ 1634 Values: []parser.QueryExpression{ 1635 parser.NewIntegerValue(1), 1636 parser.NewIntegerValue(2), 1637 }, 1638 }, 1639 }, 1640 }, 1641 }, 1642 }, 1643 Error: "field notexist does not exist", 1644 }, 1645 { 1646 Name: "In with Row Value and Subquery Query Error", 1647 Expr: parser.In{ 1648 LHS: parser.RowValue{ 1649 Value: parser.ValueList{ 1650 Values: []parser.QueryExpression{ 1651 parser.NewStringValue("2"), 1652 parser.NewStringValue("str2"), 1653 }, 1654 }, 1655 }, 1656 Values: parser.Subquery{ 1657 Query: parser.SelectQuery{ 1658 SelectEntity: parser.SelectEntity{ 1659 SelectClause: parser.SelectClause{ 1660 Fields: []parser.QueryExpression{ 1661 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 1662 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}}, 1663 }, 1664 }, 1665 FromClause: parser.FromClause{ 1666 Tables: []parser.QueryExpression{ 1667 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 1668 }, 1669 }, 1670 }, 1671 }, 1672 }, 1673 }, 1674 Error: "field notexist does not exist", 1675 }, 1676 { 1677 Name: "In with Row Value and Subquery Empty Result Set", 1678 Expr: parser.In{ 1679 LHS: parser.RowValue{ 1680 Value: parser.ValueList{ 1681 Values: []parser.QueryExpression{ 1682 parser.NewStringValue("2"), 1683 parser.NewStringValue("str2"), 1684 }, 1685 }, 1686 }, 1687 Values: parser.Subquery{ 1688 Query: parser.SelectQuery{ 1689 SelectEntity: parser.SelectEntity{ 1690 SelectClause: parser.SelectClause{ 1691 Fields: []parser.QueryExpression{ 1692 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 1693 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}}, 1694 }, 1695 }, 1696 FromClause: parser.FromClause{ 1697 Tables: []parser.QueryExpression{ 1698 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 1699 }, 1700 }, 1701 WhereClause: parser.WhereClause{ 1702 Filter: parser.NewTernaryValue(ternary.FALSE), 1703 }, 1704 }, 1705 }, 1706 }, 1707 }, 1708 Result: value.NewTernary(ternary.FALSE), 1709 }, 1710 { 1711 Name: "In with Row Value and JsonQuery Query Evaluation Error", 1712 Expr: parser.In{ 1713 LHS: parser.RowValue{ 1714 Value: parser.ValueList{ 1715 Values: []parser.QueryExpression{ 1716 parser.NewStringValue("2"), 1717 parser.NewStringValue("str2"), 1718 }, 1719 }, 1720 }, 1721 Values: parser.JsonQuery{ 1722 Query: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 1723 JsonText: parser.NewStringValue("{\"key\":{\"key2\":2, \"key3\":\"str2\"}}"), 1724 }, 1725 }, 1726 Error: "field notexist does not exist", 1727 }, 1728 { 1729 Name: "In with Row Value and JsonQuery Query is Null", 1730 Expr: parser.In{ 1731 LHS: parser.RowValue{ 1732 Value: parser.ValueList{ 1733 Values: []parser.QueryExpression{ 1734 parser.NewStringValue("2"), 1735 parser.NewStringValue("str2"), 1736 }, 1737 }, 1738 }, 1739 Values: parser.JsonQuery{ 1740 Query: parser.NewNullValue(), 1741 JsonText: parser.NewStringValue("{\"key\":{\"key2\":2, \"key3\":\"str2\"}}"), 1742 }, 1743 }, 1744 Result: value.NewTernary(ternary.FALSE), 1745 }, 1746 { 1747 Name: "In with Row Value and JsonQuery Loading Error", 1748 Expr: parser.In{ 1749 LHS: parser.RowValue{ 1750 Value: parser.ValueList{ 1751 Values: []parser.QueryExpression{ 1752 parser.NewStringValue("2"), 1753 parser.NewStringValue("str2"), 1754 }, 1755 }, 1756 }, 1757 Values: parser.JsonQuery{ 1758 Query: parser.NewStringValue("key{"), 1759 JsonText: parser.NewStringValue("{\"key\":[]}"), 1760 }, 1761 }, 1762 Error: "json loading error: column 4: unexpected termination", 1763 }, 1764 { 1765 Name: "In with Row Value and JsonQuery Empty Result Set", 1766 Expr: parser.In{ 1767 LHS: parser.RowValue{ 1768 Value: parser.ValueList{ 1769 Values: []parser.QueryExpression{ 1770 parser.NewStringValue("2"), 1771 parser.NewStringValue("str2"), 1772 }, 1773 }, 1774 }, 1775 Values: parser.JsonQuery{ 1776 Query: parser.NewStringValue("key{}"), 1777 JsonText: parser.NewStringValue("{\"key\":[]}"), 1778 }, 1779 }, 1780 Result: value.NewTernary(ternary.FALSE), 1781 }, 1782 { 1783 Name: "In with Row Value and JsonQuery Field Length Error", 1784 Expr: parser.In{ 1785 LHS: parser.RowValue{ 1786 Value: parser.ValueList{ 1787 Values: []parser.QueryExpression{ 1788 parser.NewStringValue("2"), 1789 parser.NewStringValue("str2"), 1790 }, 1791 }, 1792 }, 1793 Values: parser.JsonQuery{ 1794 Query: parser.NewStringValue("key{}"), 1795 JsonText: parser.NewStringValue("{\"key\":{}}"), 1796 }, 1797 }, 1798 Error: "row value should contain exactly 2 values", 1799 }, 1800 { 1801 Name: "In with Row Values Values Error", 1802 Expr: parser.In{ 1803 LHS: parser.RowValue{ 1804 Value: parser.ValueList{ 1805 Values: []parser.QueryExpression{ 1806 parser.NewIntegerValue(1), 1807 parser.NewIntegerValue(2), 1808 }, 1809 }, 1810 }, 1811 Values: parser.RowValueList{ 1812 RowValues: []parser.QueryExpression{ 1813 parser.RowValue{ 1814 Value: parser.ValueList{ 1815 Values: []parser.QueryExpression{ 1816 parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 1817 parser.NewIntegerValue(1), 1818 }, 1819 }, 1820 }, 1821 parser.RowValue{ 1822 Value: parser.ValueList{ 1823 Values: []parser.QueryExpression{ 1824 parser.NewIntegerValue(1), 1825 parser.NewIntegerValue(2), 1826 }, 1827 }, 1828 }, 1829 }, 1830 }, 1831 }, 1832 Error: "field notexist does not exist", 1833 }, 1834 { 1835 Name: "In with Row Values Length Not Match Error ", 1836 Expr: parser.In{ 1837 LHS: parser.RowValue{ 1838 Value: parser.ValueList{ 1839 Values: []parser.QueryExpression{ 1840 parser.NewIntegerValue(1), 1841 parser.NewIntegerValue(2), 1842 }, 1843 }, 1844 }, 1845 Values: parser.RowValueList{ 1846 RowValues: []parser.QueryExpression{ 1847 parser.RowValue{ 1848 Value: parser.ValueList{ 1849 Values: []parser.QueryExpression{ 1850 parser.NewIntegerValue(1), 1851 parser.NewIntegerValue(1), 1852 }, 1853 }, 1854 }, 1855 parser.RowValue{ 1856 Value: parser.ValueList{ 1857 Values: []parser.QueryExpression{ 1858 parser.NewIntegerValue(2), 1859 }, 1860 }, 1861 }, 1862 }, 1863 }, 1864 }, 1865 Error: "row value should contain exactly 2 values", 1866 }, 1867 { 1868 Name: "In with Row Value and Subquery Length Not Match Error", 1869 Expr: parser.In{ 1870 LHS: parser.RowValue{ 1871 Value: parser.ValueList{ 1872 Values: []parser.QueryExpression{ 1873 parser.NewStringValue("2"), 1874 parser.NewStringValue("str2"), 1875 }, 1876 }, 1877 }, 1878 Values: parser.Subquery{ 1879 Query: parser.SelectQuery{ 1880 SelectEntity: parser.SelectEntity{ 1881 SelectClause: parser.SelectClause{ 1882 Fields: []parser.QueryExpression{ 1883 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 1884 }, 1885 }, 1886 FromClause: parser.FromClause{ 1887 Tables: []parser.QueryExpression{ 1888 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 1889 }, 1890 }, 1891 }, 1892 }, 1893 }, 1894 }, 1895 Error: "select query should return exactly 2 fields", 1896 }, 1897 { 1898 Name: "Any", 1899 Expr: parser.Any{ 1900 LHS: parser.NewIntegerValue(5), 1901 Values: parser.RowValue{ 1902 Value: parser.Subquery{ 1903 Query: parser.SelectQuery{ 1904 SelectEntity: parser.SelectEntity{ 1905 SelectClause: parser.SelectClause{ 1906 Fields: []parser.QueryExpression{ 1907 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 1908 }, 1909 }, 1910 FromClause: parser.FromClause{ 1911 Tables: []parser.QueryExpression{ 1912 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 1913 }, 1914 }, 1915 }, 1916 }, 1917 }, 1918 }, 1919 Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: "<>"}, 1920 }, 1921 Result: value.NewTernary(ternary.TRUE), 1922 }, 1923 { 1924 Name: "Any LHS Error", 1925 Expr: parser.Any{ 1926 LHS: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 1927 Values: parser.RowValue{ 1928 Value: parser.Subquery{ 1929 Query: parser.SelectQuery{ 1930 SelectEntity: parser.SelectEntity{ 1931 SelectClause: parser.SelectClause{ 1932 Fields: []parser.QueryExpression{ 1933 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 1934 }, 1935 }, 1936 FromClause: parser.FromClause{ 1937 Tables: []parser.QueryExpression{ 1938 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 1939 }, 1940 }, 1941 }, 1942 }, 1943 }, 1944 }, 1945 Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: "<>"}, 1946 }, 1947 Error: "field notexist does not exist", 1948 }, 1949 { 1950 Name: "Any Query Execution Error", 1951 Expr: parser.Any{ 1952 LHS: parser.NewIntegerValue(2), 1953 Values: parser.RowValue{ 1954 Value: parser.Subquery{ 1955 Query: parser.SelectQuery{ 1956 SelectEntity: parser.SelectEntity{ 1957 SelectClause: parser.SelectClause{ 1958 Fields: []parser.QueryExpression{ 1959 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 1960 }, 1961 }, 1962 FromClause: parser.FromClause{ 1963 Tables: []parser.QueryExpression{ 1964 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 1965 }, 1966 }, 1967 WhereClause: parser.WhereClause{ 1968 Filter: parser.Comparison{ 1969 LHS: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 1970 RHS: parser.FieldReference{View: parser.Identifier{Literal: "table2"}, Column: parser.Identifier{Literal: "column4"}}, 1971 Operator: parser.Token{Token: '=', Literal: "="}, 1972 }, 1973 }, 1974 }, 1975 }, 1976 }, 1977 }, 1978 Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: "<>"}, 1979 }, 1980 Error: "field notexist does not exist", 1981 }, 1982 { 1983 Name: "Any Row Value Select Field Not Match Error", 1984 Expr: parser.Any{ 1985 LHS: parser.RowValue{ 1986 Value: parser.ValueList{ 1987 Values: []parser.QueryExpression{ 1988 parser.NewIntegerValue(1), 1989 parser.NewIntegerValue(2), 1990 }, 1991 }, 1992 }, 1993 Values: parser.Subquery{ 1994 Query: parser.SelectQuery{ 1995 SelectEntity: parser.SelectEntity{ 1996 SelectClause: parser.SelectClause{ 1997 Fields: []parser.QueryExpression{ 1998 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 1999 }, 2000 }, 2001 FromClause: parser.FromClause{ 2002 Tables: []parser.QueryExpression{ 2003 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 2004 }, 2005 }, 2006 }, 2007 }, 2008 }, 2009 Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: "<>"}, 2010 }, 2011 Error: "select query should return exactly 2 fields", 2012 }, 2013 { 2014 Name: "Any Row Value Length Not Match Error", 2015 Expr: parser.Any{ 2016 LHS: parser.RowValue{ 2017 Value: parser.ValueList{ 2018 Values: []parser.QueryExpression{ 2019 parser.NewIntegerValue(1), 2020 parser.NewIntegerValue(2), 2021 }, 2022 }, 2023 }, 2024 Values: parser.RowValueList{ 2025 RowValues: []parser.QueryExpression{ 2026 parser.RowValue{ 2027 Value: parser.ValueList{ 2028 Values: []parser.QueryExpression{ 2029 parser.NewIntegerValue(1), 2030 parser.NewIntegerValue(2), 2031 }, 2032 }, 2033 }, 2034 parser.RowValue{ 2035 Value: parser.ValueList{ 2036 Values: []parser.QueryExpression{ 2037 parser.NewIntegerValue(1), 2038 }, 2039 }, 2040 }, 2041 }, 2042 }, 2043 Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: "<>"}, 2044 }, 2045 Error: "row value should contain exactly 2 values", 2046 }, 2047 { 2048 Name: "Any with Row Value and JsonQuery Field Length Error", 2049 Expr: parser.Any{ 2050 LHS: parser.RowValue{ 2051 Value: parser.ValueList{ 2052 Values: []parser.QueryExpression{ 2053 parser.NewStringValue("2"), 2054 parser.NewStringValue("str2"), 2055 }, 2056 }, 2057 }, 2058 Values: parser.JsonQuery{ 2059 Query: parser.NewStringValue("key{}"), 2060 JsonText: parser.NewStringValue("{\"key\":{}}"), 2061 }, 2062 }, 2063 Error: "row value should contain exactly 2 values", 2064 }, 2065 { 2066 Name: "All", 2067 Expr: parser.All{ 2068 LHS: parser.NewIntegerValue(5), 2069 Values: parser.RowValue{ 2070 Value: parser.Subquery{ 2071 Query: parser.SelectQuery{ 2072 SelectEntity: parser.SelectEntity{ 2073 SelectClause: parser.SelectClause{ 2074 Fields: []parser.QueryExpression{ 2075 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 2076 }, 2077 }, 2078 FromClause: parser.FromClause{ 2079 Tables: []parser.QueryExpression{ 2080 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 2081 }, 2082 }, 2083 }, 2084 }, 2085 }, 2086 }, 2087 Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: ">"}, 2088 }, 2089 Result: value.NewTernary(ternary.TRUE), 2090 }, 2091 { 2092 Name: "All False", 2093 Expr: parser.All{ 2094 LHS: parser.NewIntegerValue(-99), 2095 Values: parser.RowValue{ 2096 Value: parser.Subquery{ 2097 Query: parser.SelectQuery{ 2098 SelectEntity: parser.SelectEntity{ 2099 SelectClause: parser.SelectClause{ 2100 Fields: []parser.QueryExpression{ 2101 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 2102 }, 2103 }, 2104 FromClause: parser.FromClause{ 2105 Tables: []parser.QueryExpression{ 2106 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 2107 }, 2108 }, 2109 }, 2110 }, 2111 }, 2112 }, 2113 Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: ">"}, 2114 }, 2115 Result: value.NewTernary(ternary.FALSE), 2116 }, 2117 { 2118 Name: "All LHS Error", 2119 Expr: parser.All{ 2120 LHS: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 2121 Values: parser.RowValue{ 2122 Value: parser.Subquery{ 2123 Query: parser.SelectQuery{ 2124 SelectEntity: parser.SelectEntity{ 2125 SelectClause: parser.SelectClause{ 2126 Fields: []parser.QueryExpression{ 2127 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 2128 }, 2129 }, 2130 FromClause: parser.FromClause{ 2131 Tables: []parser.QueryExpression{ 2132 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 2133 }, 2134 }, 2135 }, 2136 }, 2137 }, 2138 }, 2139 Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: ">"}, 2140 }, 2141 Error: "field notexist does not exist", 2142 }, 2143 { 2144 Name: "All Query Execution Error", 2145 Expr: parser.All{ 2146 LHS: parser.NewIntegerValue(5), 2147 Values: parser.RowValue{ 2148 Value: parser.Subquery{ 2149 Query: parser.SelectQuery{ 2150 SelectEntity: parser.SelectEntity{ 2151 SelectClause: parser.SelectClause{ 2152 Fields: []parser.QueryExpression{ 2153 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 2154 }, 2155 }, 2156 FromClause: parser.FromClause{ 2157 Tables: []parser.QueryExpression{ 2158 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 2159 }, 2160 }, 2161 WhereClause: parser.WhereClause{ 2162 Filter: parser.Comparison{ 2163 LHS: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 2164 RHS: parser.FieldReference{View: parser.Identifier{Literal: "table2"}, Column: parser.Identifier{Literal: "column4"}}, 2165 Operator: parser.Token{Token: '=', Literal: "="}, 2166 }, 2167 }, 2168 }, 2169 }, 2170 }, 2171 }, 2172 Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: ">"}, 2173 }, 2174 Error: "field notexist does not exist", 2175 }, 2176 { 2177 Name: "All Row Value Select Field Not Match Error", 2178 Expr: parser.All{ 2179 LHS: parser.RowValue{ 2180 Value: parser.ValueList{ 2181 Values: []parser.QueryExpression{ 2182 parser.NewIntegerValue(1), 2183 parser.NewIntegerValue(2), 2184 }, 2185 }, 2186 }, 2187 Values: parser.Subquery{ 2188 Query: parser.SelectQuery{ 2189 SelectEntity: parser.SelectEntity{ 2190 SelectClause: parser.SelectClause{ 2191 Fields: []parser.QueryExpression{ 2192 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 2193 }, 2194 }, 2195 FromClause: parser.FromClause{ 2196 Tables: []parser.QueryExpression{ 2197 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 2198 }, 2199 }, 2200 }, 2201 }, 2202 }, 2203 Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: ">"}, 2204 }, 2205 Error: "select query should return exactly 2 fields", 2206 }, 2207 { 2208 Name: "All Row Value Length Not Match Error", 2209 Expr: parser.All{ 2210 LHS: parser.RowValue{ 2211 Value: parser.ValueList{ 2212 Values: []parser.QueryExpression{ 2213 parser.NewIntegerValue(1), 2214 parser.NewIntegerValue(2), 2215 }, 2216 }, 2217 }, 2218 Values: parser.RowValueList{ 2219 RowValues: []parser.QueryExpression{ 2220 parser.RowValue{ 2221 Value: parser.ValueList{ 2222 Values: []parser.QueryExpression{ 2223 parser.NewIntegerValue(1), 2224 parser.NewIntegerValue(2), 2225 }, 2226 }, 2227 }, 2228 parser.RowValue{ 2229 Value: parser.ValueList{ 2230 Values: []parser.QueryExpression{ 2231 parser.NewIntegerValue(1), 2232 }, 2233 }, 2234 }, 2235 }, 2236 }, 2237 Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: "="}, 2238 }, 2239 Error: "row value should contain exactly 2 values", 2240 }, 2241 { 2242 Name: "All with Row Value and JsonQuery Field Length Error", 2243 Expr: parser.All{ 2244 LHS: parser.RowValue{ 2245 Value: parser.ValueList{ 2246 Values: []parser.QueryExpression{ 2247 parser.NewStringValue("2"), 2248 parser.NewStringValue("str2"), 2249 }, 2250 }, 2251 }, 2252 Values: parser.JsonQuery{ 2253 Query: parser.NewStringValue("key{}"), 2254 JsonText: parser.NewStringValue("{\"key\":{}}"), 2255 }, 2256 }, 2257 Error: "row value should contain exactly 2 values", 2258 }, 2259 { 2260 Name: "Like", 2261 Expr: parser.Like{ 2262 LHS: parser.NewStringValue("abcdefg"), 2263 Pattern: parser.NewStringValue("_bc%"), 2264 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 2265 }, 2266 Result: value.NewTernary(ternary.FALSE), 2267 }, 2268 { 2269 Name: "Like LHS Error", 2270 Expr: parser.Like{ 2271 LHS: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 2272 Pattern: parser.NewStringValue("_bc%"), 2273 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 2274 }, 2275 Error: "field notexist does not exist", 2276 }, 2277 { 2278 Name: "Like Pattern Error", 2279 Expr: parser.Like{ 2280 LHS: parser.NewStringValue("abcdefg"), 2281 Pattern: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 2282 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 2283 }, 2284 Error: "field notexist does not exist", 2285 }, 2286 { 2287 Name: "Exists", 2288 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 2289 { 2290 view: &View{ 2291 Header: NewHeaderWithId("table2", []string{"column3", "column4"}), 2292 RecordSet: []Record{ 2293 NewRecordWithId(1, []value.Primary{ 2294 value.NewInteger(1), 2295 value.NewString("str2"), 2296 }), 2297 }, 2298 }, 2299 recordIndex: 0, 2300 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 2301 }, 2302 }), 2303 Expr: parser.Exists{ 2304 Query: parser.Subquery{ 2305 Query: parser.SelectQuery{ 2306 SelectEntity: parser.SelectEntity{ 2307 SelectClause: parser.SelectClause{ 2308 Fields: []parser.QueryExpression{ 2309 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 2310 }, 2311 }, 2312 FromClause: parser.FromClause{ 2313 Tables: []parser.QueryExpression{ 2314 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 2315 }, 2316 }, 2317 WhereClause: parser.WhereClause{ 2318 Filter: parser.Comparison{ 2319 LHS: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}, 2320 RHS: parser.FieldReference{View: parser.Identifier{Literal: "table2"}, Column: parser.Identifier{Literal: "column4"}}, 2321 Operator: parser.Token{Token: '=', Literal: "="}, 2322 }, 2323 }, 2324 }, 2325 }, 2326 }, 2327 }, 2328 Result: value.NewTernary(ternary.TRUE), 2329 }, 2330 { 2331 Name: "Exists No Record", 2332 Expr: parser.Exists{ 2333 Query: parser.Subquery{ 2334 Query: parser.SelectQuery{ 2335 SelectEntity: parser.SelectEntity{ 2336 SelectClause: parser.SelectClause{ 2337 Fields: []parser.QueryExpression{ 2338 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 2339 }, 2340 }, 2341 FromClause: parser.FromClause{ 2342 Tables: []parser.QueryExpression{ 2343 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 2344 }, 2345 }, 2346 WhereClause: parser.WhereClause{ 2347 Filter: parser.NewTernaryValue(ternary.FALSE), 2348 }, 2349 }, 2350 }, 2351 }, 2352 }, 2353 Result: value.NewTernary(ternary.FALSE), 2354 }, 2355 { 2356 Name: "Exists Query Execution Error", 2357 Expr: parser.Exists{ 2358 Query: parser.Subquery{ 2359 Query: parser.SelectQuery{ 2360 SelectEntity: parser.SelectEntity{ 2361 SelectClause: parser.SelectClause{ 2362 Fields: []parser.QueryExpression{ 2363 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 2364 }, 2365 }, 2366 FromClause: parser.FromClause{ 2367 Tables: []parser.QueryExpression{ 2368 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 2369 }, 2370 }, 2371 WhereClause: parser.WhereClause{ 2372 Filter: parser.Comparison{ 2373 LHS: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 2374 RHS: parser.NewStringValue("str2"), 2375 Operator: parser.Token{Token: '=', Literal: "="}, 2376 }, 2377 }, 2378 }, 2379 }, 2380 }, 2381 }, 2382 Error: "field notexist does not exist", 2383 }, 2384 { 2385 Name: "Subquery", 2386 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 2387 { 2388 view: &View{ 2389 Header: NewHeaderWithId("table2", []string{"column3", "column4"}), 2390 RecordSet: []Record{ 2391 NewRecordWithId(1, []value.Primary{ 2392 value.NewInteger(1), 2393 value.NewString("str2"), 2394 }), 2395 }, 2396 }, 2397 recordIndex: 0, 2398 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 2399 }, 2400 }), 2401 Expr: parser.Subquery{ 2402 Query: parser.SelectQuery{ 2403 SelectEntity: parser.SelectEntity{ 2404 SelectClause: parser.SelectClause{ 2405 Fields: []parser.QueryExpression{ 2406 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 2407 }, 2408 }, 2409 FromClause: parser.FromClause{ 2410 Tables: []parser.QueryExpression{ 2411 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 2412 }, 2413 }, 2414 WhereClause: parser.WhereClause{ 2415 Filter: parser.Comparison{ 2416 LHS: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}, 2417 RHS: parser.FieldReference{View: parser.Identifier{Literal: "table2"}, Column: parser.Identifier{Literal: "column4"}}, 2418 Operator: parser.Token{Token: '=', Literal: "="}, 2419 }, 2420 }, 2421 }, 2422 LimitClause: parser.LimitClause{ 2423 Value: parser.NewIntegerValue(1), 2424 }, 2425 }, 2426 }, 2427 Result: value.NewString("2"), 2428 }, 2429 { 2430 Name: "Subquery No Record", 2431 Expr: parser.Subquery{ 2432 Query: parser.SelectQuery{ 2433 SelectEntity: parser.SelectEntity{ 2434 SelectClause: parser.SelectClause{ 2435 Fields: []parser.QueryExpression{ 2436 parser.Field{Object: parser.NewIntegerValue(1)}, 2437 }, 2438 }, 2439 FromClause: parser.FromClause{ 2440 Tables: []parser.QueryExpression{ 2441 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 2442 }, 2443 }, 2444 WhereClause: parser.WhereClause{ 2445 Filter: parser.NewTernaryValue(ternary.FALSE), 2446 }, 2447 }, 2448 LimitClause: parser.LimitClause{ 2449 Value: parser.NewIntegerValue(1), 2450 }, 2451 }, 2452 }, 2453 Result: value.NewNull(), 2454 }, 2455 { 2456 Name: "Subquery Execution Error", 2457 Expr: parser.Subquery{ 2458 Query: parser.SelectQuery{ 2459 SelectEntity: parser.SelectEntity{ 2460 SelectClause: parser.SelectClause{ 2461 Fields: []parser.QueryExpression{ 2462 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}}, 2463 }, 2464 }, 2465 FromClause: parser.FromClause{ 2466 Tables: []parser.QueryExpression{ 2467 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 2468 }, 2469 }, 2470 }, 2471 }, 2472 }, 2473 Error: "field notexist does not exist", 2474 }, 2475 { 2476 Name: "Subquery Too Many RecordSet Error", 2477 Expr: parser.Subquery{ 2478 Query: parser.SelectQuery{ 2479 SelectEntity: parser.SelectEntity{ 2480 SelectClause: parser.SelectClause{ 2481 Fields: []parser.QueryExpression{ 2482 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 2483 }, 2484 }, 2485 FromClause: parser.FromClause{ 2486 Tables: []parser.QueryExpression{ 2487 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 2488 }, 2489 }, 2490 }, 2491 }, 2492 }, 2493 Error: "subquery returns too many records, should return only one record", 2494 }, 2495 { 2496 Name: "Subquery Too Many Fields Error", 2497 Expr: parser.Subquery{ 2498 Query: parser.SelectQuery{ 2499 SelectEntity: parser.SelectEntity{ 2500 SelectClause: parser.SelectClause{ 2501 Fields: []parser.QueryExpression{ 2502 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 2503 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}}, 2504 }, 2505 }, 2506 FromClause: parser.FromClause{ 2507 Tables: []parser.QueryExpression{ 2508 parser.Table{Object: parser.Identifier{Literal: "table1"}}, 2509 }, 2510 }, 2511 }, 2512 LimitClause: parser.LimitClause{ 2513 Value: parser.NewIntegerValue(1), 2514 }, 2515 }, 2516 }, 2517 Error: "subquery returns too many fields, should return only one field", 2518 }, 2519 { 2520 Name: "Function", 2521 Expr: parser.Function{ 2522 Name: "coalesce", 2523 Args: []parser.QueryExpression{ 2524 parser.NewNullValue(), 2525 parser.NewStringValue("str"), 2526 }, 2527 }, 2528 Result: value.NewString("str"), 2529 }, 2530 { 2531 Name: "Function Now", 2532 Expr: parser.Function{ 2533 Name: "now", 2534 }, 2535 Result: value.NewDatetime(NowForTest), 2536 }, 2537 { 2538 Name: "User Defined Function", 2539 Scope: GenerateReferenceScope([]map[string]map[string]interface{}{ 2540 { 2541 scopeNameFunctions: { 2542 "USERFUNC": &UserDefinedFunction{ 2543 Name: parser.Identifier{Literal: "userfunc"}, 2544 Parameters: []parser.Variable{ 2545 {Name: "arg1"}, 2546 }, 2547 RequiredArgs: 1, 2548 Statements: []parser.Statement{ 2549 parser.Return{Value: parser.Variable{Name: "arg1"}}, 2550 }, 2551 }, 2552 }, 2553 }, 2554 }, nil, time.Time{}, nil), 2555 Expr: parser.Function{ 2556 Name: "userfunc", 2557 Args: []parser.QueryExpression{ 2558 parser.NewIntegerValue(1), 2559 }, 2560 }, 2561 Result: value.NewInteger(1), 2562 }, 2563 { 2564 Name: "User Defined Function Argument Length Error", 2565 Scope: GenerateReferenceScope([]map[string]map[string]interface{}{ 2566 { 2567 scopeNameFunctions: { 2568 "USERFUNC": &UserDefinedFunction{ 2569 Name: parser.Identifier{Literal: "userfunc"}, 2570 Parameters: []parser.Variable{ 2571 {Name: "arg1"}, 2572 }, 2573 RequiredArgs: 1, 2574 Statements: []parser.Statement{ 2575 parser.Return{Value: parser.Variable{Name: "arg1"}}, 2576 }, 2577 }, 2578 }, 2579 }, 2580 }, nil, time.Time{}, nil), 2581 Expr: parser.Function{ 2582 Name: "userfunc", 2583 Args: []parser.QueryExpression{}, 2584 }, 2585 Error: "function userfunc takes exactly 1 argument", 2586 }, 2587 { 2588 Name: "Function Not Exist Error", 2589 Expr: parser.Function{ 2590 Name: "notexist", 2591 Args: []parser.QueryExpression{ 2592 parser.NewNullValue(), 2593 parser.NewStringValue("str"), 2594 }, 2595 }, 2596 Error: "function notexist does not exist", 2597 }, 2598 { 2599 Name: "Function Evaluate Error", 2600 Expr: parser.Function{ 2601 Name: "coalesce", 2602 Args: []parser.QueryExpression{ 2603 parser.NewNullValue(), 2604 parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 2605 }, 2606 }, 2607 Error: "field notexist does not exist", 2608 }, 2609 { 2610 Name: "Aggregate Function", 2611 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 2612 { 2613 view: &View{ 2614 Header: NewHeaderWithId("table1", []string{"column1", "column2"}), 2615 RecordSet: []Record{ 2616 { 2617 NewGroupCell([]value.Primary{ 2618 value.NewInteger(1), 2619 value.NewInteger(2), 2620 value.NewInteger(3), 2621 }), 2622 NewGroupCell([]value.Primary{ 2623 value.NewInteger(1), 2624 value.NewNull(), 2625 value.NewInteger(3), 2626 }), 2627 NewGroupCell([]value.Primary{ 2628 value.NewString("str1"), 2629 value.NewString("str2"), 2630 value.NewString("str3"), 2631 }), 2632 }, 2633 }, 2634 isGrouped: true, 2635 }, 2636 recordIndex: 0, 2637 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 2638 }, 2639 }), 2640 Expr: parser.AggregateFunction{ 2641 Name: "avg", 2642 Distinct: parser.Token{}, 2643 Args: []parser.QueryExpression{ 2644 parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}, 2645 }, 2646 }, 2647 Result: value.NewFloat(2), 2648 }, 2649 { 2650 Name: "Aggregate Function Argument Length Error", 2651 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 2652 { 2653 view: &View{ 2654 Header: NewHeader("table1", []string{"column1", "column2"}), 2655 RecordSet: []Record{ 2656 { 2657 NewGroupCell([]value.Primary{ 2658 value.NewInteger(1), 2659 value.NewNull(), 2660 value.NewInteger(3), 2661 }), 2662 NewGroupCell([]value.Primary{ 2663 value.NewString("str1"), 2664 value.NewString("str2"), 2665 value.NewString("str3"), 2666 }), 2667 }, 2668 }, 2669 isGrouped: true, 2670 }, 2671 recordIndex: 0, 2672 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 2673 }, 2674 }), 2675 Expr: parser.AggregateFunction{ 2676 Name: "avg", 2677 Distinct: parser.Token{}, 2678 }, 2679 Error: "function avg takes exactly 1 argument", 2680 }, 2681 { 2682 Name: "Aggregate Function Not Grouped Error", 2683 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 2684 { 2685 view: &View{ 2686 Header: NewHeader("table1", []string{"column1", "column2"}), 2687 RecordSet: []Record{ 2688 NewRecordWithId(1, []value.Primary{ 2689 value.NewInteger(1), 2690 value.NewString("str2"), 2691 }), 2692 }, 2693 }, 2694 recordIndex: 0, 2695 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 2696 }, 2697 }), 2698 Expr: parser.AggregateFunction{ 2699 Name: "avg", 2700 Distinct: parser.Token{}, 2701 Args: []parser.QueryExpression{ 2702 parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}, 2703 }, 2704 }, 2705 Error: "function avg cannot aggregate not grouping records", 2706 }, 2707 { 2708 Name: "Aggregate Function Nested Error", 2709 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 2710 { 2711 view: &View{ 2712 Header: NewHeader("table1", []string{"column1", "column2"}), 2713 RecordSet: []Record{ 2714 { 2715 NewGroupCell([]value.Primary{ 2716 value.NewInteger(1), 2717 value.NewNull(), 2718 value.NewInteger(3), 2719 }), 2720 NewGroupCell([]value.Primary{ 2721 value.NewString("str1"), 2722 value.NewString("str2"), 2723 value.NewString("str3"), 2724 }), 2725 }, 2726 }, 2727 isGrouped: true, 2728 }, 2729 recordIndex: 0, 2730 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 2731 }, 2732 }), 2733 Expr: parser.AggregateFunction{ 2734 Name: "avg", 2735 Distinct: parser.Token{}, 2736 Args: []parser.QueryExpression{ 2737 parser.AggregateFunction{ 2738 Name: "avg", 2739 Args: []parser.QueryExpression{ 2740 parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}, 2741 }, 2742 }, 2743 }, 2744 }, 2745 Error: "aggregate functions are nested at AVG(AVG(column1))", 2746 }, 2747 { 2748 Name: "Aggregate Function Count With AllColumns", 2749 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 2750 { 2751 view: &View{ 2752 Header: NewHeader("table1", []string{"column1", "column2"}), 2753 RecordSet: []Record{ 2754 { 2755 NewGroupCell([]value.Primary{ 2756 value.NewInteger(1), 2757 value.NewNull(), 2758 value.NewInteger(3), 2759 }), 2760 NewGroupCell([]value.Primary{ 2761 value.NewString("str1"), 2762 value.NewString("str2"), 2763 value.NewString("str3"), 2764 }), 2765 }, 2766 }, 2767 isGrouped: true, 2768 }, 2769 recordIndex: 0, 2770 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 2771 }, 2772 }), 2773 Expr: parser.AggregateFunction{ 2774 Name: "count", 2775 Distinct: parser.Token{}, 2776 Args: []parser.QueryExpression{ 2777 parser.AllColumns{}, 2778 }, 2779 }, 2780 Result: value.NewInteger(3), 2781 }, 2782 { 2783 Name: "Aggregate Function Count With Null", 2784 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 2785 { 2786 view: &View{ 2787 Header: NewHeader("table1", []string{"column1", "column2"}), 2788 RecordSet: []Record{ 2789 { 2790 NewGroupCell([]value.Primary{ 2791 value.NewInteger(1), 2792 value.NewNull(), 2793 value.NewInteger(3), 2794 }), 2795 NewGroupCell([]value.Primary{ 2796 value.NewString("str1"), 2797 value.NewString("str2"), 2798 value.NewString("str3"), 2799 }), 2800 }, 2801 }, 2802 isGrouped: true, 2803 }, 2804 recordIndex: 0, 2805 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 2806 }, 2807 }), 2808 Expr: parser.AggregateFunction{ 2809 Name: "count", 2810 Distinct: parser.Token{}, 2811 Args: []parser.QueryExpression{ 2812 parser.PrimitiveType{Value: value.NewNull()}, 2813 }, 2814 }, 2815 Result: value.NewInteger(0), 2816 }, 2817 { 2818 Name: "Aggregate Function As a Statement Error", 2819 Expr: parser.AggregateFunction{ 2820 Name: "avg", 2821 Distinct: parser.Token{}, 2822 Args: []parser.QueryExpression{ 2823 parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}, 2824 }, 2825 }, 2826 Result: value.NewNull(), 2827 }, 2828 { 2829 Name: "Aggregate Function User Defined", 2830 Scope: GenerateReferenceScope([]map[string]map[string]interface{}{ 2831 { 2832 scopeNameFunctions: { 2833 "USERAGGFUNC": &UserDefinedFunction{ 2834 Name: parser.Identifier{Literal: "useraggfunc"}, 2835 IsAggregate: true, 2836 Cursor: parser.Identifier{Literal: "column1"}, 2837 Parameters: []parser.Variable{ 2838 {Name: "default"}, 2839 }, 2840 RequiredArgs: 1, 2841 Statements: []parser.Statement{ 2842 parser.VariableDeclaration{ 2843 Assignments: []parser.VariableAssignment{ 2844 { 2845 Variable: parser.Variable{Name: "value"}, 2846 }, 2847 { 2848 Variable: parser.Variable{Name: "fetch"}, 2849 }, 2850 }, 2851 }, 2852 parser.WhileInCursor{ 2853 Variables: []parser.Variable{ 2854 {Name: "fetch"}, 2855 }, 2856 Cursor: parser.Identifier{Literal: "column1"}, 2857 Statements: []parser.Statement{ 2858 parser.If{ 2859 Condition: parser.Is{ 2860 LHS: parser.Variable{Name: "fetch"}, 2861 RHS: parser.NewNullValue(), 2862 }, 2863 Statements: []parser.Statement{ 2864 parser.FlowControl{Token: parser.CONTINUE}, 2865 }, 2866 }, 2867 parser.If{ 2868 Condition: parser.Is{ 2869 LHS: parser.Variable{Name: "value"}, 2870 RHS: parser.NewNullValue(), 2871 }, 2872 Statements: []parser.Statement{ 2873 parser.VariableSubstitution{ 2874 Variable: parser.Variable{Name: "value"}, 2875 Value: parser.Variable{Name: "fetch"}, 2876 }, 2877 parser.FlowControl{Token: parser.CONTINUE}, 2878 }, 2879 }, 2880 parser.VariableSubstitution{ 2881 Variable: parser.Variable{Name: "value"}, 2882 Value: parser.Arithmetic{ 2883 LHS: parser.Variable{Name: "value"}, 2884 RHS: parser.Variable{Name: "fetch"}, 2885 Operator: parser.Token{Token: '*', Literal: "*"}, 2886 }, 2887 }, 2888 }, 2889 }, 2890 2891 parser.If{ 2892 Condition: parser.Is{ 2893 LHS: parser.Variable{Name: "value"}, 2894 RHS: parser.NewNullValue(), 2895 }, 2896 Statements: []parser.Statement{ 2897 parser.VariableSubstitution{ 2898 Variable: parser.Variable{Name: "value"}, 2899 Value: parser.Variable{Name: "default"}, 2900 }, 2901 }, 2902 }, 2903 2904 parser.Return{ 2905 Value: parser.Variable{Name: "value"}, 2906 }, 2907 }, 2908 }, 2909 }, 2910 }, 2911 }, nil, time.Time{}, []ReferenceRecord{ 2912 { 2913 view: &View{ 2914 Header: NewHeader("table1", []string{"column1", "column2"}), 2915 RecordSet: []Record{ 2916 { 2917 NewGroupCell([]value.Primary{ 2918 value.NewInteger(1), 2919 value.NewNull(), 2920 value.NewInteger(3), 2921 value.NewInteger(3), 2922 }), 2923 NewGroupCell([]value.Primary{ 2924 value.NewString("str1"), 2925 value.NewString("str2"), 2926 value.NewString("str3"), 2927 value.NewString("str4"), 2928 }), 2929 }, 2930 }, 2931 isGrouped: true, 2932 }, 2933 recordIndex: 0, 2934 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 2935 }, 2936 }), 2937 Expr: parser.AggregateFunction{ 2938 Name: "useraggfunc", 2939 Distinct: parser.Token{Token: parser.DISTINCT, Literal: "distinct"}, 2940 Args: []parser.QueryExpression{ 2941 parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}, 2942 parser.NewIntegerValue(0), 2943 }, 2944 }, 2945 Result: value.NewInteger(3), 2946 }, 2947 { 2948 Name: "Aggregate Function User Defined Argument Length Error", 2949 Scope: GenerateReferenceScope([]map[string]map[string]interface{}{ 2950 { 2951 scopeNameFunctions: { 2952 "USERAGGFUNC": &UserDefinedFunction{ 2953 Name: parser.Identifier{Literal: "useraggfunc"}, 2954 IsAggregate: true, 2955 Cursor: parser.Identifier{Literal: "column1"}, 2956 Parameters: []parser.Variable{ 2957 {Name: "default"}, 2958 }, 2959 Statements: []parser.Statement{ 2960 parser.Return{ 2961 Value: parser.Variable{Name: "value"}, 2962 }, 2963 }, 2964 }, 2965 }, 2966 }, 2967 }, nil, time.Time{}, []ReferenceRecord{ 2968 { 2969 view: &View{ 2970 Header: NewHeader("table1", []string{"column1", "column2"}), 2971 RecordSet: []Record{ 2972 { 2973 NewGroupCell([]value.Primary{ 2974 value.NewInteger(1), 2975 value.NewNull(), 2976 value.NewInteger(3), 2977 value.NewInteger(3), 2978 }), 2979 NewGroupCell([]value.Primary{ 2980 value.NewString("str1"), 2981 value.NewString("str2"), 2982 value.NewString("str3"), 2983 value.NewString("str4"), 2984 }), 2985 }, 2986 }, 2987 isGrouped: true, 2988 }, 2989 recordIndex: 0, 2990 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 2991 }, 2992 }), 2993 Expr: parser.AggregateFunction{ 2994 Name: "useraggfunc", 2995 Distinct: parser.Token{Token: parser.DISTINCT, Literal: "distinct"}, 2996 Args: []parser.QueryExpression{ 2997 parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}, 2998 }, 2999 }, 3000 Error: "function useraggfunc takes exactly 2 arguments", 3001 }, 3002 { 3003 Name: "Aggregate Function User Defined Argument Evaluation Error", 3004 Scope: GenerateReferenceScope([]map[string]map[string]interface{}{ 3005 { 3006 scopeNameFunctions: { 3007 "USERAGGFUNC": &UserDefinedFunction{ 3008 Name: parser.Identifier{Literal: "useraggfunc"}, 3009 IsAggregate: true, 3010 Cursor: parser.Identifier{Literal: "column1"}, 3011 Parameters: []parser.Variable{ 3012 {Name: "default"}, 3013 }, 3014 Statements: []parser.Statement{ 3015 parser.Return{ 3016 Value: parser.Variable{Name: "value"}, 3017 }, 3018 }, 3019 }, 3020 }, 3021 }, 3022 }, nil, time.Time{}, []ReferenceRecord{ 3023 { 3024 view: &View{ 3025 Header: NewHeader("table1", []string{"column1", "column2"}), 3026 RecordSet: []Record{ 3027 { 3028 NewGroupCell([]value.Primary{ 3029 value.NewInteger(1), 3030 value.NewNull(), 3031 value.NewInteger(3), 3032 value.NewInteger(3), 3033 }), 3034 NewGroupCell([]value.Primary{ 3035 value.NewString("str1"), 3036 value.NewString("str2"), 3037 value.NewString("str3"), 3038 value.NewString("str4"), 3039 }), 3040 }, 3041 }, 3042 isGrouped: true, 3043 }, 3044 recordIndex: 0, 3045 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 3046 }, 3047 }), 3048 Expr: parser.AggregateFunction{ 3049 Name: "useraggfunc", 3050 Distinct: parser.Token{Token: parser.DISTINCT, Literal: "distinct"}, 3051 Args: []parser.QueryExpression{ 3052 parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}, 3053 parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 3054 }, 3055 }, 3056 Error: "field notexist does not exist", 3057 }, 3058 { 3059 Name: "Aggregate Function Execute User Defined Aggregate Function Passed As Scalar Function", 3060 Scope: GenerateReferenceScope([]map[string]map[string]interface{}{ 3061 { 3062 scopeNameFunctions: { 3063 "USERAGGFUNC": &UserDefinedFunction{ 3064 Name: parser.Identifier{Literal: "useraggfunc"}, 3065 IsAggregate: true, 3066 Cursor: parser.Identifier{Literal: "column1"}, 3067 Statements: []parser.Statement{ 3068 parser.VariableDeclaration{ 3069 Assignments: []parser.VariableAssignment{ 3070 { 3071 Variable: parser.Variable{Name: "value"}, 3072 }, 3073 { 3074 Variable: parser.Variable{Name: "fetch"}, 3075 }, 3076 }, 3077 }, 3078 parser.WhileInCursor{ 3079 Variables: []parser.Variable{ 3080 {Name: "fetch"}, 3081 }, 3082 Cursor: parser.Identifier{Literal: "column1"}, 3083 Statements: []parser.Statement{ 3084 parser.If{ 3085 Condition: parser.Is{ 3086 LHS: parser.Variable{Name: "fetch"}, 3087 RHS: parser.NewNullValue(), 3088 }, 3089 Statements: []parser.Statement{ 3090 parser.FlowControl{Token: parser.CONTINUE}, 3091 }, 3092 }, 3093 parser.If{ 3094 Condition: parser.Is{ 3095 LHS: parser.Variable{Name: "value"}, 3096 RHS: parser.NewNullValue(), 3097 }, 3098 Statements: []parser.Statement{ 3099 parser.VariableSubstitution{ 3100 Variable: parser.Variable{Name: "value"}, 3101 Value: parser.Variable{Name: "fetch"}, 3102 }, 3103 parser.FlowControl{Token: parser.CONTINUE}, 3104 }, 3105 }, 3106 parser.VariableSubstitution{ 3107 Variable: parser.Variable{Name: "value"}, 3108 Value: parser.Arithmetic{ 3109 LHS: parser.Variable{Name: "value"}, 3110 RHS: parser.Variable{Name: "fetch"}, 3111 Operator: parser.Token{Token: '*', Literal: "*"}, 3112 }, 3113 }, 3114 }, 3115 }, 3116 parser.Return{ 3117 Value: parser.Variable{Name: "value"}, 3118 }, 3119 }, 3120 }, 3121 }, 3122 }, 3123 }, nil, time.Time{}, []ReferenceRecord{ 3124 { 3125 view: &View{ 3126 Header: NewHeader("table1", []string{"column1", "column2"}), 3127 RecordSet: []Record{ 3128 { 3129 NewGroupCell([]value.Primary{ 3130 value.NewInteger(1), 3131 value.NewNull(), 3132 value.NewInteger(3), 3133 }), 3134 NewGroupCell([]value.Primary{ 3135 value.NewString("str1"), 3136 value.NewString("str2"), 3137 value.NewString("str3"), 3138 }), 3139 }, 3140 }, 3141 isGrouped: true, 3142 }, 3143 recordIndex: 0, 3144 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 3145 }, 3146 }), 3147 Expr: parser.Function{ 3148 Name: "useraggfunc", 3149 Args: []parser.QueryExpression{ 3150 parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}, 3151 }, 3152 }, 3153 Result: value.NewInteger(3), 3154 }, 3155 { 3156 Name: "Aggregate Function Execute User Defined Aggregate Function Undeclared Error", 3157 Scope: GenerateReferenceScope([]map[string]map[string]interface{}{ 3158 { 3159 scopeNameFunctions: { 3160 "USERAGGFUNC": &UserDefinedFunction{ 3161 Name: parser.Identifier{Literal: "useraggfunc"}, 3162 IsAggregate: true, 3163 Cursor: parser.Identifier{Literal: "column1"}, 3164 Statements: []parser.Statement{ 3165 parser.VariableDeclaration{ 3166 Assignments: []parser.VariableAssignment{ 3167 { 3168 Variable: parser.Variable{Name: "value"}, 3169 }, 3170 { 3171 Variable: parser.Variable{Name: "fetch"}, 3172 }, 3173 }, 3174 }, 3175 parser.WhileInCursor{ 3176 Variables: []parser.Variable{ 3177 {Name: "fetch"}, 3178 }, 3179 Cursor: parser.Identifier{Literal: "column1"}, 3180 Statements: []parser.Statement{ 3181 parser.If{ 3182 Condition: parser.Is{ 3183 LHS: parser.Variable{Name: "fetch"}, 3184 RHS: parser.NewNullValue(), 3185 }, 3186 Statements: []parser.Statement{ 3187 parser.FlowControl{Token: parser.CONTINUE}, 3188 }, 3189 }, 3190 parser.If{ 3191 Condition: parser.Is{ 3192 LHS: parser.Variable{Name: "value"}, 3193 RHS: parser.NewNullValue(), 3194 }, 3195 Statements: []parser.Statement{ 3196 parser.VariableSubstitution{ 3197 Variable: parser.Variable{Name: "value"}, 3198 Value: parser.Variable{Name: "fetch"}, 3199 }, 3200 parser.FlowControl{Token: parser.CONTINUE}, 3201 }, 3202 }, 3203 parser.VariableSubstitution{ 3204 Variable: parser.Variable{Name: "value"}, 3205 Value: parser.Arithmetic{ 3206 LHS: parser.Variable{Name: "value"}, 3207 RHS: parser.Variable{Name: "fetch"}, 3208 Operator: parser.Token{Token: '*', Literal: "*"}, 3209 }, 3210 }, 3211 }, 3212 }, 3213 parser.Return{ 3214 Value: parser.Variable{Name: "value"}, 3215 }, 3216 }, 3217 }, 3218 }, 3219 }, 3220 }, nil, time.Time{}, []ReferenceRecord{ 3221 { 3222 view: &View{ 3223 Header: NewHeader("table1", []string{"column1", "column2"}), 3224 RecordSet: []Record{ 3225 { 3226 NewGroupCell([]value.Primary{ 3227 value.NewInteger(1), 3228 value.NewNull(), 3229 value.NewInteger(3), 3230 }), 3231 NewGroupCell([]value.Primary{ 3232 value.NewString("str1"), 3233 value.NewString("str2"), 3234 value.NewString("str3"), 3235 }), 3236 }, 3237 }, 3238 isGrouped: true, 3239 }, 3240 recordIndex: 0, 3241 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 3242 }, 3243 }), 3244 Expr: parser.AggregateFunction{ 3245 Name: "undefined", 3246 Args: []parser.QueryExpression{ 3247 parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}, 3248 }, 3249 }, 3250 Error: "function undefined does not exist", 3251 }, 3252 { 3253 Name: "ListAgg Function", 3254 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 3255 { 3256 view: &View{ 3257 Header: NewHeaderWithId("table1", []string{"column1", "column2"}), 3258 RecordSet: []Record{ 3259 { 3260 NewGroupCell([]value.Primary{ 3261 value.NewInteger(1), 3262 value.NewInteger(2), 3263 value.NewInteger(3), 3264 value.NewInteger(4), 3265 }), 3266 NewGroupCell([]value.Primary{ 3267 value.NewInteger(1), 3268 value.NewInteger(2), 3269 value.NewInteger(3), 3270 value.NewInteger(4), 3271 }), 3272 NewGroupCell([]value.Primary{ 3273 value.NewString("str2"), 3274 value.NewString("str1"), 3275 value.NewNull(), 3276 value.NewString("str2"), 3277 }), 3278 }, 3279 }, 3280 isGrouped: true, 3281 }, 3282 recordIndex: 0, 3283 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 3284 }, 3285 }), 3286 Expr: parser.ListFunction{ 3287 Name: "listagg", 3288 Distinct: parser.Token{Token: parser.DISTINCT, Literal: "distinct"}, 3289 Args: []parser.QueryExpression{ 3290 parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}, 3291 parser.NewStringValue(","), 3292 }, 3293 OrderBy: parser.OrderByClause{ 3294 Items: []parser.QueryExpression{ 3295 parser.OrderItem{Value: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}}, 3296 }, 3297 }, 3298 }, 3299 Result: value.NewString("str1,str2"), 3300 }, 3301 { 3302 Name: "ListAgg Function Null", 3303 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 3304 { 3305 view: &View{ 3306 Header: NewHeaderWithId("table1", []string{"column1", "column2"}), 3307 RecordSet: []Record{ 3308 { 3309 NewGroupCell([]value.Primary{ 3310 value.NewInteger(1), 3311 value.NewInteger(2), 3312 value.NewInteger(3), 3313 value.NewInteger(4), 3314 }), 3315 NewGroupCell([]value.Primary{ 3316 value.NewInteger(1), 3317 value.NewInteger(2), 3318 value.NewInteger(3), 3319 value.NewInteger(4), 3320 }), 3321 NewGroupCell([]value.Primary{ 3322 value.NewNull(), 3323 value.NewNull(), 3324 value.NewNull(), 3325 value.NewNull(), 3326 }), 3327 }, 3328 }, 3329 isGrouped: true, 3330 }, 3331 recordIndex: 0, 3332 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 3333 }, 3334 }), 3335 Expr: parser.ListFunction{ 3336 Distinct: parser.Token{Token: parser.DISTINCT, Literal: "distinct"}, 3337 Args: []parser.QueryExpression{ 3338 parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}, 3339 parser.NewStringValue(","), 3340 }, 3341 }, 3342 Result: value.NewNull(), 3343 }, 3344 { 3345 Name: "ListAgg Function Argument Length Error", 3346 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 3347 { 3348 view: &View{ 3349 Header: NewHeaderWithId("table1", []string{"column1", "column2"}), 3350 RecordSet: []Record{ 3351 NewRecordWithId(1, []value.Primary{ 3352 value.NewInteger(1), 3353 value.NewString("str2"), 3354 }), 3355 }, 3356 }, 3357 recordIndex: 0, 3358 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 3359 }, 3360 }), 3361 Expr: parser.ListFunction{ 3362 Name: "listagg", 3363 Distinct: parser.Token{Token: parser.DISTINCT, Literal: "distinct"}, 3364 OrderBy: parser.OrderByClause{ 3365 Items: []parser.QueryExpression{ 3366 parser.OrderItem{Value: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}}, 3367 }, 3368 }, 3369 }, 3370 Error: "function listagg takes 1 or 2 arguments", 3371 }, 3372 { 3373 Name: "ListAgg Function Not Grouped Error", 3374 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 3375 { 3376 view: &View{ 3377 Header: NewHeaderWithId("table1", []string{"column1", "column2"}), 3378 RecordSet: []Record{ 3379 NewRecordWithId(1, []value.Primary{ 3380 value.NewInteger(1), 3381 value.NewString("str2"), 3382 }), 3383 }, 3384 }, 3385 recordIndex: 0, 3386 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 3387 }, 3388 }), 3389 Expr: parser.ListFunction{ 3390 Name: "listagg", 3391 Distinct: parser.Token{Token: parser.DISTINCT, Literal: "distinct"}, 3392 Args: []parser.QueryExpression{ 3393 parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}, 3394 parser.NewStringValue(","), 3395 }, 3396 OrderBy: parser.OrderByClause{ 3397 Items: []parser.QueryExpression{ 3398 parser.OrderItem{Value: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}}, 3399 }, 3400 }, 3401 }, 3402 Error: "function listagg cannot aggregate not grouping records", 3403 }, 3404 { 3405 Name: "ListAgg Function Sort Error", 3406 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 3407 { 3408 view: &View{ 3409 Header: NewHeaderWithId("table1", []string{"column1", "column2"}), 3410 RecordSet: []Record{ 3411 { 3412 NewGroupCell([]value.Primary{ 3413 value.NewInteger(1), 3414 value.NewInteger(2), 3415 value.NewInteger(3), 3416 value.NewInteger(4), 3417 }), 3418 NewGroupCell([]value.Primary{ 3419 value.NewString("str2"), 3420 value.NewString("str1"), 3421 value.NewNull(), 3422 value.NewString("str2"), 3423 }), 3424 }, 3425 }, 3426 isGrouped: true, 3427 }, 3428 recordIndex: 0, 3429 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 3430 }, 3431 }), 3432 Expr: parser.ListFunction{ 3433 Name: "listagg", 3434 Distinct: parser.Token{Token: parser.DISTINCT, Literal: "distinct"}, 3435 Args: []parser.QueryExpression{ 3436 parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}, 3437 parser.NewStringValue(","), 3438 }, 3439 OrderBy: parser.OrderByClause{ 3440 Items: []parser.QueryExpression{ 3441 parser.OrderItem{Value: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}}, 3442 }, 3443 }, 3444 }, 3445 Error: "field notexist does not exist", 3446 }, 3447 { 3448 Name: "ListAgg Function Nested Error", 3449 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 3450 { 3451 view: &View{ 3452 Header: NewHeaderWithId("table1", []string{"column1", "column2"}), 3453 RecordSet: []Record{ 3454 { 3455 NewGroupCell([]value.Primary{ 3456 value.NewInteger(1), 3457 value.NewNull(), 3458 value.NewInteger(3), 3459 }), 3460 NewGroupCell([]value.Primary{ 3461 value.NewString("str1"), 3462 value.NewString("str2"), 3463 value.NewString("str3"), 3464 }), 3465 }, 3466 }, 3467 isGrouped: true, 3468 }, 3469 recordIndex: 0, 3470 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 3471 }, 3472 }), 3473 Expr: parser.ListFunction{ 3474 Name: "listagg", 3475 Args: []parser.QueryExpression{ 3476 parser.AggregateFunction{ 3477 Name: "avg", 3478 Distinct: parser.Token{}, 3479 Args: []parser.QueryExpression{ 3480 parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}, 3481 }, 3482 }, 3483 }, 3484 }, 3485 Error: "aggregate functions are nested at LISTAGG(AVG(column1))", 3486 }, 3487 { 3488 Name: "ListAgg Function Second Argument Evaluation Error", 3489 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 3490 { 3491 view: &View{ 3492 Header: NewHeaderWithId("table1", []string{"column1", "column2"}), 3493 RecordSet: []Record{ 3494 { 3495 NewGroupCell([]value.Primary{ 3496 value.NewInteger(1), 3497 value.NewNull(), 3498 value.NewInteger(3), 3499 }), 3500 NewGroupCell([]value.Primary{ 3501 value.NewString("str1"), 3502 value.NewString("str2"), 3503 value.NewString("str3"), 3504 }), 3505 }, 3506 }, 3507 isGrouped: true, 3508 }, 3509 recordIndex: 0, 3510 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 3511 }, 3512 }), 3513 Expr: parser.ListFunction{ 3514 Name: "listagg", 3515 Args: []parser.QueryExpression{ 3516 parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}, 3517 parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}, 3518 }, 3519 }, 3520 Error: "the second argument must be a string for function listagg", 3521 }, 3522 { 3523 Name: "ListAgg Function Second Argument Not String Error", 3524 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 3525 { 3526 view: &View{ 3527 Header: NewHeaderWithId("table1", []string{"column1", "column2"}), 3528 RecordSet: []Record{ 3529 { 3530 NewGroupCell([]value.Primary{ 3531 value.NewInteger(1), 3532 value.NewNull(), 3533 value.NewInteger(3), 3534 }), 3535 NewGroupCell([]value.Primary{ 3536 value.NewString("str1"), 3537 value.NewString("str2"), 3538 value.NewString("str3"), 3539 }), 3540 }, 3541 }, 3542 isGrouped: true, 3543 }, 3544 recordIndex: 0, 3545 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 3546 }, 3547 }), 3548 Expr: parser.ListFunction{ 3549 Name: "listagg", 3550 Args: []parser.QueryExpression{ 3551 parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}, 3552 parser.NewNullValue(), 3553 }, 3554 }, 3555 Error: "the second argument must be a string for function listagg", 3556 }, 3557 { 3558 Name: "ListAgg Function As a Statement Error", 3559 Expr: parser.ListFunction{ 3560 Name: "listagg", 3561 Distinct: parser.Token{Token: parser.DISTINCT, Literal: "distinct"}, 3562 Args: []parser.QueryExpression{ 3563 parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}, 3564 parser.NewStringValue(","), 3565 }, 3566 OrderBy: parser.OrderByClause{ 3567 Items: []parser.QueryExpression{ 3568 parser.OrderItem{Value: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}}, 3569 }, 3570 }, 3571 }, 3572 Result: value.NewNull(), 3573 }, 3574 { 3575 Name: "JsonAgg Function", 3576 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 3577 { 3578 view: &View{ 3579 Header: NewHeaderWithId("table1", []string{"column1", "column2"}), 3580 RecordSet: []Record{ 3581 { 3582 NewGroupCell([]value.Primary{ 3583 value.NewInteger(1), 3584 value.NewInteger(2), 3585 value.NewInteger(3), 3586 value.NewInteger(4), 3587 }), 3588 NewGroupCell([]value.Primary{ 3589 value.NewInteger(1), 3590 value.NewInteger(2), 3591 value.NewInteger(3), 3592 value.NewInteger(4), 3593 }), 3594 NewGroupCell([]value.Primary{ 3595 value.NewString("str2"), 3596 value.NewString("str1"), 3597 value.NewNull(), 3598 value.NewString("str2"), 3599 }), 3600 }, 3601 }, 3602 isGrouped: true, 3603 }, 3604 recordIndex: 0, 3605 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 3606 }, 3607 }), 3608 Expr: parser.ListFunction{ 3609 Name: "json_agg", 3610 Distinct: parser.Token{Token: parser.DISTINCT, Literal: "distinct"}, 3611 Args: []parser.QueryExpression{ 3612 parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}, 3613 }, 3614 OrderBy: parser.OrderByClause{ 3615 Items: []parser.QueryExpression{ 3616 parser.OrderItem{Value: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}}, 3617 }, 3618 }, 3619 }, 3620 Result: value.NewString("[null,\"str1\",\"str2\"]"), 3621 }, 3622 { 3623 Name: "JsonAgg Function Arguments Error", 3624 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 3625 { 3626 view: &View{ 3627 Header: NewHeaderWithId("table1", []string{"column1", "column2"}), 3628 RecordSet: []Record{ 3629 { 3630 NewGroupCell([]value.Primary{ 3631 value.NewInteger(1), 3632 value.NewInteger(2), 3633 }), 3634 NewGroupCell([]value.Primary{ 3635 value.NewInteger(1), 3636 value.NewInteger(2), 3637 }), 3638 NewGroupCell([]value.Primary{ 3639 value.NewString("str2"), 3640 value.NewString("str1"), 3641 }), 3642 }, 3643 }, 3644 isGrouped: true, 3645 }, 3646 recordIndex: 0, 3647 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 3648 }, 3649 }), 3650 Expr: parser.ListFunction{ 3651 Name: "json_agg", 3652 Distinct: parser.Token{Token: parser.DISTINCT, Literal: "distinct"}, 3653 Args: []parser.QueryExpression{}, 3654 OrderBy: parser.OrderByClause{ 3655 Items: []parser.QueryExpression{ 3656 parser.OrderItem{Value: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}}, 3657 }, 3658 }, 3659 }, 3660 Error: "function json_agg takes exactly 1 argument", 3661 }, 3662 { 3663 Name: "Analytic Function", 3664 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 3665 { 3666 view: &View{ 3667 Header: append( 3668 NewHeader("table1", []string{"column1", "column2"}), 3669 HeaderField{Identifier: "RANK() OVER (PARTITION BY column1 ORDER BY column2)", Column: "RANK() OVER (PARTITION BY column1 ORDER BY column2)"}, 3670 ), 3671 RecordSet: []Record{ 3672 NewRecord([]value.Primary{ 3673 value.NewString("a"), 3674 value.NewInteger(11), 3675 value.NewInteger(1), 3676 }), 3677 NewRecord([]value.Primary{ 3678 value.NewString("b"), 3679 value.NewInteger(22), 3680 value.NewInteger(2), 3681 }), 3682 NewRecord([]value.Primary{ 3683 value.NewString("c"), 3684 value.NewInteger(33), 3685 value.NewInteger(3), 3686 }), 3687 }, 3688 }, 3689 recordIndex: 1, 3690 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 3691 }, 3692 }), 3693 Expr: parser.AnalyticFunction{ 3694 Name: "rank", 3695 AnalyticClause: parser.AnalyticClause{ 3696 PartitionClause: parser.PartitionClause{ 3697 Values: []parser.QueryExpression{ 3698 parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}, 3699 }, 3700 }, 3701 OrderByClause: parser.OrderByClause{ 3702 Items: []parser.QueryExpression{ 3703 parser.OrderItem{ 3704 Value: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}, 3705 }, 3706 }, 3707 }, 3708 }, 3709 }, 3710 Result: value.NewInteger(2), 3711 }, 3712 { 3713 Name: "Analytic Function Not Allowed Error", 3714 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 3715 { 3716 view: &View{ 3717 Header: NewHeader("table1", []string{"column1", "column2"}), 3718 RecordSet: []Record{ 3719 NewRecord([]value.Primary{ 3720 value.NewString("a"), 3721 value.NewInteger(11), 3722 }), 3723 NewRecord([]value.Primary{ 3724 value.NewString("b"), 3725 value.NewInteger(22), 3726 }), 3727 NewRecord([]value.Primary{ 3728 value.NewString("c"), 3729 value.NewInteger(33), 3730 }), 3731 }, 3732 }, 3733 recordIndex: 1, 3734 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 3735 }, 3736 }), 3737 Expr: parser.AnalyticFunction{ 3738 Name: "rank", 3739 AnalyticClause: parser.AnalyticClause{ 3740 PartitionClause: parser.PartitionClause{ 3741 Values: []parser.QueryExpression{ 3742 parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}, 3743 }, 3744 }, 3745 OrderByClause: parser.OrderByClause{ 3746 Items: []parser.QueryExpression{ 3747 parser.OrderItem{ 3748 Value: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}, 3749 }, 3750 }, 3751 }, 3752 }, 3753 }, 3754 Error: "analytic function rank is only available in select clause or order by clause", 3755 }, 3756 { 3757 Name: "CaseExpr Comparison", 3758 Expr: parser.CaseExpr{ 3759 Value: parser.NewIntegerValue(2), 3760 When: []parser.QueryExpression{ 3761 parser.CaseExprWhen{ 3762 Condition: parser.NewIntegerValue(1), 3763 Result: parser.NewStringValue("A"), 3764 }, 3765 parser.CaseExprWhen{ 3766 Condition: parser.NewIntegerValue(2), 3767 Result: parser.NewStringValue("B"), 3768 }, 3769 }, 3770 }, 3771 Result: value.NewString("B"), 3772 }, 3773 { 3774 Name: "CaseExpr Filter", 3775 Expr: parser.CaseExpr{ 3776 When: []parser.QueryExpression{ 3777 parser.CaseExprWhen{ 3778 Condition: parser.Comparison{ 3779 LHS: parser.NewIntegerValue(2), 3780 RHS: parser.NewIntegerValue(1), 3781 Operator: parser.Token{Token: '=', Literal: "="}, 3782 }, 3783 Result: parser.NewStringValue("A"), 3784 }, 3785 parser.CaseExprWhen{ 3786 Condition: parser.Comparison{ 3787 LHS: parser.NewIntegerValue(2), 3788 RHS: parser.NewIntegerValue(2), 3789 Operator: parser.Token{Token: '=', Literal: "="}, 3790 }, 3791 Result: parser.NewStringValue("B"), 3792 }, 3793 }, 3794 }, 3795 Result: value.NewString("B"), 3796 }, 3797 { 3798 Name: "CaseExpr Else", 3799 Expr: parser.CaseExpr{ 3800 Value: parser.NewIntegerValue(0), 3801 When: []parser.QueryExpression{ 3802 parser.CaseExprWhen{ 3803 Condition: parser.NewIntegerValue(1), 3804 Result: parser.NewStringValue("A"), 3805 }, 3806 parser.CaseExprWhen{ 3807 Condition: parser.NewIntegerValue(2), 3808 Result: parser.NewStringValue("B"), 3809 }, 3810 }, 3811 Else: parser.CaseExprElse{ 3812 Result: parser.NewStringValue("C"), 3813 }, 3814 }, 3815 Result: value.NewString("C"), 3816 }, 3817 { 3818 Name: "CaseExpr No Else", 3819 Expr: parser.CaseExpr{ 3820 Value: parser.NewIntegerValue(0), 3821 When: []parser.QueryExpression{ 3822 parser.CaseExprWhen{ 3823 Condition: parser.NewIntegerValue(1), 3824 Result: parser.NewStringValue("A"), 3825 }, 3826 parser.CaseExprWhen{ 3827 Condition: parser.NewIntegerValue(2), 3828 Result: parser.NewStringValue("B"), 3829 }, 3830 }, 3831 }, 3832 Result: value.NewNull(), 3833 }, 3834 { 3835 Name: "CaseExpr Value Error", 3836 Expr: parser.CaseExpr{ 3837 Value: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 3838 When: []parser.QueryExpression{ 3839 parser.CaseExprWhen{ 3840 Condition: parser.NewIntegerValue(1), 3841 Result: parser.NewStringValue("A"), 3842 }, 3843 parser.CaseExprWhen{ 3844 Condition: parser.NewIntegerValue(2), 3845 Result: parser.NewStringValue("B"), 3846 }, 3847 }, 3848 }, 3849 Error: "field notexist does not exist", 3850 }, 3851 { 3852 Name: "CaseExpr When Condition Error", 3853 Expr: parser.CaseExpr{ 3854 Value: parser.NewIntegerValue(2), 3855 When: []parser.QueryExpression{ 3856 parser.CaseExprWhen{ 3857 Condition: parser.NewIntegerValue(1), 3858 Result: parser.NewStringValue("A"), 3859 }, 3860 parser.CaseExprWhen{ 3861 Condition: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 3862 Result: parser.NewStringValue("B"), 3863 }, 3864 }, 3865 }, 3866 Error: "field notexist does not exist", 3867 }, 3868 { 3869 Name: "CaseExpr When Result Error", 3870 Expr: parser.CaseExpr{ 3871 Value: parser.NewIntegerValue(2), 3872 When: []parser.QueryExpression{ 3873 parser.CaseExprWhen{ 3874 Condition: parser.NewIntegerValue(1), 3875 Result: parser.NewStringValue("A"), 3876 }, 3877 parser.CaseExprWhen{ 3878 Condition: parser.NewIntegerValue(2), 3879 Result: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 3880 }, 3881 }, 3882 }, 3883 Error: "field notexist does not exist", 3884 }, 3885 { 3886 Name: "CaseExpr Else Result Error", 3887 Expr: parser.CaseExpr{ 3888 Value: parser.NewIntegerValue(0), 3889 When: []parser.QueryExpression{ 3890 parser.CaseExprWhen{ 3891 Condition: parser.NewIntegerValue(1), 3892 Result: parser.NewStringValue("A"), 3893 }, 3894 parser.CaseExprWhen{ 3895 Condition: parser.NewIntegerValue(2), 3896 Result: parser.NewStringValue("B"), 3897 }, 3898 }, 3899 Else: parser.CaseExprElse{ 3900 Result: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 3901 }, 3902 }, 3903 Error: "field notexist does not exist", 3904 }, 3905 { 3906 Name: "Logic AND", 3907 Expr: parser.Logic{ 3908 LHS: parser.NewTernaryValue(ternary.TRUE), 3909 RHS: parser.NewTernaryValue(ternary.FALSE), 3910 Operator: parser.Token{Token: parser.AND, Literal: "and"}, 3911 }, 3912 Result: value.NewTernary(ternary.FALSE), 3913 }, 3914 { 3915 Name: "Logic AND Decided with LHS", 3916 Expr: parser.Logic{ 3917 LHS: parser.NewTernaryValue(ternary.FALSE), 3918 RHS: parser.NewTernaryValue(ternary.FALSE), 3919 Operator: parser.Token{Token: parser.AND, Literal: "and"}, 3920 }, 3921 Result: value.NewTernary(ternary.FALSE), 3922 }, 3923 { 3924 Name: "Logic OR", 3925 Expr: parser.Logic{ 3926 LHS: parser.NewTernaryValue(ternary.FALSE), 3927 RHS: parser.NewTernaryValue(ternary.TRUE), 3928 Operator: parser.Token{Token: parser.OR, Literal: "or"}, 3929 }, 3930 Result: value.NewTernary(ternary.TRUE), 3931 }, 3932 { 3933 Name: "Logic OR Decided with LHS", 3934 Expr: parser.Logic{ 3935 LHS: parser.NewTernaryValue(ternary.TRUE), 3936 RHS: parser.NewTernaryValue(ternary.FALSE), 3937 Operator: parser.Token{Token: parser.OR, Literal: "or"}, 3938 }, 3939 Result: value.NewTernary(ternary.TRUE), 3940 }, 3941 { 3942 Name: "Logic LHS Error", 3943 Expr: parser.Logic{ 3944 LHS: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 3945 RHS: parser.NewTernaryValue(ternary.FALSE), 3946 Operator: parser.Token{Token: parser.AND, Literal: "and"}, 3947 }, 3948 Error: "field notexist does not exist", 3949 }, 3950 { 3951 Name: "Logic RHS Error", 3952 Expr: parser.Logic{ 3953 LHS: parser.NewTernaryValue(ternary.UNKNOWN), 3954 RHS: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 3955 Operator: parser.Token{Token: parser.AND, Literal: "and"}, 3956 }, 3957 Error: "field notexist does not exist", 3958 }, 3959 { 3960 Name: "UnaryLogic", 3961 Expr: parser.UnaryLogic{ 3962 Operand: parser.NewTernaryValue(ternary.FALSE), 3963 Operator: parser.Token{Token: parser.NOT, Literal: "not"}, 3964 }, 3965 Result: value.NewTernary(ternary.TRUE), 3966 }, 3967 { 3968 Name: "UnaryLogic Operand Error", 3969 Expr: parser.UnaryLogic{ 3970 Operand: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}, 3971 Operator: parser.Token{Token: parser.NOT, Literal: "not"}, 3972 }, 3973 Error: "field notexist does not exist", 3974 }, 3975 { 3976 Name: "Variable", 3977 Scope: GenerateReferenceScope([]map[string]map[string]interface{}{ 3978 { 3979 scopeNameVariables: { 3980 "var1": value.NewInteger(1), 3981 }, 3982 }, 3983 }, nil, time.Time{}, nil), 3984 Expr: parser.Variable{ 3985 Name: "var1", 3986 }, 3987 Result: value.NewInteger(1), 3988 }, 3989 { 3990 Name: "Environment Variable", 3991 Expr: parser.EnvironmentVariable{ 3992 Name: "CSVQ_TEST_ENV", 3993 }, 3994 Result: value.NewString("foo"), 3995 }, 3996 { 3997 Name: "Runtime Information", 3998 Expr: parser.RuntimeInformation{ 3999 Name: "version", 4000 }, 4001 Result: value.NewString("v1.0.0"), 4002 }, 4003 { 4004 Name: "Constant", 4005 Expr: parser.Constant{ 4006 Space: "math", 4007 Name: "pi", 4008 }, 4009 Result: value.NewFloat(math.Pi), 4010 }, 4011 { 4012 Name: "Constant Undefined Error", 4013 Expr: parser.Constant{ 4014 Space: "math", 4015 Name: "undefined", 4016 }, 4017 Error: "constant MATH::UNDEFINED is not defined", 4018 }, 4019 { 4020 Name: "Flag", 4021 Expr: parser.Flag{ 4022 Name: "json_escape", 4023 }, 4024 Result: value.NewString("BACKSLASH"), 4025 }, 4026 { 4027 Name: "Flag Ivalid Flag Name Error", 4028 Expr: parser.Flag{ 4029 Name: "invalid", 4030 }, 4031 Error: "@@INVALID is an unknown flag", 4032 }, 4033 { 4034 Name: "Variable Undeclared Error", 4035 Expr: parser.Variable{ 4036 Name: "undefined", 4037 }, 4038 Error: "variable @undefined is undeclared", 4039 }, 4040 { 4041 Name: "Variable Substitution", 4042 Scope: GenerateReferenceScope([]map[string]map[string]interface{}{ 4043 { 4044 scopeNameVariables: { 4045 "var1": value.NewInteger(1), 4046 }, 4047 }, 4048 }, nil, time.Time{}, nil), 4049 Expr: parser.VariableSubstitution{ 4050 Variable: parser.Variable{Name: "var1"}, 4051 Value: parser.NewIntegerValue(2), 4052 }, 4053 Result: value.NewInteger(2), 4054 }, 4055 { 4056 Name: "Variable Substitution Undeclared Error", 4057 Expr: parser.VariableSubstitution{ 4058 Variable: parser.Variable{Name: "undefined"}, 4059 Value: parser.NewIntegerValue(2), 4060 }, 4061 Error: "variable @undefined is undeclared", 4062 }, 4063 { 4064 Name: "Cursor Status Is Not Open", 4065 Expr: parser.CursorStatus{ 4066 Cursor: parser.Identifier{Literal: "cur"}, 4067 Negation: parser.Token{Token: parser.NOT, Literal: "not"}, 4068 Type: parser.Token{Token: parser.OPEN, Literal: "open"}, 4069 }, 4070 Result: value.NewTernary(ternary.FALSE), 4071 }, 4072 { 4073 Name: "Cursor Status Is In Range", 4074 Expr: parser.CursorStatus{ 4075 Cursor: parser.Identifier{Literal: "cur"}, 4076 Type: parser.Token{Token: parser.RANGE, Literal: "range"}, 4077 }, 4078 Result: value.NewTernary(ternary.TRUE), 4079 }, 4080 { 4081 Name: "Cursor Status Open Error", 4082 Expr: parser.CursorStatus{ 4083 Cursor: parser.Identifier{Literal: "notexist"}, 4084 Type: parser.Token{Token: parser.OPEN, Literal: "open"}, 4085 }, 4086 Error: "cursor notexist is undeclared", 4087 }, 4088 { 4089 Name: "Cursor Status In Range Error", 4090 Expr: parser.CursorStatus{ 4091 Cursor: parser.Identifier{Literal: "notexist"}, 4092 Type: parser.Token{Token: parser.RANGE, Literal: "range"}, 4093 }, 4094 Error: "cursor notexist is undeclared", 4095 }, 4096 { 4097 Name: "Cursor Attribute Count", 4098 Expr: parser.CursorAttrebute{ 4099 Cursor: parser.Identifier{Literal: "cur"}, 4100 Attrebute: parser.Token{Token: parser.COUNT, Literal: "count"}, 4101 }, 4102 Result: value.NewInteger(3), 4103 }, 4104 { 4105 Name: "Cursor Attribute Count Error", 4106 Expr: parser.CursorAttrebute{ 4107 Cursor: parser.Identifier{Literal: "notexist"}, 4108 Attrebute: parser.Token{Token: parser.COUNT, Literal: "count"}, 4109 }, 4110 Error: "cursor notexist is undeclared", 4111 }, 4112 { 4113 Name: "Placeholder Ordinal", 4114 Expr: parser.Placeholder{ 4115 Literal: "?", 4116 Ordinal: 1, 4117 }, 4118 ReplaceValues: &ReplaceValues{ 4119 Values: []parser.QueryExpression{parser.NewIntegerValueFromString("1")}, 4120 Names: map[string]int{}, 4121 }, 4122 Result: value.NewInteger(1), 4123 }, 4124 { 4125 Name: "Placeholder Named", 4126 Expr: parser.Placeholder{ 4127 Literal: ":val", 4128 Ordinal: 1, 4129 Name: "val", 4130 }, 4131 ReplaceValues: &ReplaceValues{ 4132 Values: []parser.QueryExpression{parser.NewIntegerValueFromString("1")}, 4133 Names: map[string]int{"val": 0}, 4134 }, 4135 Result: value.NewInteger(1), 4136 }, 4137 { 4138 Name: "Placeholder Replace Values Not Exist Error", 4139 Expr: parser.Placeholder{ 4140 Literal: "?", 4141 Ordinal: 1, 4142 }, 4143 Error: "replace value for ?{1} is not specified", 4144 }, 4145 { 4146 Name: "Placeholder Ordinal Replace Value Not Exist Error", 4147 Expr: parser.Placeholder{ 4148 Literal: "?", 4149 Ordinal: 10, 4150 }, 4151 ReplaceValues: &ReplaceValues{ 4152 Values: []parser.QueryExpression{parser.NewIntegerValueFromString("1")}, 4153 }, 4154 Error: "replace value for ?{10} is not specified", 4155 }, 4156 { 4157 Name: "Placeholder Named Replace Value Not Exist Error", 4158 Expr: parser.Placeholder{ 4159 Literal: ":notexist", 4160 Ordinal: 1, 4161 Name: "notexist", 4162 }, 4163 ReplaceValues: &ReplaceValues{ 4164 Values: []parser.QueryExpression{parser.NewIntegerValueFromString("1")}, 4165 Names: map[string]int{"val": 0}, 4166 }, 4167 Error: "replace value for :notexist is not specified", 4168 }, 4169 } 4170 4171 func TestEvaluate(t *testing.T) { 4172 defer func() { 4173 _ = TestTx.CachedViews.Clean(TestTx.FileContainer) 4174 initFlag(TestTx.Flags) 4175 }() 4176 4177 TestTx.Flags.Repository = TestDataDir 4178 scope := GenerateReferenceScope([]map[string]map[string]interface{}{ 4179 { 4180 scopeNameCursors: { 4181 "CUR": &Cursor{ 4182 query: selectQueryForCursorTest, 4183 mtx: &sync.Mutex{}, 4184 }, 4185 }, 4186 }, 4187 }, nil, time.Time{}, nil) 4188 4189 ctx := context.Background() 4190 _ = scope.OpenCursor(ctx, parser.Identifier{Literal: "cur"}, nil) 4191 _, _ = scope.FetchCursor(parser.Identifier{Literal: "cur"}, parser.NEXT, 0) 4192 4193 for _, v := range evaluateTests { 4194 _ = TestTx.CachedViews.Clean(TestTx.FileContainer) 4195 4196 if v.Scope == nil { 4197 v.Scope = scope 4198 } 4199 4200 evalCtx := ctx 4201 if v.ReplaceValues != nil { 4202 evalCtx = ContextForPreparedStatement(ctx, v.ReplaceValues) 4203 } 4204 result, err := Evaluate(evalCtx, v.Scope, v.Expr) 4205 if err != nil { 4206 if len(v.Error) < 1 { 4207 t.Errorf("%s: unexpected error %q", v.Name, err) 4208 } else if err.Error() != v.Error { 4209 t.Errorf("%s: error %q, want error %q", v.Name, err.Error(), v.Error) 4210 } 4211 continue 4212 } 4213 if 0 < len(v.Error) { 4214 t.Errorf("%s: no error, want error %q", v.Name, v.Error) 4215 continue 4216 } 4217 if !reflect.DeepEqual(result, v.Result) { 4218 t.Errorf("%s: result = %q, want %q", v.Name, result, v.Result) 4219 } 4220 } 4221 } 4222 4223 var evaluateEmbeddedStringTests = []struct { 4224 Input string 4225 Expect string 4226 Error string 4227 }{ 4228 { 4229 Input: "str", 4230 Expect: "str", 4231 }, 4232 { 4233 Input: "str\\tstr", 4234 Expect: "str\tstr", 4235 }, 4236 { 4237 Input: "str\\\\tstr", 4238 Expect: "str\\tstr", 4239 }, 4240 { 4241 Input: "str''str", 4242 Expect: "str''str", 4243 }, 4244 { 4245 Input: "'str''str'", 4246 Expect: "str'str", 4247 }, 4248 { 4249 Input: "\"str\"\"str\"", 4250 Expect: "str\"str", 4251 }, 4252 { 4253 Input: "@var", 4254 Expect: "1", 4255 }, 4256 { 4257 Input: "@%CSVQ_TEST_FILTER", 4258 Expect: "FILTER_TEST", 4259 }, 4260 { 4261 Input: "@#version", 4262 Expect: "v1.0.0", 4263 }, 4264 { 4265 Input: "abc${}def", 4266 Expect: "abcdef", 4267 }, 4268 { 4269 Input: "abc${@var}def", 4270 Expect: "abc1def", 4271 }, 4272 { 4273 Input: "abc${'a\\tb'}def", 4274 Expect: "abca\tbdef", 4275 }, 4276 { 4277 Input: "abc${'a\\\\tb'}def", 4278 Expect: "abca\\tbdef", 4279 }, 4280 { 4281 Input: "@notexist", 4282 Error: "variable @notexist is undeclared", 4283 }, 4284 { 4285 Input: "@#notexist", 4286 Error: "@#NOTEXIST is an unknown runtime information", 4287 }, 4288 { 4289 Input: "abc${invalid expr}def", 4290 Error: "invalid expr [L:1 C:9] syntax error: unexpected token \"expr\"", 4291 }, 4292 { 4293 Input: "abc${print 1;}def", 4294 Error: "'print 1;': cannot evaluate as a value", 4295 }, 4296 { 4297 Input: "abc${print 1;print2;}def", 4298 Error: "print 1;print2; [L:1 C:15] syntax error: unexpected token \";\"", 4299 }, 4300 { 4301 Input: "abc${@notexist}def", 4302 Error: "@notexist [L:1 C:1] variable @notexist is undeclared", 4303 }, 4304 { 4305 Input: "abc${@var1; @var2;}def", 4306 Error: "'@var1; @var2;': cannot evaluate as a value", 4307 }, 4308 } 4309 4310 func TestEvaluateEmbeddedString(t *testing.T) { 4311 scope := NewReferenceScope(TestTx) 4312 _ = scope.DeclareVariableDirectly(parser.Variable{Name: "var"}, value.NewInteger(1)) 4313 _ = os.Setenv("CSVQ_TEST_FILTER", "FILTER_TEST") 4314 4315 for _, v := range evaluateEmbeddedStringTests { 4316 result, err := EvaluateEmbeddedString(context.Background(), scope, v.Input) 4317 4318 if err != nil { 4319 if len(v.Error) < 1 { 4320 t.Errorf("unexpected error %q for %q", err, v.Input) 4321 } else if err.Error() != v.Error { 4322 t.Errorf("error %q, want error %q for %q", err.Error(), v.Error, v.Input) 4323 } 4324 continue 4325 } 4326 if 0 < len(v.Error) { 4327 t.Errorf("no error, want error %q for %q", v.Error, v.Input) 4328 continue 4329 } 4330 4331 if result != v.Expect { 4332 t.Errorf("result = %q, want %q for %q", result, v.Expect, v.Input) 4333 } 4334 } 4335 } 4336 4337 func generateBenchGroupedViewScope() *ReferenceScope { 4338 primaries := make([]value.Primary, 10000) 4339 for i := 0; i < 10000; i++ { 4340 primaries[i] = value.NewInteger(int64(i)) 4341 } 4342 4343 view := &View{ 4344 Header: NewHeader("table1", []string{"c1"}), 4345 RecordSet: []Record{ 4346 { 4347 NewGroupCell(primaries), 4348 }, 4349 }, 4350 isGrouped: true, 4351 } 4352 4353 return NewReferenceScope(TestTx).CreateScopeForRecordEvaluation( 4354 view, 4355 0, 4356 ) 4357 } 4358 4359 func BenchmarkEvaluateCountAllColumns(b *testing.B) { 4360 ctx := context.Background() 4361 scope := generateBenchGroupedViewScope() 4362 4363 b.ResetTimer() 4364 4365 for i := 0; i < b.N; i++ { 4366 _, _ = Evaluate(ctx, scope, parser.AggregateFunction{ 4367 Name: "count", 4368 Distinct: parser.Token{}, 4369 Args: []parser.QueryExpression{ 4370 parser.AllColumns{}, 4371 }, 4372 }) 4373 } 4374 } 4375 4376 func BenchmarkEvaluateCount(b *testing.B) { 4377 ctx := context.Background() 4378 scope := generateBenchGroupedViewScope() 4379 4380 b.ResetTimer() 4381 4382 for i := 0; i < b.N; i++ { 4383 _, _ = Evaluate(ctx, scope, parser.AggregateFunction{ 4384 Name: "count", 4385 Distinct: parser.Token{}, 4386 Args: []parser.QueryExpression{ 4387 parser.FieldReference{Column: parser.Identifier{Literal: "c1"}}, 4388 }, 4389 }) 4390 } 4391 } 4392 4393 func BenchmarkEvaluateSingleThread(b *testing.B) { 4394 ctx := context.Background() 4395 4396 for i := 0; i < b.N; i++ { 4397 scope := NewReferenceScope(TestTx) 4398 4399 for j := 0; j < 150; j++ { 4400 _, _ = Evaluate(ctx, scope, parser.Comparison{ 4401 LHS: parser.NewIntegerValue(1), 4402 RHS: parser.NewStringValue("1"), 4403 Operator: parser.Token{Token: '=', Literal: "="}, 4404 }) 4405 } 4406 } 4407 } 4408 4409 func BenchmarkEvaluateMultiThread(b *testing.B) { 4410 ctx := context.Background() 4411 4412 for i := 0; i < b.N; i++ { 4413 wg := sync.WaitGroup{} 4414 for i := 0; i < 3; i++ { 4415 wg.Add(1) 4416 go func(thIdx int) { 4417 scope := NewReferenceScope(TestTx) 4418 4419 for j := 0; j < 50; j++ { 4420 _, _ = Evaluate(ctx, scope, parser.Comparison{ 4421 LHS: parser.NewIntegerValue(1), 4422 RHS: parser.NewStringValue("1"), 4423 Operator: parser.Token{Token: '=', Literal: "="}, 4424 }) 4425 } 4426 wg.Done() 4427 }(i) 4428 } 4429 wg.Wait() 4430 } 4431 } 4432 4433 var evaluateFieldReferenceBenchScope = GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 4434 { 4435 view: &View{ 4436 Header: NewHeader("table1", []string{"column1", "column2", "column3"}), 4437 RecordSet: RecordSet{ 4438 NewRecord([]value.Primary{ 4439 value.NewInteger(1), 4440 value.NewInteger(1), 4441 value.NewInteger(1), 4442 }), 4443 }, 4444 }, 4445 recordIndex: 0, 4446 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 4447 }, 4448 }) 4449 4450 var evaluateFieldReferenceBenchExpr = parser.FieldReference{ 4451 Column: parser.Identifier{Literal: "column3"}, 4452 } 4453 4454 func BenchmarkEvaluateFieldReference(b *testing.B) { 4455 ctx := context.Background() 4456 scope := evaluateFieldReferenceBenchScope 4457 expr := evaluateFieldReferenceBenchExpr 4458 4459 b.ResetTimer() 4460 for i := 0; i < b.N; i++ { 4461 _, _ = Evaluate(ctx, scope, expr) 4462 } 4463 }