github.com/Ali-iotechsys/sqlboiler/v4@v4.0.0-20221208124957-6aec9a5f1f71/types/array_test.go (about) 1 // Copyright (c) 2011-2013, 'pq' Contributors Portions Copyright (C) 2011 Blake Mizerany. MIT license. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining 4 // a copy of this software and associated documentation files (the "Software"), 5 // to deal in the Software without restriction, including without limitation the 6 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software 8 // is furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included 11 // in all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 14 // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 15 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 16 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 18 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 20 package types 21 22 import ( 23 "bytes" 24 "database/sql" 25 "database/sql/driver" 26 "math/rand" 27 "reflect" 28 "strings" 29 "testing" 30 ) 31 32 func TestParseArray(t *testing.T) { 33 for _, tt := range []struct { 34 input string 35 delim string 36 dims []int 37 elems [][]byte 38 }{ 39 {`{}`, `,`, nil, [][]byte{}}, 40 {`{NULL}`, `,`, []int{1}, [][]byte{nil}}, 41 {`{a}`, `,`, []int{1}, [][]byte{{'a'}}}, 42 {`{a,b}`, `,`, []int{2}, [][]byte{{'a'}, {'b'}}}, 43 {`{{a,b}}`, `,`, []int{1, 2}, [][]byte{{'a'}, {'b'}}}, 44 {`{{a},{b}}`, `,`, []int{2, 1}, [][]byte{{'a'}, {'b'}}}, 45 {`{{{a,b},{c,d},{e,f}}}`, `,`, []int{1, 3, 2}, [][]byte{ 46 {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'}, 47 }}, 48 {`{""}`, `,`, []int{1}, [][]byte{{}}}, 49 {`{","}`, `,`, []int{1}, [][]byte{{','}}}, 50 {`{",",","}`, `,`, []int{2}, [][]byte{{','}, {','}}}, 51 {`{{",",","}}`, `,`, []int{1, 2}, [][]byte{{','}, {','}}}, 52 {`{{","},{","}}`, `,`, []int{2, 1}, [][]byte{{','}, {','}}}, 53 {`{{{",",","},{",",","},{",",","}}}`, `,`, []int{1, 3, 2}, [][]byte{ 54 {','}, {','}, {','}, {','}, {','}, {','}, 55 }}, 56 {`{"\"}"}`, `,`, []int{1}, [][]byte{{'"', '}'}}}, 57 {`{"\"","\""}`, `,`, []int{2}, [][]byte{{'"'}, {'"'}}}, 58 {`{{"\"","\""}}`, `,`, []int{1, 2}, [][]byte{{'"'}, {'"'}}}, 59 {`{{"\""},{"\""}}`, `,`, []int{2, 1}, [][]byte{{'"'}, {'"'}}}, 60 {`{{{"\"","\""},{"\"","\""},{"\"","\""}}}`, `,`, []int{1, 3, 2}, [][]byte{ 61 {'"'}, {'"'}, {'"'}, {'"'}, {'"'}, {'"'}, 62 }}, 63 {`{axyzb}`, `xyz`, []int{2}, [][]byte{{'a'}, {'b'}}}, 64 } { 65 dims, elems, err := parseArray([]byte(tt.input), []byte(tt.delim)) 66 67 if err != nil { 68 t.Fatalf("Expected no error for %q, got %q", tt.input, err) 69 } 70 if !reflect.DeepEqual(dims, tt.dims) { 71 t.Errorf("Expected %v dimensions for %q, got %v", tt.dims, tt.input, dims) 72 } 73 if !reflect.DeepEqual(elems, tt.elems) { 74 t.Errorf("Expected %v elements for %q, got %v", tt.elems, tt.input, elems) 75 } 76 } 77 } 78 79 func TestParseArrayError(t *testing.T) { 80 for _, tt := range []struct { 81 input, err string 82 }{ 83 {``, "expected '{' at offset 0"}, 84 {`x`, "expected '{' at offset 0"}, 85 {`}`, "expected '{' at offset 0"}, 86 {`{`, "expected '}' at offset 1"}, 87 {`{{}`, "expected '}' at offset 3"}, 88 {`{}}`, "unexpected '}' at offset 2"}, 89 {`{,}`, "unexpected ',' at offset 1"}, 90 {`{,x}`, "unexpected ',' at offset 1"}, 91 {`{x,}`, "unexpected '}' at offset 3"}, 92 {`{x,{`, "unexpected '{' at offset 3"}, 93 {`{x},`, "unexpected ',' at offset 3"}, 94 {`{x}}`, "unexpected '}' at offset 3"}, 95 {`{{x}`, "expected '}' at offset 4"}, 96 {`{""x}`, "unexpected 'x' at offset 3"}, 97 {`{{a},{b,c}}`, "multidimensional arrays must have elements with matching dimensions"}, 98 } { 99 _, _, err := parseArray([]byte(tt.input), []byte{','}) 100 101 if err == nil { 102 t.Fatalf("Expected error for %q, got none", tt.input) 103 } 104 if !strings.Contains(err.Error(), tt.err) { 105 t.Errorf("Expected error to contain %q for %q, got %q", tt.err, tt.input, err) 106 } 107 } 108 } 109 110 func TestArrayScanner(t *testing.T) { 111 var s sql.Scanner 112 113 s = Array(&[]bool{}) 114 if _, ok := s.(*BoolArray); !ok { 115 t.Errorf("Expected *BoolArray, got %T", s) 116 } 117 118 s = Array(&[]float64{}) 119 if _, ok := s.(*Float64Array); !ok { 120 t.Errorf("Expected *Float64Array, got %T", s) 121 } 122 123 s = Array(&[]int64{}) 124 if _, ok := s.(*Int64Array); !ok { 125 t.Errorf("Expected *Int64Array, got %T", s) 126 } 127 128 s = Array(&[]string{}) 129 if _, ok := s.(*StringArray); !ok { 130 t.Errorf("Expected *StringArray, got %T", s) 131 } 132 133 for _, tt := range []interface{}{ 134 &[]sql.Scanner{}, 135 &[][]bool{}, 136 &[][]float64{}, 137 &[][]int64{}, 138 &[][]string{}, 139 } { 140 s = Array(tt) 141 if _, ok := s.(GenericArray); !ok { 142 t.Errorf("Expected GenericArray for %T, got %T", tt, s) 143 } 144 } 145 } 146 147 func TestArrayValuer(t *testing.T) { 148 var v driver.Valuer 149 150 v = Array([]bool{}) 151 if _, ok := v.(*BoolArray); !ok { 152 t.Errorf("Expected *BoolArray, got %T", v) 153 } 154 155 v = Array([]float64{}) 156 if _, ok := v.(*Float64Array); !ok { 157 t.Errorf("Expected *Float64Array, got %T", v) 158 } 159 160 v = Array([]int64{}) 161 if _, ok := v.(*Int64Array); !ok { 162 t.Errorf("Expected *Int64Array, got %T", v) 163 } 164 165 v = Array([]string{}) 166 if _, ok := v.(*StringArray); !ok { 167 t.Errorf("Expected *StringArray, got %T", v) 168 } 169 170 for _, tt := range []interface{}{ 171 nil, 172 []driver.Value{}, 173 [][]bool{}, 174 [][]float64{}, 175 [][]int64{}, 176 [][]string{}, 177 } { 178 v = Array(tt) 179 if _, ok := v.(GenericArray); !ok { 180 t.Errorf("Expected GenericArray for %T, got %T", tt, v) 181 } 182 } 183 } 184 185 func TestBoolArrayScanUnsupported(t *testing.T) { 186 var arr BoolArray 187 err := arr.Scan(1) 188 189 if err == nil { 190 t.Fatal("Expected error when scanning from int") 191 } 192 if !strings.Contains(err.Error(), "int to BoolArray") { 193 t.Errorf("Expected type to be mentioned when scanning, got %q", err) 194 } 195 } 196 197 func TestBoolArrayScanEmpty(t *testing.T) { 198 var arr BoolArray 199 err := arr.Scan(`{}`) 200 201 if err != nil { 202 t.Fatalf("Expected no error, got %v", err) 203 } 204 if arr == nil || len(arr) != 0 { 205 t.Errorf("Expected empty, got %#v", arr) 206 } 207 } 208 209 func TestBoolArrayScanNil(t *testing.T) { 210 arr := BoolArray{true, true, true} 211 err := arr.Scan(nil) 212 213 if err != nil { 214 t.Fatalf("Expected no error, got %v", err) 215 } 216 if arr != nil { 217 t.Errorf("Expected nil, got %+v", arr) 218 } 219 } 220 221 var BoolArrayStringTests = []struct { 222 str string 223 arr BoolArray 224 }{ 225 {`{}`, BoolArray{}}, 226 {`{t}`, BoolArray{true}}, 227 {`{f,t}`, BoolArray{false, true}}, 228 {`{F,T}`, BoolArray{false, true}}, 229 {`{false,true}`, BoolArray{false, true}}, 230 {`{FALSE,TRUE}`, BoolArray{false, true}}, 231 } 232 233 func TestBoolArrayScanBytes(t *testing.T) { 234 for _, tt := range BoolArrayStringTests { 235 bytes := []byte(tt.str) 236 arr := BoolArray{true, true, true} 237 err := arr.Scan(bytes) 238 239 if err != nil { 240 t.Fatalf("Expected no error for %q, got %v", bytes, err) 241 } 242 if !reflect.DeepEqual(arr, tt.arr) { 243 t.Errorf("Expected %+v for %q, got %+v", tt.arr, bytes, arr) 244 } 245 } 246 } 247 248 func BenchmarkBoolArrayScanBytes(b *testing.B) { 249 var a BoolArray 250 var x interface{} = []byte(`{t,f,t,f,t,f,t,f,t,f}`) 251 252 for i := 0; i < b.N; i++ { 253 a = BoolArray{} 254 a.Scan(x) 255 } 256 } 257 258 func TestBoolArrayScanString(t *testing.T) { 259 for _, tt := range BoolArrayStringTests { 260 arr := BoolArray{true, true, true} 261 err := arr.Scan(tt.str) 262 263 if err != nil { 264 t.Fatalf("Expected no error for %q, got %v", tt.str, err) 265 } 266 if !reflect.DeepEqual(arr, tt.arr) { 267 t.Errorf("Expected %+v for %q, got %+v", tt.arr, tt.str, arr) 268 } 269 } 270 } 271 272 func TestBoolArrayScanError(t *testing.T) { 273 for _, tt := range []struct { 274 input, err string 275 }{ 276 {``, "unable to parse array"}, 277 {`{`, "unable to parse array"}, 278 {`{{t},{f}}`, "cannot convert ARRAY[2][1] to BoolArray"}, 279 {`{NULL}`, `could not parse boolean array index 0: invalid boolean ""`}, 280 {`{a}`, `could not parse boolean array index 0: invalid boolean "a"`}, 281 {`{t,b}`, `could not parse boolean array index 1: invalid boolean "b"`}, 282 {`{t,f,cd}`, `could not parse boolean array index 2: invalid boolean "cd"`}, 283 } { 284 arr := BoolArray{true, true, true} 285 err := arr.Scan(tt.input) 286 287 if err == nil { 288 t.Fatalf("Expected error for %q, got none", tt.input) 289 } 290 if !strings.Contains(err.Error(), tt.err) { 291 t.Errorf("Expected error to contain %q for %q, got %q", tt.err, tt.input, err) 292 } 293 if !reflect.DeepEqual(arr, BoolArray{true, true, true}) { 294 t.Errorf("Expected destination not to change for %q, got %+v", tt.input, arr) 295 } 296 } 297 } 298 299 func TestBoolArrayValue(t *testing.T) { 300 result, err := BoolArray(nil).Value() 301 302 if err != nil { 303 t.Fatalf("Expected no error for nil, got %v", err) 304 } 305 if result != nil { 306 t.Errorf("Expected nil, got %q", result) 307 } 308 309 result, err = BoolArray([]bool{}).Value() 310 311 if err != nil { 312 t.Fatalf("Expected no error for empty, got %v", err) 313 } 314 if expected := `{}`; !reflect.DeepEqual(result, expected) { 315 t.Errorf("Expected empty, got %q", result) 316 } 317 318 result, err = BoolArray([]bool{false, true, false}).Value() 319 320 if err != nil { 321 t.Fatalf("Expected no error, got %v", err) 322 } 323 if expected := `{f,t,f}`; !reflect.DeepEqual(result, expected) { 324 t.Errorf("Expected %q, got %q", expected, result) 325 } 326 } 327 328 func BenchmarkBoolArrayValue(b *testing.B) { 329 rand.Seed(1) 330 x := make([]bool, 10) 331 for i := 0; i < len(x); i++ { 332 x[i] = rand.Intn(2) == 0 333 } 334 a := BoolArray(x) 335 336 for i := 0; i < b.N; i++ { 337 a.Value() 338 } 339 } 340 341 func TestBytesArrayScanUnsupported(t *testing.T) { 342 var arr BytesArray 343 err := arr.Scan(1) 344 345 if err == nil { 346 t.Fatal("Expected error when scanning from int") 347 } 348 if !strings.Contains(err.Error(), "int to BytesArray") { 349 t.Errorf("Expected type to be mentioned when scanning, got %q", err) 350 } 351 } 352 353 func TestBytesArrayScanEmpty(t *testing.T) { 354 var arr BytesArray 355 err := arr.Scan(`{}`) 356 357 if err != nil { 358 t.Fatalf("Expected no error, got %v", err) 359 } 360 if arr == nil || len(arr) != 0 { 361 t.Errorf("Expected empty, got %#v", arr) 362 } 363 } 364 365 func TestBytesArrayScanNil(t *testing.T) { 366 arr := BytesArray{{2}, {6}, {0, 0}} 367 err := arr.Scan(nil) 368 369 if err != nil { 370 t.Fatalf("Expected no error, got %v", err) 371 } 372 if arr != nil { 373 t.Errorf("Expected nil, got %+v", arr) 374 } 375 } 376 377 var BytesArrayStringTests = []struct { 378 str string 379 arr BytesArray 380 }{ 381 {`{}`, BytesArray{}}, 382 {`{NULL}`, BytesArray{nil}}, 383 {`{"\\xfeff"}`, BytesArray{{'\xFE', '\xFF'}}}, 384 {`{"\\xdead","\\xbeef"}`, BytesArray{{'\xDE', '\xAD'}, {'\xBE', '\xEF'}}}, 385 } 386 387 func TestBytesArrayScanBytes(t *testing.T) { 388 for _, tt := range BytesArrayStringTests { 389 bytes := []byte(tt.str) 390 arr := BytesArray{{2}, {6}, {0, 0}} 391 err := arr.Scan(bytes) 392 393 if err != nil { 394 t.Fatalf("Expected no error for %q, got %v", bytes, err) 395 } 396 if !reflect.DeepEqual(arr, tt.arr) { 397 t.Errorf("Expected %+v for %q, got %+v", tt.arr, bytes, arr) 398 } 399 } 400 } 401 402 func BenchmarkBytesArrayScanBytes(b *testing.B) { 403 var a BytesArray 404 var x interface{} = []byte(`{"\\xfe","\\xff","\\xdead","\\xbeef","\\xfe","\\xff","\\xdead","\\xbeef","\\xfe","\\xff"}`) 405 406 for i := 0; i < b.N; i++ { 407 a = BytesArray{} 408 a.Scan(x) 409 } 410 } 411 412 func TestBytesArrayScanString(t *testing.T) { 413 for _, tt := range BytesArrayStringTests { 414 arr := BytesArray{{2}, {6}, {0, 0}} 415 err := arr.Scan(tt.str) 416 417 if err != nil { 418 t.Fatalf("Expected no error for %q, got %v", tt.str, err) 419 } 420 if !reflect.DeepEqual(arr, tt.arr) { 421 t.Errorf("Expected %+v for %q, got %+v", tt.arr, tt.str, arr) 422 } 423 } 424 } 425 426 func TestBytesArrayScanError(t *testing.T) { 427 for _, tt := range []struct { 428 input, err string 429 }{ 430 {``, "unable to parse array"}, 431 {`{`, "unable to parse array"}, 432 {`{{"\\xfeff"},{"\\xbeef"}}`, "cannot convert ARRAY[2][1] to BytesArray"}, 433 {`{"\\abc"}`, "could not parse bytea array index 0: could not parse bytea value"}, 434 } { 435 arr := BytesArray{{2}, {6}, {0, 0}} 436 err := arr.Scan(tt.input) 437 438 if err == nil { 439 t.Fatalf("Expected error for %q, got none", tt.input) 440 } 441 if !strings.Contains(err.Error(), tt.err) { 442 t.Errorf("Expected error to contain %q for %q, got %q", tt.err, tt.input, err) 443 } 444 if !reflect.DeepEqual(arr, BytesArray{{2}, {6}, {0, 0}}) { 445 t.Errorf("Expected destination not to change for %q, got %+v", tt.input, arr) 446 } 447 } 448 } 449 450 func TestBytesArrayValue(t *testing.T) { 451 result, err := BytesArray(nil).Value() 452 453 if err != nil { 454 t.Fatalf("Expected no error for nil, got %v", err) 455 } 456 if result != nil { 457 t.Errorf("Expected nil, got %q", result) 458 } 459 460 result, err = BytesArray([][]byte{}).Value() 461 462 if err != nil { 463 t.Fatalf("Expected no error for empty, got %v", err) 464 } 465 if expected := `{}`; !reflect.DeepEqual(result, expected) { 466 t.Errorf("Expected empty, got %q", result) 467 } 468 469 result, err = BytesArray([][]byte{{'\xDE', '\xAD', '\xBE', '\xEF'}, {'\xFE', '\xFF'}, {}}).Value() 470 471 if err != nil { 472 t.Fatalf("Expected no error, got %v", err) 473 } 474 if expected := `{"\\xdeadbeef","\\xfeff","\\x"}`; !reflect.DeepEqual(result, expected) { 475 t.Errorf("Expected %q, got %q", expected, result) 476 } 477 } 478 479 func BenchmarkBytesArrayValue(b *testing.B) { 480 rand.Seed(1) 481 x := make([][]byte, 10) 482 for i := 0; i < len(x); i++ { 483 x[i] = make([]byte, len(x)) 484 for j := 0; j < len(x); j++ { 485 x[i][j] = byte(rand.Int()) 486 } 487 } 488 a := BytesArray(x) 489 490 for i := 0; i < b.N; i++ { 491 a.Value() 492 } 493 } 494 495 func TestFloat64ArrayScanUnsupported(t *testing.T) { 496 var arr Float64Array 497 err := arr.Scan(true) 498 499 if err == nil { 500 t.Fatal("Expected error when scanning from bool") 501 } 502 if !strings.Contains(err.Error(), "bool to Float64Array") { 503 t.Errorf("Expected type to be mentioned when scanning, got %q", err) 504 } 505 } 506 507 func TestFloat64ArrayScanEmpty(t *testing.T) { 508 var arr Float64Array 509 err := arr.Scan(`{}`) 510 511 if err != nil { 512 t.Fatalf("Expected no error, got %v", err) 513 } 514 if arr == nil || len(arr) != 0 { 515 t.Errorf("Expected empty, got %#v", arr) 516 } 517 } 518 519 func TestFloat64ArrayScanNil(t *testing.T) { 520 arr := Float64Array{5, 5, 5} 521 err := arr.Scan(nil) 522 523 if err != nil { 524 t.Fatalf("Expected no error, got %v", err) 525 } 526 if arr != nil { 527 t.Errorf("Expected nil, got %+v", arr) 528 } 529 } 530 531 var Float64ArrayStringTests = []struct { 532 str string 533 arr Float64Array 534 }{ 535 {`{}`, Float64Array{}}, 536 {`{1.2}`, Float64Array{1.2}}, 537 {`{3.456,7.89}`, Float64Array{3.456, 7.89}}, 538 {`{3,1,2}`, Float64Array{3, 1, 2}}, 539 } 540 541 func TestFloat64ArrayScanBytes(t *testing.T) { 542 for _, tt := range Float64ArrayStringTests { 543 bytes := []byte(tt.str) 544 arr := Float64Array{5, 5, 5} 545 err := arr.Scan(bytes) 546 547 if err != nil { 548 t.Fatalf("Expected no error for %q, got %v", bytes, err) 549 } 550 if !reflect.DeepEqual(arr, tt.arr) { 551 t.Errorf("Expected %+v for %q, got %+v", tt.arr, bytes, arr) 552 } 553 } 554 } 555 556 func BenchmarkFloat64ArrayScanBytes(b *testing.B) { 557 var a Float64Array 558 var x interface{} = []byte(`{1.2,3.4,5.6,7.8,9.01,2.34,5.67,8.90,1.234,5.678}`) 559 560 for i := 0; i < b.N; i++ { 561 a = Float64Array{} 562 a.Scan(x) 563 } 564 } 565 566 func TestFloat64ArrayScanString(t *testing.T) { 567 for _, tt := range Float64ArrayStringTests { 568 arr := Float64Array{5, 5, 5} 569 err := arr.Scan(tt.str) 570 571 if err != nil { 572 t.Fatalf("Expected no error for %q, got %v", tt.str, err) 573 } 574 if !reflect.DeepEqual(arr, tt.arr) { 575 t.Errorf("Expected %+v for %q, got %+v", tt.arr, tt.str, arr) 576 } 577 } 578 } 579 580 func TestFloat64ArrayScanError(t *testing.T) { 581 for _, tt := range []struct { 582 input, err string 583 }{ 584 {``, "unable to parse array"}, 585 {`{`, "unable to parse array"}, 586 {`{{5.6},{7.8}}`, "cannot convert ARRAY[2][1] to Float64Array"}, 587 {`{NULL}`, "parsing array element index 0:"}, 588 {`{a}`, "parsing array element index 0:"}, 589 {`{5.6,a}`, "parsing array element index 1:"}, 590 {`{5.6,7.8,a}`, "parsing array element index 2:"}, 591 } { 592 arr := Float64Array{5, 5, 5} 593 err := arr.Scan(tt.input) 594 595 if err == nil { 596 t.Fatalf("Expected error for %q, got none", tt.input) 597 } 598 if !strings.Contains(err.Error(), tt.err) { 599 t.Errorf("Expected error to contain %q for %q, got %q", tt.err, tt.input, err) 600 } 601 if !reflect.DeepEqual(arr, Float64Array{5, 5, 5}) { 602 t.Errorf("Expected destination not to change for %q, got %+v", tt.input, arr) 603 } 604 } 605 } 606 607 func TestFloat64ArrayValue(t *testing.T) { 608 result, err := Float64Array(nil).Value() 609 610 if err != nil { 611 t.Fatalf("Expected no error for nil, got %v", err) 612 } 613 if result != nil { 614 t.Errorf("Expected nil, got %q", result) 615 } 616 617 result, err = Float64Array([]float64{}).Value() 618 619 if err != nil { 620 t.Fatalf("Expected no error for empty, got %v", err) 621 } 622 if expected := `{}`; !reflect.DeepEqual(result, expected) { 623 t.Errorf("Expected empty, got %q", result) 624 } 625 626 result, err = Float64Array([]float64{1.2, 3.4, 5.6}).Value() 627 628 if err != nil { 629 t.Fatalf("Expected no error, got %v", err) 630 } 631 if expected := `{1.2,3.4,5.6}`; !reflect.DeepEqual(result, expected) { 632 t.Errorf("Expected %q, got %q", expected, result) 633 } 634 } 635 636 func BenchmarkFloat64ArrayValue(b *testing.B) { 637 rand.Seed(1) 638 x := make([]float64, 10) 639 for i := 0; i < len(x); i++ { 640 x[i] = rand.NormFloat64() 641 } 642 a := Float64Array(x) 643 644 for i := 0; i < b.N; i++ { 645 a.Value() 646 } 647 } 648 649 func TestInt64ArrayScanUnsupported(t *testing.T) { 650 var arr Int64Array 651 err := arr.Scan(true) 652 653 if err == nil { 654 t.Fatal("Expected error when scanning from bool") 655 } 656 if !strings.Contains(err.Error(), "bool to Int64Array") { 657 t.Errorf("Expected type to be mentioned when scanning, got %q", err) 658 } 659 } 660 661 func TestInt64ArrayScanEmpty(t *testing.T) { 662 var arr Int64Array 663 err := arr.Scan(`{}`) 664 665 if err != nil { 666 t.Fatalf("Expected no error, got %v", err) 667 } 668 if arr == nil || len(arr) != 0 { 669 t.Errorf("Expected empty, got %#v", arr) 670 } 671 } 672 673 func TestInt64ArrayScanNil(t *testing.T) { 674 arr := Int64Array{5, 5, 5} 675 err := arr.Scan(nil) 676 677 if err != nil { 678 t.Fatalf("Expected no error, got %v", err) 679 } 680 if arr != nil { 681 t.Errorf("Expected nil, got %+v", arr) 682 } 683 } 684 685 var Int64ArrayStringTests = []struct { 686 str string 687 arr Int64Array 688 }{ 689 {`{}`, Int64Array{}}, 690 {`{12}`, Int64Array{12}}, 691 {`{345,678}`, Int64Array{345, 678}}, 692 } 693 694 func TestInt64ArrayScanBytes(t *testing.T) { 695 for _, tt := range Int64ArrayStringTests { 696 bytes := []byte(tt.str) 697 arr := Int64Array{5, 5, 5} 698 err := arr.Scan(bytes) 699 700 if err != nil { 701 t.Fatalf("Expected no error for %q, got %v", bytes, err) 702 } 703 if !reflect.DeepEqual(arr, tt.arr) { 704 t.Errorf("Expected %+v for %q, got %+v", tt.arr, bytes, arr) 705 } 706 } 707 } 708 709 func BenchmarkInt64ArrayScanBytes(b *testing.B) { 710 var a Int64Array 711 var x interface{} = []byte(`{1,2,3,4,5,6,7,8,9,0}`) 712 713 for i := 0; i < b.N; i++ { 714 a = Int64Array{} 715 a.Scan(x) 716 } 717 } 718 719 func TestInt64ArrayScanString(t *testing.T) { 720 for _, tt := range Int64ArrayStringTests { 721 arr := Int64Array{5, 5, 5} 722 err := arr.Scan(tt.str) 723 724 if err != nil { 725 t.Fatalf("Expected no error for %q, got %v", tt.str, err) 726 } 727 if !reflect.DeepEqual(arr, tt.arr) { 728 t.Errorf("Expected %+v for %q, got %+v", tt.arr, tt.str, arr) 729 } 730 } 731 } 732 733 func TestInt64ArrayScanError(t *testing.T) { 734 for _, tt := range []struct { 735 input, err string 736 }{ 737 {``, "unable to parse array"}, 738 {`{`, "unable to parse array"}, 739 {`{{5},{6}}`, "cannot convert ARRAY[2][1] to Int64Array"}, 740 {`{NULL}`, "parsing array element index 0:"}, 741 {`{a}`, "parsing array element index 0:"}, 742 {`{5,a}`, "parsing array element index 1:"}, 743 {`{5,6,a}`, "parsing array element index 2:"}, 744 } { 745 arr := Int64Array{5, 5, 5} 746 err := arr.Scan(tt.input) 747 748 if err == nil { 749 t.Fatalf("Expected error for %q, got none", tt.input) 750 } 751 if !strings.Contains(err.Error(), tt.err) { 752 t.Errorf("Expected error to contain %q for %q, got %q", tt.err, tt.input, err) 753 } 754 if !reflect.DeepEqual(arr, Int64Array{5, 5, 5}) { 755 t.Errorf("Expected destination not to change for %q, got %+v", tt.input, arr) 756 } 757 } 758 } 759 760 func TestInt64ArrayValue(t *testing.T) { 761 result, err := Int64Array(nil).Value() 762 763 if err != nil { 764 t.Fatalf("Expected no error for nil, got %v", err) 765 } 766 if result != nil { 767 t.Errorf("Expected nil, got %q", result) 768 } 769 770 result, err = Int64Array([]int64{}).Value() 771 772 if err != nil { 773 t.Fatalf("Expected no error for empty, got %v", err) 774 } 775 if expected := `{}`; !reflect.DeepEqual(result, expected) { 776 t.Errorf("Expected empty, got %q", result) 777 } 778 779 result, err = Int64Array([]int64{1, 2, 3}).Value() 780 781 if err != nil { 782 t.Fatalf("Expected no error, got %v", err) 783 } 784 if expected := `{1,2,3}`; !reflect.DeepEqual(result, expected) { 785 t.Errorf("Expected %q, got %q", expected, result) 786 } 787 } 788 789 func BenchmarkInt64ArrayValue(b *testing.B) { 790 rand.Seed(1) 791 x := make([]int64, 10) 792 for i := 0; i < len(x); i++ { 793 x[i] = rand.Int63() 794 } 795 a := Int64Array(x) 796 797 for i := 0; i < b.N; i++ { 798 a.Value() 799 } 800 } 801 802 func TestStringArrayScanUnsupported(t *testing.T) { 803 var arr StringArray 804 err := arr.Scan(true) 805 806 if err == nil { 807 t.Fatal("Expected error when scanning from bool") 808 } 809 if !strings.Contains(err.Error(), "bool to StringArray") { 810 t.Errorf("Expected type to be mentioned when scanning, got %q", err) 811 } 812 } 813 814 func TestStringArrayScanEmpty(t *testing.T) { 815 var arr StringArray 816 err := arr.Scan(`{}`) 817 818 if err != nil { 819 t.Fatalf("Expected no error, got %v", err) 820 } 821 if arr == nil || len(arr) != 0 { 822 t.Errorf("Expected empty, got %#v", arr) 823 } 824 } 825 826 func TestStringArrayScanNil(t *testing.T) { 827 arr := StringArray{"x", "x", "x"} 828 err := arr.Scan(nil) 829 830 if err != nil { 831 t.Fatalf("Expected no error, got %v", err) 832 } 833 if arr != nil { 834 t.Errorf("Expected nil, got %+v", arr) 835 } 836 } 837 838 var StringArrayStringTests = []struct { 839 str string 840 arr StringArray 841 }{ 842 {`{}`, StringArray{}}, 843 {`{t}`, StringArray{"t"}}, 844 {`{f,1}`, StringArray{"f", "1"}}, 845 {`{"a\\b","c d",","}`, StringArray{"a\\b", "c d", ","}}, 846 } 847 848 func TestStringArrayScanBytes(t *testing.T) { 849 for _, tt := range StringArrayStringTests { 850 bytes := []byte(tt.str) 851 arr := StringArray{"x", "x", "x"} 852 err := arr.Scan(bytes) 853 854 if err != nil { 855 t.Fatalf("Expected no error for %q, got %v", bytes, err) 856 } 857 if !reflect.DeepEqual(arr, tt.arr) { 858 t.Errorf("Expected %+v for %q, got %+v", tt.arr, bytes, arr) 859 } 860 } 861 } 862 863 func BenchmarkStringArrayScanBytes(b *testing.B) { 864 var a StringArray 865 var x interface{} = []byte(`{a,b,c,d,e,f,g,h,i,j}`) 866 var y interface{} = []byte(`{"\a","\b","\c","\d","\e","\f","\g","\h","\i","\j"}`) 867 868 for i := 0; i < b.N; i++ { 869 a = StringArray{} 870 a.Scan(x) 871 a = StringArray{} 872 a.Scan(y) 873 } 874 } 875 876 func TestStringArrayScanString(t *testing.T) { 877 for _, tt := range StringArrayStringTests { 878 arr := StringArray{"x", "x", "x"} 879 err := arr.Scan(tt.str) 880 881 if err != nil { 882 t.Fatalf("Expected no error for %q, got %v", tt.str, err) 883 } 884 if !reflect.DeepEqual(arr, tt.arr) { 885 t.Errorf("Expected %+v for %q, got %+v", tt.arr, tt.str, arr) 886 } 887 } 888 } 889 890 func TestStringArrayScanError(t *testing.T) { 891 for _, tt := range []struct { 892 input, err string 893 }{ 894 {``, "unable to parse array"}, 895 {`{`, "unable to parse array"}, 896 {`{{a},{b}}`, "cannot convert ARRAY[2][1] to StringArray"}, 897 {`{NULL}`, "parsing array element index 0: cannot convert nil to string"}, 898 {`{a,NULL}`, "parsing array element index 1: cannot convert nil to string"}, 899 {`{a,b,NULL}`, "parsing array element index 2: cannot convert nil to string"}, 900 } { 901 arr := StringArray{"x", "x", "x"} 902 err := arr.Scan(tt.input) 903 904 if err == nil { 905 t.Fatalf("Expected error for %q, got none", tt.input) 906 } 907 if !strings.Contains(err.Error(), tt.err) { 908 t.Errorf("Expected error to contain %q for %q, got %q", tt.err, tt.input, err) 909 } 910 if !reflect.DeepEqual(arr, StringArray{"x", "x", "x"}) { 911 t.Errorf("Expected destination not to change for %q, got %+v", tt.input, arr) 912 } 913 } 914 } 915 916 func TestStringArrayValue(t *testing.T) { 917 result, err := StringArray(nil).Value() 918 919 if err != nil { 920 t.Fatalf("Expected no error for nil, got %v", err) 921 } 922 if result != nil { 923 t.Errorf("Expected nil, got %q", result) 924 } 925 926 result, err = StringArray([]string{}).Value() 927 928 if err != nil { 929 t.Fatalf("Expected no error for empty, got %v", err) 930 } 931 if expected := `{}`; !reflect.DeepEqual(result, expected) { 932 t.Errorf("Expected empty, got %q", result) 933 } 934 935 result, err = StringArray([]string{`a`, `\b`, `c"`, `d,e`}).Value() 936 937 if err != nil { 938 t.Fatalf("Expected no error, got %v", err) 939 } 940 if expected := `{"a","\\b","c\"","d,e"}`; !reflect.DeepEqual(result, expected) { 941 t.Errorf("Expected %q, got %q", expected, result) 942 } 943 } 944 945 func BenchmarkStringArrayValue(b *testing.B) { 946 x := make([]string, 10) 947 for i := 0; i < len(x); i++ { 948 x[i] = strings.Repeat(`abc"def\ghi`, 5) 949 } 950 a := StringArray(x) 951 952 for i := 0; i < b.N; i++ { 953 a.Value() 954 } 955 } 956 957 func TestGenericArrayScanUnsupported(t *testing.T) { 958 var s string 959 var ss []string 960 var nsa [1]sql.NullString 961 962 for _, tt := range []struct { 963 src, dest interface{} 964 err string 965 }{ 966 {nil, nil, "destination <nil> is not a pointer to array or slice"}, 967 {nil, true, "destination bool is not a pointer to array or slice"}, 968 {nil, &s, "destination *string is not a pointer to array or slice"}, 969 {nil, ss, "destination []string is not a pointer to array or slice"}, 970 {nil, &nsa, "<nil> to [1]sql.NullString"}, 971 {true, &ss, "bool to []string"}, 972 {`{{x}}`, &ss, "multidimensional ARRAY[1][1] is not implemented"}, 973 {`{{x},{x}}`, &ss, "multidimensional ARRAY[2][1] is not implemented"}, 974 {`{x}`, &ss, "scanning to string is not implemented"}, 975 } { 976 err := GenericArray{tt.dest}.Scan(tt.src) 977 978 if err == nil { 979 t.Fatalf("Expected error for [%#v %#v]", tt.src, tt.dest) 980 } 981 if !strings.Contains(err.Error(), tt.err) { 982 t.Errorf("Expected error to contain %q for [%#v %#v], got %q", tt.err, tt.src, tt.dest, err) 983 } 984 } 985 } 986 987 func TestGenericArrayScanScannerArrayBytes(t *testing.T) { 988 src, expected, nsa := []byte(`{NULL,abc,"\""}`), 989 [3]sql.NullString{{}, {String: `abc`, Valid: true}, {String: `"`, Valid: true}}, 990 [3]sql.NullString{{String: ``, Valid: true}, {}, {}} 991 992 if err := (GenericArray{&nsa}).Scan(src); err != nil { 993 t.Fatalf("Expected no error, got %v", err) 994 } 995 if !reflect.DeepEqual(nsa, expected) { 996 t.Errorf("Expected %v, got %v", expected, nsa) 997 } 998 } 999 1000 func TestGenericArrayScanScannerArrayString(t *testing.T) { 1001 src, expected, nsa := `{NULL,"\"",xyz}`, 1002 [3]sql.NullString{{}, {String: `"`, Valid: true}, {String: `xyz`, Valid: true}}, 1003 [3]sql.NullString{{String: ``, Valid: true}, {}, {}} 1004 1005 if err := (GenericArray{&nsa}).Scan(src); err != nil { 1006 t.Fatalf("Expected no error, got %v", err) 1007 } 1008 if !reflect.DeepEqual(nsa, expected) { 1009 t.Errorf("Expected %v, got %v", expected, nsa) 1010 } 1011 } 1012 1013 func TestGenericArrayScanScannerSliceEmpty(t *testing.T) { 1014 var nss []sql.NullString 1015 1016 if err := (GenericArray{&nss}).Scan(`{}`); err != nil { 1017 t.Fatalf("Expected no error, got %v", err) 1018 } 1019 if nss == nil || len(nss) != 0 { 1020 t.Errorf("Expected empty, got %#v", nss) 1021 } 1022 } 1023 1024 func TestGenericArrayScanScannerSliceNil(t *testing.T) { 1025 nss := []sql.NullString{{String: ``, Valid: true}, {}} 1026 1027 if err := (GenericArray{&nss}).Scan(nil); err != nil { 1028 t.Fatalf("Expected no error, got %v", err) 1029 } 1030 if nss != nil { 1031 t.Errorf("Expected nil, got %+v", nss) 1032 } 1033 } 1034 1035 func TestGenericArrayScanScannerSliceBytes(t *testing.T) { 1036 src, expected, nss := []byte(`{NULL,abc,"\""}`), 1037 []sql.NullString{{}, {String: `abc`, Valid: true}, {String: `"`, Valid: true}}, 1038 []sql.NullString{{String: ``, Valid: true}, {}, {}, {}, {}} 1039 1040 if err := (GenericArray{&nss}).Scan(src); err != nil { 1041 t.Fatalf("Expected no error, got %v", err) 1042 } 1043 if !reflect.DeepEqual(nss, expected) { 1044 t.Errorf("Expected %v, got %v", expected, nss) 1045 } 1046 } 1047 1048 func BenchmarkGenericArrayScanScannerSliceBytes(b *testing.B) { 1049 var a GenericArray 1050 var x interface{} = []byte(`{a,b,c,d,e,f,g,h,i,j}`) 1051 var y interface{} = []byte(`{"\a","\b","\c","\d","\e","\f","\g","\h","\i","\j"}`) 1052 1053 for i := 0; i < b.N; i++ { 1054 a = GenericArray{new([]sql.NullString)} 1055 a.Scan(x) 1056 a = GenericArray{new([]sql.NullString)} 1057 a.Scan(y) 1058 } 1059 } 1060 1061 func TestGenericArrayScanScannerSliceString(t *testing.T) { 1062 src, expected, nss := `{NULL,"\"",xyz}`, 1063 []sql.NullString{{}, {String: `"`, Valid: true}, {String: `xyz`, Valid: true}}, 1064 []sql.NullString{{String: ``, Valid: true}, {}, {}} 1065 1066 if err := (GenericArray{&nss}).Scan(src); err != nil { 1067 t.Fatalf("Expected no error, got %v", err) 1068 } 1069 if !reflect.DeepEqual(nss, expected) { 1070 t.Errorf("Expected %v, got %v", expected, nss) 1071 } 1072 } 1073 1074 type TildeNullInt64 struct{ sql.NullInt64 } 1075 1076 func (TildeNullInt64) ArrayDelimiter() string { return "~" } 1077 1078 func TestGenericArrayScanDelimiter(t *testing.T) { 1079 src, expected, tnis := `{12~NULL~76}`, 1080 []TildeNullInt64{{sql.NullInt64{Int64: 12, Valid: true}}, {}, {sql.NullInt64{Int64: 76, Valid: true}}}, 1081 []TildeNullInt64{{sql.NullInt64{Int64: 0, Valid: true}}, {}} 1082 1083 if err := (GenericArray{&tnis}).Scan(src); err != nil { 1084 t.Fatalf("Expected no error for %#v, got %v", src, err) 1085 } 1086 if !reflect.DeepEqual(tnis, expected) { 1087 t.Errorf("Expected %v for %#v, got %v", expected, src, tnis) 1088 } 1089 } 1090 1091 func TestGenericArrayScanErrors(t *testing.T) { 1092 var sa [1]string 1093 var nis []sql.NullInt64 1094 var pss *[]string 1095 1096 for _, tt := range []struct { 1097 src, dest interface{} 1098 err string 1099 }{ 1100 {nil, pss, "destination *[]string is nil"}, 1101 {`{`, &sa, "unable to parse"}, 1102 {`{}`, &sa, "cannot convert ARRAY[0] to [1]string"}, 1103 {`{x,x}`, &sa, "cannot convert ARRAY[2] to [1]string"}, 1104 {`{x}`, &nis, `parsing array element index 0: converting`}, 1105 } { 1106 err := GenericArray{tt.dest}.Scan(tt.src) 1107 1108 if err == nil { 1109 t.Fatalf("Expected error for [%#v %#v]", tt.src, tt.dest) 1110 } 1111 if !strings.Contains(err.Error(), tt.err) { 1112 t.Errorf("Expected error to contain %q for [%#v %#v], got %q", tt.err, tt.src, tt.dest, err) 1113 } 1114 } 1115 } 1116 1117 func TestGenericArrayValueUnsupported(t *testing.T) { 1118 _, err := GenericArray{true}.Value() 1119 1120 if err == nil { 1121 t.Fatal("Expected error for bool") 1122 } 1123 if !strings.Contains(err.Error(), "bool to array") { 1124 t.Errorf("Expected type to be mentioned, got %q", err) 1125 } 1126 } 1127 1128 type ByteArrayValuer [1]byte 1129 type ByteSliceValuer []byte 1130 type FuncArrayValuer struct { 1131 delimiter func() string 1132 value func() (driver.Value, error) 1133 } 1134 1135 func (a ByteArrayValuer) Value() (driver.Value, error) { return a[:], nil } 1136 func (b ByteSliceValuer) Value() (driver.Value, error) { return []byte(b), nil } 1137 func (f FuncArrayValuer) ArrayDelimiter() string { return f.delimiter() } 1138 func (f FuncArrayValuer) Value() (driver.Value, error) { return f.value() } 1139 1140 func TestGenericArrayValue(t *testing.T) { 1141 result, err := GenericArray{nil}.Value() 1142 1143 if err != nil { 1144 t.Fatalf("Expected no error for nil, got %v", err) 1145 } 1146 if result != nil { 1147 t.Errorf("Expected nil, got %q", result) 1148 } 1149 1150 for _, tt := range []interface{}{ 1151 []bool(nil), 1152 [][]int(nil), 1153 []*int(nil), 1154 []sql.NullString(nil), 1155 } { 1156 result, err := GenericArray{tt}.Value() 1157 1158 if err != nil { 1159 t.Fatalf("Expected no error for %#v, got %v", tt, err) 1160 } 1161 if result != nil { 1162 t.Errorf("Expected nil for %#v, got %q", tt, result) 1163 } 1164 } 1165 1166 Tilde := func(v driver.Value) FuncArrayValuer { 1167 return FuncArrayValuer{ 1168 func() string { return "~" }, 1169 func() (driver.Value, error) { return v, nil }} 1170 } 1171 1172 for _, tt := range []struct { 1173 result string 1174 input interface{} 1175 }{ 1176 {`{}`, []bool{}}, 1177 {`{true}`, []bool{true}}, 1178 {`{true,false}`, []bool{true, false}}, 1179 {`{true,false}`, [2]bool{true, false}}, 1180 1181 {`{}`, [][]int{{}}}, 1182 {`{}`, [][]int{{}, {}}}, 1183 {`{{1}}`, [][]int{{1}}}, 1184 {`{{1},{2}}`, [][]int{{1}, {2}}}, 1185 {`{{1,2},{3,4}}`, [][]int{{1, 2}, {3, 4}}}, 1186 {`{{1,2},{3,4}}`, [2][2]int{{1, 2}, {3, 4}}}, 1187 1188 {`{"a","\\b","c\"","d,e"}`, []string{`a`, `\b`, `c"`, `d,e`}}, 1189 {`{"a","\\b","c\"","d,e"}`, [][]byte{{'a'}, {'\\', 'b'}, {'c', '"'}, {'d', ',', 'e'}}}, 1190 1191 {`{NULL}`, []*int{nil}}, 1192 {`{0,NULL}`, []*int{new(int), nil}}, 1193 1194 {`{NULL}`, []sql.NullString{{}}}, 1195 {`{"\"",NULL}`, []sql.NullString{{String: `"`, Valid: true}, {}}}, 1196 1197 {`{"a","b"}`, []ByteArrayValuer{{'a'}, {'b'}}}, 1198 {`{{"a","b"},{"c","d"}}`, [][]ByteArrayValuer{{{'a'}, {'b'}}, {{'c'}, {'d'}}}}, 1199 1200 {`{"e","f"}`, []ByteSliceValuer{{'e'}, {'f'}}}, 1201 {`{{"e","f"},{"g","h"}}`, [][]ByteSliceValuer{{{'e'}, {'f'}}, {{'g'}, {'h'}}}}, 1202 1203 {`{1~2}`, []FuncArrayValuer{Tilde(int64(1)), Tilde(int64(2))}}, 1204 {`{{1~2}~{3~4}}`, [][]FuncArrayValuer{{Tilde(int64(1)), Tilde(int64(2))}, {Tilde(int64(3)), Tilde(int64(4))}}}, 1205 } { 1206 result, err := GenericArray{tt.input}.Value() 1207 1208 if err != nil { 1209 t.Fatalf("Expected no error for %q, got %v", tt.input, err) 1210 } 1211 if !reflect.DeepEqual(result, tt.result) { 1212 t.Errorf("Expected %q for %q, got %q", tt.result, tt.input, result) 1213 } 1214 } 1215 } 1216 1217 func TestGenericArrayValueErrors(t *testing.T) { 1218 var v []interface{} 1219 1220 v = []interface{}{func() {}} 1221 if _, err := (GenericArray{v}).Value(); err == nil { 1222 t.Errorf("Expected error for %q, got nil", v) 1223 } 1224 1225 v = []interface{}{nil, func() {}} 1226 if _, err := (GenericArray{v}).Value(); err == nil { 1227 t.Errorf("Expected error for %q, got nil", v) 1228 } 1229 } 1230 1231 func BenchmarkGenericArrayValueBools(b *testing.B) { 1232 rand.Seed(1) 1233 x := make([]bool, 10) 1234 for i := 0; i < len(x); i++ { 1235 x[i] = rand.Intn(2) == 0 1236 } 1237 a := GenericArray{x} 1238 1239 for i := 0; i < b.N; i++ { 1240 a.Value() 1241 } 1242 } 1243 1244 func BenchmarkGenericArrayValueFloat64s(b *testing.B) { 1245 rand.Seed(1) 1246 x := make([]float64, 10) 1247 for i := 0; i < len(x); i++ { 1248 x[i] = rand.NormFloat64() 1249 } 1250 a := GenericArray{x} 1251 1252 for i := 0; i < b.N; i++ { 1253 a.Value() 1254 } 1255 } 1256 1257 func BenchmarkGenericArrayValueInt64s(b *testing.B) { 1258 rand.Seed(1) 1259 x := make([]int64, 10) 1260 for i := 0; i < len(x); i++ { 1261 x[i] = rand.Int63() 1262 } 1263 a := GenericArray{x} 1264 1265 for i := 0; i < b.N; i++ { 1266 a.Value() 1267 } 1268 } 1269 1270 func BenchmarkGenericArrayValueByteSlices(b *testing.B) { 1271 x := make([][]byte, 10) 1272 for i := 0; i < len(x); i++ { 1273 x[i] = bytes.Repeat([]byte(`abc"def\ghi`), 5) 1274 } 1275 a := GenericArray{x} 1276 1277 for i := 0; i < b.N; i++ { 1278 a.Value() 1279 } 1280 } 1281 1282 func BenchmarkGenericArrayValueStrings(b *testing.B) { 1283 x := make([]string, 10) 1284 for i := 0; i < len(x); i++ { 1285 x[i] = strings.Repeat(`abc"def\ghi`, 5) 1286 } 1287 a := GenericArray{x} 1288 1289 for i := 0; i < b.N; i++ { 1290 a.Value() 1291 } 1292 }