You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1637 lines
44 KiB

  1. /*
  2. Copyright 2017 Google LLC
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package spanner
  14. import (
  15. "encoding/base64"
  16. "reflect"
  17. "strconv"
  18. "strings"
  19. "testing"
  20. "time"
  21. "cloud.google.com/go/civil"
  22. proto "github.com/golang/protobuf/proto"
  23. proto3 "github.com/golang/protobuf/ptypes/struct"
  24. sppb "google.golang.org/genproto/googleapis/spanner/v1"
  25. )
  26. var (
  27. tm = time.Date(2016, 11, 15, 0, 0, 0, 0, time.UTC)
  28. dt, _ = civil.ParseDate("2016-11-15")
  29. // row contains a column for each unique Cloud Spanner type.
  30. row = Row{
  31. []*sppb.StructType_Field{
  32. // STRING / STRING ARRAY
  33. {Name: "STRING", Type: stringType()},
  34. {Name: "NULL_STRING", Type: stringType()},
  35. {Name: "STRING_ARRAY", Type: listType(stringType())},
  36. {Name: "NULL_STRING_ARRAY", Type: listType(stringType())},
  37. // BYTES / BYTES ARRAY
  38. {Name: "BYTES", Type: bytesType()},
  39. {Name: "NULL_BYTES", Type: bytesType()},
  40. {Name: "BYTES_ARRAY", Type: listType(bytesType())},
  41. {Name: "NULL_BYTES_ARRAY", Type: listType(bytesType())},
  42. // INT64 / INT64 ARRAY
  43. {Name: "INT64", Type: intType()},
  44. {Name: "NULL_INT64", Type: intType()},
  45. {Name: "INT64_ARRAY", Type: listType(intType())},
  46. {Name: "NULL_INT64_ARRAY", Type: listType(intType())},
  47. // BOOL / BOOL ARRAY
  48. {Name: "BOOL", Type: boolType()},
  49. {Name: "NULL_BOOL", Type: boolType()},
  50. {Name: "BOOL_ARRAY", Type: listType(boolType())},
  51. {Name: "NULL_BOOL_ARRAY", Type: listType(boolType())},
  52. // FLOAT64 / FLOAT64 ARRAY
  53. {Name: "FLOAT64", Type: floatType()},
  54. {Name: "NULL_FLOAT64", Type: floatType()},
  55. {Name: "FLOAT64_ARRAY", Type: listType(floatType())},
  56. {Name: "NULL_FLOAT64_ARRAY", Type: listType(floatType())},
  57. // TIMESTAMP / TIMESTAMP ARRAY
  58. {Name: "TIMESTAMP", Type: timeType()},
  59. {Name: "NULL_TIMESTAMP", Type: timeType()},
  60. {Name: "TIMESTAMP_ARRAY", Type: listType(timeType())},
  61. {Name: "NULL_TIMESTAMP_ARRAY", Type: listType(timeType())},
  62. // DATE / DATE ARRAY
  63. {Name: "DATE", Type: dateType()},
  64. {Name: "NULL_DATE", Type: dateType()},
  65. {Name: "DATE_ARRAY", Type: listType(dateType())},
  66. {Name: "NULL_DATE_ARRAY", Type: listType(dateType())},
  67. // STRUCT ARRAY
  68. {
  69. Name: "STRUCT_ARRAY",
  70. Type: listType(
  71. structType(
  72. mkField("Col1", intType()),
  73. mkField("Col2", floatType()),
  74. mkField("Col3", stringType()),
  75. ),
  76. ),
  77. },
  78. {
  79. Name: "NULL_STRUCT_ARRAY",
  80. Type: listType(
  81. structType(
  82. mkField("Col1", intType()),
  83. mkField("Col2", floatType()),
  84. mkField("Col3", stringType()),
  85. ),
  86. ),
  87. },
  88. },
  89. []*proto3.Value{
  90. // STRING / STRING ARRAY
  91. stringProto("value"),
  92. nullProto(),
  93. listProto(stringProto("value1"), nullProto(), stringProto("value3")),
  94. nullProto(),
  95. // BYTES / BYTES ARRAY
  96. bytesProto([]byte("value")),
  97. nullProto(),
  98. listProto(bytesProto([]byte("value1")), nullProto(), bytesProto([]byte("value3"))),
  99. nullProto(),
  100. // INT64 / INT64 ARRAY
  101. intProto(17),
  102. nullProto(),
  103. listProto(intProto(1), intProto(2), nullProto()),
  104. nullProto(),
  105. // BOOL / BOOL ARRAY
  106. boolProto(true),
  107. nullProto(),
  108. listProto(nullProto(), boolProto(true), boolProto(false)),
  109. nullProto(),
  110. // FLOAT64 / FLOAT64 ARRAY
  111. floatProto(1.7),
  112. nullProto(),
  113. listProto(nullProto(), nullProto(), floatProto(1.7)),
  114. nullProto(),
  115. // TIMESTAMP / TIMESTAMP ARRAY
  116. timeProto(tm),
  117. nullProto(),
  118. listProto(nullProto(), timeProto(tm)),
  119. nullProto(),
  120. // DATE / DATE ARRAY
  121. dateProto(dt),
  122. nullProto(),
  123. listProto(nullProto(), dateProto(dt)),
  124. nullProto(),
  125. // STRUCT ARRAY
  126. listProto(
  127. nullProto(),
  128. listProto(intProto(3), floatProto(33.3), stringProto("three")),
  129. nullProto(),
  130. ),
  131. nullProto(),
  132. },
  133. }
  134. )
  135. // Test helpers for getting column values.
  136. func TestColumnValues(t *testing.T) {
  137. vals := []interface{}{}
  138. wantVals := []interface{}{}
  139. // Test getting column values.
  140. for i, wants := range [][]interface{}{
  141. // STRING / STRING ARRAY
  142. {"value", NullString{"value", true}},
  143. {NullString{}},
  144. {[]NullString{{"value1", true}, {}, {"value3", true}}},
  145. {[]NullString(nil)},
  146. // BYTES / BYTES ARRAY
  147. {[]byte("value")},
  148. {[]byte(nil)},
  149. {[][]byte{[]byte("value1"), nil, []byte("value3")}},
  150. {[][]byte(nil)},
  151. // INT64 / INT64 ARRAY
  152. {int64(17), NullInt64{17, true}},
  153. {NullInt64{}},
  154. {[]NullInt64{{1, true}, {2, true}, {}}},
  155. {[]NullInt64(nil)},
  156. // BOOL / BOOL ARRAY
  157. {true, NullBool{true, true}},
  158. {NullBool{}},
  159. {[]NullBool{{}, {true, true}, {false, true}}},
  160. {[]NullBool(nil)},
  161. // FLOAT64 / FLOAT64 ARRAY
  162. {1.7, NullFloat64{1.7, true}},
  163. {NullFloat64{}},
  164. {[]NullFloat64{{}, {}, {1.7, true}}},
  165. {[]NullFloat64(nil)},
  166. // TIMESTAMP / TIMESTAMP ARRAY
  167. {tm, NullTime{tm, true}},
  168. {NullTime{}},
  169. {[]NullTime{{}, {tm, true}}},
  170. {[]NullTime(nil)},
  171. // DATE / DATE ARRAY
  172. {dt, NullDate{dt, true}},
  173. {NullDate{}},
  174. {[]NullDate{{}, {dt, true}}},
  175. {[]NullDate(nil)},
  176. // STRUCT ARRAY
  177. {
  178. []*struct {
  179. Col1 NullInt64
  180. Col2 NullFloat64
  181. Col3 string
  182. }{
  183. nil,
  184. {
  185. NullInt64{3, true},
  186. NullFloat64{33.3, true},
  187. "three",
  188. },
  189. nil,
  190. },
  191. []NullRow{
  192. {},
  193. {
  194. Row: Row{
  195. fields: []*sppb.StructType_Field{
  196. mkField("Col1", intType()),
  197. mkField("Col2", floatType()),
  198. mkField("Col3", stringType()),
  199. },
  200. vals: []*proto3.Value{
  201. intProto(3),
  202. floatProto(33.3),
  203. stringProto("three"),
  204. },
  205. },
  206. Valid: true,
  207. },
  208. {},
  209. },
  210. },
  211. {
  212. []*struct {
  213. Col1 NullInt64
  214. Col2 NullFloat64
  215. Col3 string
  216. }(nil),
  217. []NullRow(nil),
  218. },
  219. } {
  220. for j, want := range wants {
  221. // Prepare Value vector to test Row.Columns.
  222. if j == 0 {
  223. vals = append(vals, reflect.New(reflect.TypeOf(want)).Interface())
  224. wantVals = append(wantVals, want)
  225. }
  226. // Column
  227. gotp := reflect.New(reflect.TypeOf(want))
  228. err := row.Column(i, gotp.Interface())
  229. if err != nil {
  230. t.Errorf("\t row.Column(%v, %T) returns error: %v, want nil", i, gotp.Interface(), err)
  231. }
  232. if got := reflect.Indirect(gotp).Interface(); !testEqual(got, want) {
  233. t.Errorf("\t row.Column(%v, %T) retrives %v, want %v", i, gotp.Interface(), got, want)
  234. }
  235. // ColumnByName
  236. gotp = reflect.New(reflect.TypeOf(want))
  237. err = row.ColumnByName(row.fields[i].Name, gotp.Interface())
  238. if err != nil {
  239. t.Errorf("\t row.ColumnByName(%v, %T) returns error: %v, want nil", row.fields[i].Name, gotp.Interface(), err)
  240. }
  241. if got := reflect.Indirect(gotp).Interface(); !testEqual(got, want) {
  242. t.Errorf("\t row.ColumnByName(%v, %T) retrives %v, want %v", row.fields[i].Name, gotp.Interface(), got, want)
  243. }
  244. }
  245. }
  246. // Test Row.Columns.
  247. if err := row.Columns(vals...); err != nil {
  248. t.Errorf("row.Columns() returns error: %v, want nil", err)
  249. }
  250. for i, want := range wantVals {
  251. if got := reflect.Indirect(reflect.ValueOf(vals[i])).Interface(); !testEqual(got, want) {
  252. t.Errorf("\t got %v(%T) for column[%v], want %v(%T)", got, got, row.fields[i].Name, want, want)
  253. }
  254. }
  255. }
  256. // Test decoding into nil destination.
  257. func TestNilDst(t *testing.T) {
  258. for i, test := range []struct {
  259. r *Row
  260. dst interface{}
  261. wantErr error
  262. structDst interface{}
  263. wantToStructErr error
  264. }{
  265. {
  266. &Row{
  267. []*sppb.StructType_Field{
  268. {Name: "Col0", Type: stringType()},
  269. },
  270. []*proto3.Value{stringProto("value")},
  271. },
  272. nil,
  273. errDecodeColumn(0, errNilDst(nil)),
  274. nil,
  275. errToStructArgType(nil),
  276. },
  277. {
  278. &Row{
  279. []*sppb.StructType_Field{
  280. {Name: "Col0", Type: stringType()},
  281. },
  282. []*proto3.Value{stringProto("value")},
  283. },
  284. (*string)(nil),
  285. errDecodeColumn(0, errNilDst((*string)(nil))),
  286. (*struct{ STRING string })(nil),
  287. errNilDst((*struct{ STRING string })(nil)),
  288. },
  289. {
  290. &Row{
  291. []*sppb.StructType_Field{
  292. {
  293. Name: "Col0",
  294. Type: listType(
  295. structType(
  296. mkField("Col1", intType()),
  297. mkField("Col2", floatType()),
  298. ),
  299. ),
  300. },
  301. },
  302. []*proto3.Value{listProto(
  303. listProto(intProto(3), floatProto(33.3)),
  304. )},
  305. },
  306. (*[]*struct {
  307. Col1 int
  308. Col2 float64
  309. })(nil),
  310. errDecodeColumn(0, errNilDst((*[]*struct {
  311. Col1 int
  312. Col2 float64
  313. })(nil))),
  314. (*struct {
  315. StructArray []*struct {
  316. Col1 int
  317. Col2 float64
  318. } `spanner:"STRUCT_ARRAY"`
  319. })(nil),
  320. errNilDst((*struct {
  321. StructArray []*struct {
  322. Col1 int
  323. Col2 float64
  324. } `spanner:"STRUCT_ARRAY"`
  325. })(nil)),
  326. },
  327. } {
  328. if gotErr := test.r.Column(0, test.dst); !testEqual(gotErr, test.wantErr) {
  329. t.Errorf("%v: test.r.Column() returns error %v, want %v", i, gotErr, test.wantErr)
  330. }
  331. if gotErr := test.r.ColumnByName("Col0", test.dst); !testEqual(gotErr, test.wantErr) {
  332. t.Errorf("%v: test.r.ColumnByName() returns error %v, want %v", i, gotErr, test.wantErr)
  333. }
  334. // Row.Columns(T) should return nil on T == nil, otherwise, it should return test.wantErr.
  335. wantColumnsErr := test.wantErr
  336. if test.dst == nil {
  337. wantColumnsErr = nil
  338. }
  339. if gotErr := test.r.Columns(test.dst); !testEqual(gotErr, wantColumnsErr) {
  340. t.Errorf("%v: test.r.Columns() returns error %v, want %v", i, gotErr, wantColumnsErr)
  341. }
  342. if gotErr := test.r.ToStruct(test.structDst); !testEqual(gotErr, test.wantToStructErr) {
  343. t.Errorf("%v: test.r.ToStruct() returns error %v, want %v", i, gotErr, test.wantToStructErr)
  344. }
  345. }
  346. }
  347. // Test decoding NULL columns using Go types that don't support NULL.
  348. func TestNullTypeErr(t *testing.T) {
  349. var tm time.Time
  350. ntoi := func(n string) int {
  351. for i, f := range row.fields {
  352. if f.Name == n {
  353. return i
  354. }
  355. }
  356. t.Errorf("cannot find column name %q in row", n)
  357. return 0
  358. }
  359. for _, test := range []struct {
  360. colName string
  361. dst interface{}
  362. }{
  363. {
  364. "NULL_STRING",
  365. proto.String(""),
  366. },
  367. {
  368. "NULL_INT64",
  369. proto.Int64(0),
  370. },
  371. {
  372. "NULL_BOOL",
  373. proto.Bool(false),
  374. },
  375. {
  376. "NULL_FLOAT64",
  377. proto.Float64(0.0),
  378. },
  379. {
  380. "NULL_TIMESTAMP",
  381. &tm,
  382. },
  383. {
  384. "NULL_DATE",
  385. &dt,
  386. },
  387. } {
  388. wantErr := errDecodeColumn(ntoi(test.colName), errDstNotForNull(test.dst))
  389. if gotErr := row.ColumnByName(test.colName, test.dst); !testEqual(gotErr, wantErr) {
  390. t.Errorf("row.ColumnByName(%v) returns error %v, want %v", test.colName, gotErr, wantErr)
  391. }
  392. }
  393. }
  394. // Test using wrong destination type in column decoders.
  395. func TestColumnTypeErr(t *testing.T) {
  396. // badDst cannot hold any of the column values.
  397. badDst := &struct{}{}
  398. for i, f := range row.fields { // For each of the columns, try to decode it into badDst.
  399. tc := f.Type.Code
  400. var etc sppb.TypeCode
  401. if strings.Contains(f.Name, "ARRAY") {
  402. etc = f.Type.ArrayElementType.Code
  403. }
  404. wantErr := errDecodeColumn(i, errTypeMismatch(tc, etc, badDst))
  405. if gotErr := row.Column(i, badDst); !testEqual(gotErr, wantErr) {
  406. t.Errorf("Column(%v): decoding into destination with wrong type %T returns error %v, want %v",
  407. i, badDst, gotErr, wantErr)
  408. }
  409. if gotErr := row.ColumnByName(f.Name, badDst); !testEqual(gotErr, wantErr) {
  410. t.Errorf("ColumnByName(%v): decoding into destination with wrong type %T returns error %v, want %v",
  411. f.Name, badDst, gotErr, wantErr)
  412. }
  413. }
  414. wantErr := errDecodeColumn(1, errTypeMismatch(sppb.TypeCode_STRING, sppb.TypeCode_TYPE_CODE_UNSPECIFIED, badDst))
  415. // badDst is used to receive column 1.
  416. vals := []interface{}{nil, badDst} // Row.Column() is expected to fail at column 1.
  417. // Skip decoding the rest columns by providing nils as the destinations.
  418. for i := 2; i < len(row.fields); i++ {
  419. vals = append(vals, nil)
  420. }
  421. if gotErr := row.Columns(vals...); !testEqual(gotErr, wantErr) {
  422. t.Errorf("Columns(): decoding column 1 with wrong type %T returns error %v, want %v",
  423. badDst, gotErr, wantErr)
  424. }
  425. }
  426. // Test the handling of invalid column decoding requests which cannot be mapped to correct column(s).
  427. func TestInvalidColumnRequest(t *testing.T) {
  428. for _, test := range []struct {
  429. desc string
  430. f func() error
  431. wantErr error
  432. }{
  433. {
  434. "Request column index is out of range",
  435. func() error {
  436. return row.Column(10000, &struct{}{})
  437. },
  438. errColIdxOutOfRange(10000, &row),
  439. },
  440. {
  441. "Cannot find the named column",
  442. func() error {
  443. return row.ColumnByName("string", &struct{}{})
  444. },
  445. errColNotFound("string"),
  446. },
  447. {
  448. "Not enough arguments to call row.Columns()",
  449. func() error {
  450. return row.Columns(nil, nil)
  451. },
  452. errNumOfColValue(2, &row),
  453. },
  454. {
  455. "Call ColumnByName on row with duplicated column names",
  456. func() error {
  457. var s string
  458. r := &Row{
  459. []*sppb.StructType_Field{
  460. {Name: "Val", Type: stringType()},
  461. {Name: "Val", Type: stringType()},
  462. },
  463. []*proto3.Value{stringProto("value1"), stringProto("value2")},
  464. }
  465. return r.ColumnByName("Val", &s)
  466. },
  467. errDupColName("Val"),
  468. },
  469. {
  470. "Call ToStruct on row with duplicated column names",
  471. func() error {
  472. s := &struct {
  473. Val string
  474. }{}
  475. r := &Row{
  476. []*sppb.StructType_Field{
  477. {Name: "Val", Type: stringType()},
  478. {Name: "Val", Type: stringType()},
  479. },
  480. []*proto3.Value{stringProto("value1"), stringProto("value2")},
  481. }
  482. return r.ToStruct(s)
  483. },
  484. errDupSpannerField("Val", &sppb.StructType{
  485. Fields: []*sppb.StructType_Field{
  486. {Name: "Val", Type: stringType()},
  487. {Name: "Val", Type: stringType()},
  488. },
  489. }),
  490. },
  491. {
  492. "Call ToStruct on a row with unnamed field",
  493. func() error {
  494. s := &struct {
  495. Val string
  496. }{}
  497. r := &Row{
  498. []*sppb.StructType_Field{
  499. {Name: "", Type: stringType()},
  500. },
  501. []*proto3.Value{stringProto("value1")},
  502. }
  503. return r.ToStruct(s)
  504. },
  505. errUnnamedField(&sppb.StructType{Fields: []*sppb.StructType_Field{
  506. {Name: "", Type: stringType()},
  507. }}, 0),
  508. },
  509. } {
  510. if gotErr := test.f(); !testEqual(gotErr, test.wantErr) {
  511. t.Errorf("%v: test.f() returns error %v, want %v", test.desc, gotErr, test.wantErr)
  512. }
  513. }
  514. }
  515. // Test decoding the row with row.ToStruct into an invalid destination.
  516. func TestToStructInvalidDst(t *testing.T) {
  517. for _, test := range []struct {
  518. desc string
  519. dst interface{}
  520. wantErr error
  521. }{
  522. {
  523. "Decode row as STRUCT into int32",
  524. proto.Int(1),
  525. errToStructArgType(proto.Int(1)),
  526. },
  527. {
  528. "Decode row as STRUCT to nil Go struct",
  529. (*struct{})(nil),
  530. errNilDst((*struct{})(nil)),
  531. },
  532. {
  533. "Decode row as STRUCT to Go struct with duplicated fields for the PK column",
  534. &struct {
  535. PK1 string `spanner:"STRING"`
  536. PK2 string `spanner:"STRING"`
  537. }{},
  538. errNoOrDupGoField(&struct {
  539. PK1 string `spanner:"STRING"`
  540. PK2 string `spanner:"STRING"`
  541. }{}, "STRING"),
  542. },
  543. {
  544. "Decode row as STRUCT to Go struct with no field for the PK column",
  545. &struct {
  546. PK1 string `spanner:"_STRING"`
  547. }{},
  548. errNoOrDupGoField(&struct {
  549. PK1 string `spanner:"_STRING"`
  550. }{}, "STRING"),
  551. },
  552. {
  553. "Decode row as STRUCT to Go struct with wrong type for the PK column",
  554. &struct {
  555. PK1 int64 `spanner:"STRING"`
  556. }{},
  557. errDecodeStructField(&sppb.StructType{Fields: row.fields}, "STRING",
  558. errTypeMismatch(sppb.TypeCode_STRING, sppb.TypeCode_TYPE_CODE_UNSPECIFIED, proto.Int64(0))),
  559. },
  560. } {
  561. if gotErr := row.ToStruct(test.dst); !testEqual(gotErr, test.wantErr) {
  562. t.Errorf("%v: decoding:\ngot %v\nwant %v", test.desc, gotErr, test.wantErr)
  563. }
  564. }
  565. }
  566. // Test decoding a broken row.
  567. func TestBrokenRow(t *testing.T) {
  568. for i, test := range []struct {
  569. row *Row
  570. dst interface{}
  571. wantErr error
  572. }{
  573. {
  574. // A row with no field.
  575. &Row{
  576. []*sppb.StructType_Field{},
  577. []*proto3.Value{stringProto("value")},
  578. },
  579. &NullString{"value", true},
  580. errFieldsMismatchVals(&Row{
  581. []*sppb.StructType_Field{},
  582. []*proto3.Value{stringProto("value")},
  583. }),
  584. },
  585. {
  586. // A row with nil field.
  587. &Row{
  588. []*sppb.StructType_Field{nil},
  589. []*proto3.Value{stringProto("value")},
  590. },
  591. &NullString{"value", true},
  592. errNilColType(0),
  593. },
  594. {
  595. // Field is not nil, but its type is nil.
  596. &Row{
  597. []*sppb.StructType_Field{
  598. {Name: "Col0", Type: nil},
  599. },
  600. []*proto3.Value{listProto(stringProto("value1"), stringProto("value2"))},
  601. },
  602. &[]NullString{},
  603. errDecodeColumn(0, errNilSpannerType()),
  604. },
  605. {
  606. // Field is not nil, field type is not nil, but it is an array and its array element type is nil.
  607. &Row{
  608. []*sppb.StructType_Field{
  609. {Name: "Col0", Type: &sppb.Type{Code: sppb.TypeCode_ARRAY}},
  610. },
  611. []*proto3.Value{listProto(stringProto("value1"), stringProto("value2"))},
  612. },
  613. &[]NullString{},
  614. errDecodeColumn(0, errNilArrElemType(&sppb.Type{Code: sppb.TypeCode_ARRAY})),
  615. },
  616. {
  617. // Field specifies valid type, value is nil.
  618. &Row{
  619. []*sppb.StructType_Field{
  620. {Name: "Col0", Type: intType()},
  621. },
  622. []*proto3.Value{nil},
  623. },
  624. &NullInt64{1, true},
  625. errDecodeColumn(0, errNilSrc()),
  626. },
  627. {
  628. // Field specifies INT64 type, value is having a nil Kind.
  629. &Row{
  630. []*sppb.StructType_Field{
  631. {Name: "Col0", Type: intType()},
  632. },
  633. []*proto3.Value{{Kind: (*proto3.Value_StringValue)(nil)}},
  634. },
  635. &NullInt64{1, true},
  636. errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_StringValue)(nil)}, "String")),
  637. },
  638. {
  639. // Field specifies INT64 type, but value is for Number type.
  640. &Row{
  641. []*sppb.StructType_Field{
  642. {Name: "Col0", Type: intType()},
  643. },
  644. []*proto3.Value{floatProto(1.0)},
  645. },
  646. &NullInt64{1, true},
  647. errDecodeColumn(0, errSrcVal(floatProto(1.0), "String")),
  648. },
  649. {
  650. // Field specifies INT64 type, but value is wrongly encoded.
  651. &Row{
  652. []*sppb.StructType_Field{
  653. {Name: "Col0", Type: intType()},
  654. },
  655. []*proto3.Value{stringProto("&1")},
  656. },
  657. proto.Int64(0),
  658. errDecodeColumn(0, errBadEncoding(stringProto("&1"), func() error {
  659. _, err := strconv.ParseInt("&1", 10, 64)
  660. return err
  661. }())),
  662. },
  663. {
  664. // Field specifies INT64 type, but value is wrongly encoded.
  665. &Row{
  666. []*sppb.StructType_Field{
  667. {Name: "Col0", Type: intType()},
  668. },
  669. []*proto3.Value{stringProto("&1")},
  670. },
  671. &NullInt64{},
  672. errDecodeColumn(0, errBadEncoding(stringProto("&1"), func() error {
  673. _, err := strconv.ParseInt("&1", 10, 64)
  674. return err
  675. }())),
  676. },
  677. {
  678. // Field specifies STRING type, but value is having a nil Kind.
  679. &Row{
  680. []*sppb.StructType_Field{
  681. {Name: "Col0", Type: stringType()},
  682. },
  683. []*proto3.Value{{Kind: (*proto3.Value_StringValue)(nil)}},
  684. },
  685. &NullString{"value", true},
  686. errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_StringValue)(nil)}, "String")),
  687. },
  688. {
  689. // Field specifies STRING type, but value is for ARRAY type.
  690. &Row{
  691. []*sppb.StructType_Field{
  692. {Name: "Col0", Type: stringType()},
  693. },
  694. []*proto3.Value{listProto(stringProto("value"))},
  695. },
  696. &NullString{"value", true},
  697. errDecodeColumn(0, errSrcVal(listProto(stringProto("value")), "String")),
  698. },
  699. {
  700. // Field specifies FLOAT64 type, value is having a nil Kind.
  701. &Row{
  702. []*sppb.StructType_Field{
  703. {Name: "Col0", Type: floatType()},
  704. },
  705. []*proto3.Value{{Kind: (*proto3.Value_NumberValue)(nil)}},
  706. },
  707. &NullFloat64{1.0, true},
  708. errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_NumberValue)(nil)}, "Number")),
  709. },
  710. {
  711. // Field specifies FLOAT64 type, but value is for BOOL type.
  712. &Row{
  713. []*sppb.StructType_Field{
  714. {Name: "Col0", Type: floatType()},
  715. },
  716. []*proto3.Value{boolProto(true)},
  717. },
  718. &NullFloat64{1.0, true},
  719. errDecodeColumn(0, errSrcVal(boolProto(true), "Number")),
  720. },
  721. {
  722. // Field specifies FLOAT64 type, but value is wrongly encoded.
  723. &Row{
  724. []*sppb.StructType_Field{
  725. {Name: "Col0", Type: floatType()},
  726. },
  727. []*proto3.Value{stringProto("nan")},
  728. },
  729. &NullFloat64{},
  730. errDecodeColumn(0, errUnexpectedNumStr("nan")),
  731. },
  732. {
  733. // Field specifies FLOAT64 type, but value is wrongly encoded.
  734. &Row{
  735. []*sppb.StructType_Field{
  736. {Name: "Col0", Type: floatType()},
  737. },
  738. []*proto3.Value{stringProto("nan")},
  739. },
  740. proto.Float64(0),
  741. errDecodeColumn(0, errUnexpectedNumStr("nan")),
  742. },
  743. {
  744. // Field specifies BYTES type, value is having a nil Kind.
  745. &Row{
  746. []*sppb.StructType_Field{
  747. {Name: "Col0", Type: bytesType()},
  748. },
  749. []*proto3.Value{{Kind: (*proto3.Value_StringValue)(nil)}},
  750. },
  751. &[]byte{},
  752. errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_StringValue)(nil)}, "String")),
  753. },
  754. {
  755. // Field specifies BYTES type, but value is for BOOL type.
  756. &Row{
  757. []*sppb.StructType_Field{
  758. {Name: "Col0", Type: bytesType()},
  759. },
  760. []*proto3.Value{boolProto(false)},
  761. },
  762. &[]byte{},
  763. errDecodeColumn(0, errSrcVal(boolProto(false), "String")),
  764. },
  765. {
  766. // Field specifies BYTES type, but value is wrongly encoded.
  767. &Row{
  768. []*sppb.StructType_Field{
  769. {Name: "Col0", Type: bytesType()},
  770. },
  771. []*proto3.Value{stringProto("&&")},
  772. },
  773. &[]byte{},
  774. errDecodeColumn(0, errBadEncoding(stringProto("&&"), func() error {
  775. _, err := base64.StdEncoding.DecodeString("&&")
  776. return err
  777. }())),
  778. },
  779. {
  780. // Field specifies BOOL type, value is having a nil Kind.
  781. &Row{
  782. []*sppb.StructType_Field{
  783. {Name: "Col0", Type: boolType()},
  784. },
  785. []*proto3.Value{{Kind: (*proto3.Value_BoolValue)(nil)}},
  786. },
  787. &NullBool{false, true},
  788. errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_BoolValue)(nil)}, "Bool")),
  789. },
  790. {
  791. // Field specifies BOOL type, but value is for STRING type.
  792. &Row{
  793. []*sppb.StructType_Field{
  794. {Name: "Col0", Type: boolType()},
  795. },
  796. []*proto3.Value{stringProto("false")},
  797. },
  798. &NullBool{false, true},
  799. errDecodeColumn(0, errSrcVal(stringProto("false"), "Bool")),
  800. },
  801. {
  802. // Field specifies TIMESTAMP type, value is having a nil Kind.
  803. &Row{
  804. []*sppb.StructType_Field{
  805. {Name: "Col0", Type: timeType()},
  806. },
  807. []*proto3.Value{{Kind: (*proto3.Value_StringValue)(nil)}},
  808. },
  809. &NullTime{time.Now(), true},
  810. errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_StringValue)(nil)}, "String")),
  811. },
  812. {
  813. // Field specifies TIMESTAMP type, but value is for BOOL type.
  814. &Row{
  815. []*sppb.StructType_Field{
  816. {Name: "Col0", Type: timeType()},
  817. },
  818. []*proto3.Value{boolProto(false)},
  819. },
  820. &NullTime{time.Now(), true},
  821. errDecodeColumn(0, errSrcVal(boolProto(false), "String")),
  822. },
  823. {
  824. // Field specifies TIMESTAMP type, but value is invalid timestamp.
  825. &Row{
  826. []*sppb.StructType_Field{
  827. {Name: "Col0", Type: timeType()},
  828. },
  829. []*proto3.Value{stringProto("junk")},
  830. },
  831. &NullTime{time.Now(), true},
  832. errDecodeColumn(0, errBadEncoding(stringProto("junk"), func() error {
  833. _, err := time.Parse(time.RFC3339Nano, "junk")
  834. return err
  835. }())),
  836. },
  837. {
  838. // Field specifies DATE type, value is having a nil Kind.
  839. &Row{
  840. []*sppb.StructType_Field{
  841. {Name: "Col0", Type: dateType()},
  842. },
  843. []*proto3.Value{{Kind: (*proto3.Value_StringValue)(nil)}},
  844. },
  845. &NullDate{civil.Date{}, true},
  846. errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_StringValue)(nil)}, "String")),
  847. },
  848. {
  849. // Field specifies DATE type, but value is for BOOL type.
  850. &Row{
  851. []*sppb.StructType_Field{
  852. {Name: "Col0", Type: dateType()},
  853. },
  854. []*proto3.Value{boolProto(false)},
  855. },
  856. &NullDate{civil.Date{}, true},
  857. errDecodeColumn(0, errSrcVal(boolProto(false), "String")),
  858. },
  859. {
  860. // Field specifies DATE type, but value is invalid timestamp.
  861. &Row{
  862. []*sppb.StructType_Field{
  863. {Name: "Col0", Type: dateType()},
  864. },
  865. []*proto3.Value{stringProto("junk")},
  866. },
  867. &NullDate{civil.Date{}, true},
  868. errDecodeColumn(0, errBadEncoding(stringProto("junk"), func() error {
  869. _, err := civil.ParseDate("junk")
  870. return err
  871. }())),
  872. },
  873. {
  874. // Field specifies ARRAY<INT64> type, value is having a nil Kind.
  875. &Row{
  876. []*sppb.StructType_Field{
  877. {Name: "Col0", Type: listType(intType())},
  878. },
  879. []*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}},
  880. },
  881. &[]NullInt64{},
  882. errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")),
  883. },
  884. {
  885. // Field specifies ARRAY<INT64> type, value is having a nil ListValue.
  886. &Row{
  887. []*sppb.StructType_Field{
  888. {Name: "Col0", Type: listType(intType())},
  889. },
  890. []*proto3.Value{{Kind: &proto3.Value_ListValue{}}},
  891. },
  892. &[]NullInt64{},
  893. errDecodeColumn(0, errNilListValue("INT64")),
  894. },
  895. {
  896. // Field specifies ARRAY<INT64> type, but value is for BYTES type.
  897. &Row{
  898. []*sppb.StructType_Field{
  899. {Name: "Col0", Type: listType(intType())},
  900. },
  901. []*proto3.Value{bytesProto([]byte("value"))},
  902. },
  903. &[]NullInt64{},
  904. errDecodeColumn(0, errSrcVal(bytesProto([]byte("value")), "List")),
  905. },
  906. {
  907. // Field specifies ARRAY<INT64> type, but value is for ARRAY<BOOL> type.
  908. &Row{
  909. []*sppb.StructType_Field{
  910. {Name: "Col0", Type: listType(intType())},
  911. },
  912. []*proto3.Value{listProto(boolProto(true))},
  913. },
  914. &[]NullInt64{},
  915. errDecodeColumn(0, errDecodeArrayElement(0, boolProto(true),
  916. "INT64", errSrcVal(boolProto(true), "String"))),
  917. },
  918. {
  919. // Field specifies ARRAY<STRING> type, value is having a nil Kind.
  920. &Row{
  921. []*sppb.StructType_Field{
  922. {Name: "Col0", Type: listType(stringType())},
  923. },
  924. []*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}},
  925. },
  926. &[]NullString{},
  927. errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")),
  928. },
  929. {
  930. // Field specifies ARRAY<STRING> type, value is having a nil ListValue.
  931. &Row{
  932. []*sppb.StructType_Field{
  933. {Name: "Col0", Type: listType(stringType())},
  934. },
  935. []*proto3.Value{{Kind: &proto3.Value_ListValue{}}},
  936. },
  937. &[]NullString{},
  938. errDecodeColumn(0, errNilListValue("STRING")),
  939. },
  940. {
  941. // Field specifies ARRAY<STRING> type, but value is for BOOL type.
  942. &Row{
  943. []*sppb.StructType_Field{
  944. {Name: "Col0", Type: listType(stringType())},
  945. },
  946. []*proto3.Value{boolProto(true)},
  947. },
  948. &[]NullString{},
  949. errDecodeColumn(0, errSrcVal(boolProto(true), "List")),
  950. },
  951. {
  952. // Field specifies ARRAY<STRING> type, but value is for ARRAY<BOOL> type.
  953. &Row{
  954. []*sppb.StructType_Field{
  955. {Name: "Col0", Type: listType(stringType())},
  956. },
  957. []*proto3.Value{listProto(boolProto(true))},
  958. },
  959. &[]NullString{},
  960. errDecodeColumn(0, errDecodeArrayElement(0, boolProto(true),
  961. "STRING", errSrcVal(boolProto(true), "String"))),
  962. },
  963. {
  964. // Field specifies ARRAY<FLOAT64> type, value is having a nil Kind.
  965. &Row{
  966. []*sppb.StructType_Field{
  967. {Name: "Col0", Type: listType(floatType())},
  968. },
  969. []*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}},
  970. },
  971. &[]NullFloat64{},
  972. errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")),
  973. },
  974. {
  975. // Field specifies ARRAY<FLOAT64> type, value is having a nil ListValue.
  976. &Row{
  977. []*sppb.StructType_Field{
  978. {Name: "Col0", Type: listType(floatType())},
  979. },
  980. []*proto3.Value{{Kind: &proto3.Value_ListValue{}}},
  981. },
  982. &[]NullFloat64{},
  983. errDecodeColumn(0, errNilListValue("FLOAT64")),
  984. },
  985. {
  986. // Field specifies ARRAY<FLOAT64> type, but value is for STRING type.
  987. &Row{
  988. []*sppb.StructType_Field{
  989. {Name: "Col0", Type: listType(floatType())},
  990. },
  991. []*proto3.Value{stringProto("value")},
  992. },
  993. &[]NullFloat64{},
  994. errDecodeColumn(0, errSrcVal(stringProto("value"), "List")),
  995. },
  996. {
  997. // Field specifies ARRAY<FLOAT64> type, but value is for ARRAY<BOOL> type.
  998. &Row{
  999. []*sppb.StructType_Field{
  1000. {Name: "Col0", Type: listType(floatType())},
  1001. },
  1002. []*proto3.Value{listProto(boolProto(true))},
  1003. },
  1004. &[]NullFloat64{},
  1005. errDecodeColumn(0, errDecodeArrayElement(0, boolProto(true),
  1006. "FLOAT64", errSrcVal(boolProto(true), "Number"))),
  1007. },
  1008. {
  1009. // Field specifies ARRAY<BYTES> type, value is having a nil Kind.
  1010. &Row{
  1011. []*sppb.StructType_Field{
  1012. {Name: "Col0", Type: listType(bytesType())},
  1013. },
  1014. []*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}},
  1015. },
  1016. &[][]byte{},
  1017. errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")),
  1018. },
  1019. {
  1020. // Field specifies ARRAY<BYTES> type, value is having a nil ListValue.
  1021. &Row{
  1022. []*sppb.StructType_Field{
  1023. {Name: "Col0", Type: listType(bytesType())},
  1024. },
  1025. []*proto3.Value{{Kind: &proto3.Value_ListValue{}}},
  1026. },
  1027. &[][]byte{},
  1028. errDecodeColumn(0, errNilListValue("BYTES")),
  1029. },
  1030. {
  1031. // Field specifies ARRAY<BYTES> type, but value is for FLOAT64 type.
  1032. &Row{
  1033. []*sppb.StructType_Field{
  1034. {Name: "Col0", Type: listType(bytesType())},
  1035. },
  1036. []*proto3.Value{floatProto(1.0)},
  1037. },
  1038. &[][]byte{},
  1039. errDecodeColumn(0, errSrcVal(floatProto(1.0), "List")),
  1040. },
  1041. {
  1042. // Field specifies ARRAY<BYTES> type, but value is for ARRAY<FLOAT64> type.
  1043. &Row{
  1044. []*sppb.StructType_Field{
  1045. {Name: "Col0", Type: listType(bytesType())},
  1046. },
  1047. []*proto3.Value{listProto(floatProto(1.0))},
  1048. },
  1049. &[][]byte{},
  1050. errDecodeColumn(0, errDecodeArrayElement(0, floatProto(1.0),
  1051. "BYTES", errSrcVal(floatProto(1.0), "String"))),
  1052. },
  1053. {
  1054. // Field specifies ARRAY<BOOL> type, value is having a nil Kind.
  1055. &Row{
  1056. []*sppb.StructType_Field{
  1057. {Name: "Col0", Type: listType(boolType())},
  1058. },
  1059. []*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}},
  1060. },
  1061. &[]NullBool{},
  1062. errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")),
  1063. },
  1064. {
  1065. // Field specifies ARRAY<BOOL> type, value is having a nil ListValue.
  1066. &Row{
  1067. []*sppb.StructType_Field{
  1068. {Name: "Col0", Type: listType(boolType())},
  1069. },
  1070. []*proto3.Value{{Kind: &proto3.Value_ListValue{}}},
  1071. },
  1072. &[]NullBool{},
  1073. errDecodeColumn(0, errNilListValue("BOOL")),
  1074. },
  1075. {
  1076. // Field specifies ARRAY<BOOL> type, but value is for FLOAT64 type.
  1077. &Row{
  1078. []*sppb.StructType_Field{
  1079. {Name: "Col0", Type: listType(boolType())},
  1080. },
  1081. []*proto3.Value{floatProto(1.0)},
  1082. },
  1083. &[]NullBool{},
  1084. errDecodeColumn(0, errSrcVal(floatProto(1.0), "List")),
  1085. },
  1086. {
  1087. // Field specifies ARRAY<BOOL> type, but value is for ARRAY<FLOAT64> type.
  1088. &Row{
  1089. []*sppb.StructType_Field{
  1090. {Name: "Col0", Type: listType(boolType())},
  1091. },
  1092. []*proto3.Value{listProto(floatProto(1.0))},
  1093. },
  1094. &[]NullBool{},
  1095. errDecodeColumn(0, errDecodeArrayElement(0, floatProto(1.0),
  1096. "BOOL", errSrcVal(floatProto(1.0), "Bool"))),
  1097. },
  1098. {
  1099. // Field specifies ARRAY<TIMESTAMP> type, value is having a nil Kind.
  1100. &Row{
  1101. []*sppb.StructType_Field{
  1102. {Name: "Col0", Type: listType(timeType())},
  1103. },
  1104. []*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}},
  1105. },
  1106. &[]NullTime{},
  1107. errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")),
  1108. },
  1109. {
  1110. // Field specifies ARRAY<TIMESTAMP> type, value is having a nil ListValue.
  1111. &Row{
  1112. []*sppb.StructType_Field{
  1113. {Name: "Col0", Type: listType(timeType())},
  1114. },
  1115. []*proto3.Value{{Kind: &proto3.Value_ListValue{}}},
  1116. },
  1117. &[]NullTime{},
  1118. errDecodeColumn(0, errNilListValue("TIMESTAMP")),
  1119. },
  1120. {
  1121. // Field specifies ARRAY<TIMESTAMP> type, but value is for FLOAT64 type.
  1122. &Row{
  1123. []*sppb.StructType_Field{
  1124. {Name: "Col0", Type: listType(timeType())},
  1125. },
  1126. []*proto3.Value{floatProto(1.0)},
  1127. },
  1128. &[]NullTime{},
  1129. errDecodeColumn(0, errSrcVal(floatProto(1.0), "List")),
  1130. },
  1131. {
  1132. // Field specifies ARRAY<TIMESTAMP> type, but value is for ARRAY<FLOAT64> type.
  1133. &Row{
  1134. []*sppb.StructType_Field{
  1135. {Name: "Col0", Type: listType(timeType())},
  1136. },
  1137. []*proto3.Value{listProto(floatProto(1.0))},
  1138. },
  1139. &[]NullTime{},
  1140. errDecodeColumn(0, errDecodeArrayElement(0, floatProto(1.0),
  1141. "TIMESTAMP", errSrcVal(floatProto(1.0), "String"))),
  1142. },
  1143. {
  1144. // Field specifies ARRAY<DATE> type, value is having a nil Kind.
  1145. &Row{
  1146. []*sppb.StructType_Field{
  1147. {Name: "Col0", Type: listType(dateType())},
  1148. },
  1149. []*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}},
  1150. },
  1151. &[]NullDate{},
  1152. errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")),
  1153. },
  1154. {
  1155. // Field specifies ARRAY<DATE> type, value is having a nil ListValue.
  1156. &Row{
  1157. []*sppb.StructType_Field{
  1158. {Name: "Col0", Type: listType(dateType())},
  1159. },
  1160. []*proto3.Value{{Kind: &proto3.Value_ListValue{}}},
  1161. },
  1162. &[]NullDate{},
  1163. errDecodeColumn(0, errNilListValue("DATE")),
  1164. },
  1165. {
  1166. // Field specifies ARRAY<DATE> type, but value is for FLOAT64 type.
  1167. &Row{
  1168. []*sppb.StructType_Field{
  1169. {Name: "Col0", Type: listType(dateType())},
  1170. },
  1171. []*proto3.Value{floatProto(1.0)},
  1172. },
  1173. &[]NullDate{},
  1174. errDecodeColumn(0, errSrcVal(floatProto(1.0), "List")),
  1175. },
  1176. {
  1177. // Field specifies ARRAY<DATE> type, but value is for ARRAY<FLOAT64> type.
  1178. &Row{
  1179. []*sppb.StructType_Field{
  1180. {Name: "Col0", Type: listType(dateType())},
  1181. },
  1182. []*proto3.Value{listProto(floatProto(1.0))},
  1183. },
  1184. &[]NullDate{},
  1185. errDecodeColumn(0, errDecodeArrayElement(0, floatProto(1.0),
  1186. "DATE", errSrcVal(floatProto(1.0), "String"))),
  1187. },
  1188. {
  1189. // Field specifies ARRAY<STRUCT> type, value is having a nil Kind.
  1190. &Row{
  1191. []*sppb.StructType_Field{
  1192. {Name: "Col0", Type: listType(structType(
  1193. mkField("Col1", intType()),
  1194. mkField("Col2", floatType()),
  1195. mkField("Col3", stringType()),
  1196. ))},
  1197. },
  1198. []*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}},
  1199. },
  1200. &[]*struct {
  1201. Col1 int64
  1202. Col2 float64
  1203. Col3 string
  1204. }{},
  1205. errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")),
  1206. },
  1207. {
  1208. // Field specifies ARRAY<STRUCT> type, value is having a nil ListValue.
  1209. &Row{
  1210. []*sppb.StructType_Field{
  1211. {Name: "Col0", Type: listType(structType(
  1212. mkField("Col1", intType()),
  1213. mkField("Col2", floatType()),
  1214. mkField("Col3", stringType()),
  1215. ))},
  1216. },
  1217. []*proto3.Value{{Kind: &proto3.Value_ListValue{}}},
  1218. },
  1219. &[]*struct {
  1220. Col1 int64
  1221. Col2 float64
  1222. Col3 string
  1223. }{},
  1224. errDecodeColumn(0, errNilListValue("STRUCT")),
  1225. },
  1226. {
  1227. // Field specifies ARRAY<STRUCT> type, value is having a nil ListValue.
  1228. &Row{
  1229. []*sppb.StructType_Field{
  1230. {
  1231. Name: "Col0",
  1232. Type: listType(
  1233. structType(
  1234. mkField("Col1", intType()),
  1235. mkField("Col2", floatType()),
  1236. mkField("Col3", stringType()),
  1237. ),
  1238. ),
  1239. },
  1240. },
  1241. []*proto3.Value{{Kind: &proto3.Value_ListValue{}}},
  1242. },
  1243. &[]NullRow{},
  1244. errDecodeColumn(0, errNilListValue("STRUCT")),
  1245. },
  1246. {
  1247. // Field specifies ARRAY<STRUCT> type, value is for BYTES type.
  1248. &Row{
  1249. []*sppb.StructType_Field{
  1250. {
  1251. Name: "Col0",
  1252. Type: listType(
  1253. structType(
  1254. mkField("Col1", intType()),
  1255. mkField("Col2", floatType()),
  1256. mkField("Col3", stringType()),
  1257. ),
  1258. ),
  1259. },
  1260. },
  1261. []*proto3.Value{bytesProto([]byte("value"))},
  1262. },
  1263. &[]*struct {
  1264. Col1 int64
  1265. Col2 float64
  1266. Col3 string
  1267. }{},
  1268. errDecodeColumn(0, errSrcVal(bytesProto([]byte("value")), "List")),
  1269. },
  1270. {
  1271. // Field specifies ARRAY<STRUCT> type, value is for BYTES type.
  1272. &Row{
  1273. []*sppb.StructType_Field{
  1274. {
  1275. Name: "Col0",
  1276. Type: listType(
  1277. structType(
  1278. mkField("Col1", intType()),
  1279. mkField("Col2", floatType()),
  1280. mkField("Col3", stringType()),
  1281. ),
  1282. ),
  1283. },
  1284. },
  1285. []*proto3.Value{listProto(bytesProto([]byte("value")))},
  1286. },
  1287. &[]NullRow{},
  1288. errDecodeColumn(0, errNotStructElement(0, bytesProto([]byte("value")))),
  1289. },
  1290. {
  1291. // Field specifies ARRAY<STRUCT> type, value is for ARRAY<BYTES> type.
  1292. &Row{
  1293. []*sppb.StructType_Field{
  1294. {
  1295. Name: "Col0",
  1296. Type: listType(
  1297. structType(
  1298. mkField("Col1", intType()),
  1299. mkField("Col2", floatType()),
  1300. mkField("Col3", stringType()),
  1301. ),
  1302. ),
  1303. },
  1304. },
  1305. []*proto3.Value{listProto(bytesProto([]byte("value")))},
  1306. },
  1307. &[]*struct {
  1308. Col1 int64
  1309. Col2 float64
  1310. Col3 string
  1311. }{},
  1312. errDecodeColumn(0, errDecodeArrayElement(0, bytesProto([]byte("value")),
  1313. "STRUCT", errSrcVal(bytesProto([]byte("value")), "List"))),
  1314. },
  1315. {
  1316. // Field specifies ARRAY<STRUCT>, but is having nil StructType.
  1317. &Row{
  1318. []*sppb.StructType_Field{
  1319. {
  1320. Name: "Col0", Type: listType(&sppb.Type{Code: sppb.TypeCode_STRUCT}),
  1321. },
  1322. },
  1323. []*proto3.Value{listProto(listProto(intProto(1), floatProto(2.0), stringProto("3")))},
  1324. },
  1325. &[]*struct {
  1326. Col1 int64
  1327. Col2 float64
  1328. Col3 string
  1329. }{},
  1330. errDecodeColumn(0, errDecodeArrayElement(0, listProto(intProto(1), floatProto(2.0), stringProto("3")),
  1331. "STRUCT", errNilSpannerStructType())),
  1332. },
  1333. {
  1334. // Field specifies ARRAY<STRUCT>, but the second struct value is for BOOL type instead of FLOAT64.
  1335. &Row{
  1336. []*sppb.StructType_Field{
  1337. {
  1338. Name: "Col0",
  1339. Type: listType(
  1340. structType(
  1341. mkField("Col1", intType()),
  1342. mkField("Col2", floatType()),
  1343. mkField("Col3", stringType()),
  1344. ),
  1345. ),
  1346. },
  1347. },
  1348. []*proto3.Value{listProto(listProto(intProto(1), boolProto(true), stringProto("3")))},
  1349. },
  1350. &[]*struct {
  1351. Col1 int64
  1352. Col2 float64
  1353. Col3 string
  1354. }{},
  1355. errDecodeColumn(
  1356. 0,
  1357. errDecodeArrayElement(
  1358. 0, listProto(intProto(1), boolProto(true), stringProto("3")), "STRUCT",
  1359. errDecodeStructField(
  1360. &sppb.StructType{
  1361. Fields: []*sppb.StructType_Field{
  1362. mkField("Col1", intType()),
  1363. mkField("Col2", floatType()),
  1364. mkField("Col3", stringType()),
  1365. },
  1366. },
  1367. "Col2",
  1368. errSrcVal(boolProto(true), "Number"),
  1369. ),
  1370. ),
  1371. ),
  1372. },
  1373. } {
  1374. if gotErr := test.row.Column(0, test.dst); !testEqual(gotErr, test.wantErr) {
  1375. t.Errorf("%v: test.row.Column(0) got error %v, want %v", i, gotErr, test.wantErr)
  1376. }
  1377. if gotErr := test.row.ColumnByName("Col0", test.dst); !testEqual(gotErr, test.wantErr) {
  1378. t.Errorf("%v: test.row.ColumnByName(%q) got error %v, want %v", i, "Col0", gotErr, test.wantErr)
  1379. }
  1380. if gotErr := test.row.Columns(test.dst); !testEqual(gotErr, test.wantErr) {
  1381. t.Errorf("%v: test.row.Columns(%T) got error %v, want %v", i, test.dst, gotErr, test.wantErr)
  1382. }
  1383. }
  1384. }
  1385. // Test Row.ToStruct().
  1386. func TestToStruct(t *testing.T) {
  1387. s := []struct {
  1388. // STRING / STRING ARRAY
  1389. PrimaryKey string `spanner:"STRING"`
  1390. NullString NullString `spanner:"NULL_STRING"`
  1391. StringArray []NullString `spanner:"STRING_ARRAY"`
  1392. NullStringArray []NullString `spanner:"NULL_STRING_ARRAY"`
  1393. // BYTES / BYTES ARRAY
  1394. Bytes []byte `spanner:"BYTES"`
  1395. NullBytes []byte `spanner:"NULL_BYTES"`
  1396. BytesArray [][]byte `spanner:"BYTES_ARRAY"`
  1397. NullBytesArray [][]byte `spanner:"NULL_BYTES_ARRAY"`
  1398. // INT64 / INT64 ARRAY
  1399. Int64 int64 `spanner:"INT64"`
  1400. NullInt64 NullInt64 `spanner:"NULL_INT64"`
  1401. Int64Array []NullInt64 `spanner:"INT64_ARRAY"`
  1402. NullInt64Array []NullInt64 `spanner:"NULL_INT64_ARRAY"`
  1403. // BOOL / BOOL ARRAY
  1404. Bool bool `spanner:"BOOL"`
  1405. NullBool NullBool `spanner:"NULL_BOOL"`
  1406. BoolArray []NullBool `spanner:"BOOL_ARRAY"`
  1407. NullBoolArray []NullBool `spanner:"NULL_BOOL_ARRAY"`
  1408. // FLOAT64 / FLOAT64 ARRAY
  1409. Float64 float64 `spanner:"FLOAT64"`
  1410. NullFloat64 NullFloat64 `spanner:"NULL_FLOAT64"`
  1411. Float64Array []NullFloat64 `spanner:"FLOAT64_ARRAY"`
  1412. NullFloat64Array []NullFloat64 `spanner:"NULL_FLOAT64_ARRAY"`
  1413. // TIMESTAMP / TIMESTAMP ARRAY
  1414. Timestamp time.Time `spanner:"TIMESTAMP"`
  1415. NullTimestamp NullTime `spanner:"NULL_TIMESTAMP"`
  1416. TimestampArray []NullTime `spanner:"TIMESTAMP_ARRAY"`
  1417. NullTimestampArray []NullTime `spanner:"NULL_TIMESTAMP_ARRAY"`
  1418. // DATE / DATE ARRAY
  1419. Date civil.Date `spanner:"DATE"`
  1420. NullDate NullDate `spanner:"NULL_DATE"`
  1421. DateArray []NullDate `spanner:"DATE_ARRAY"`
  1422. NullDateArray []NullDate `spanner:"NULL_DATE_ARRAY"`
  1423. // STRUCT ARRAY
  1424. StructArray []*struct {
  1425. Col1 int64
  1426. Col2 float64
  1427. Col3 string
  1428. } `spanner:"STRUCT_ARRAY"`
  1429. NullStructArray []*struct {
  1430. Col1 int64
  1431. Col2 float64
  1432. Col3 string
  1433. } `spanner:"NULL_STRUCT_ARRAY"`
  1434. }{
  1435. {}, // got
  1436. {
  1437. // STRING / STRING ARRAY
  1438. "value",
  1439. NullString{},
  1440. []NullString{{"value1", true}, {}, {"value3", true}},
  1441. []NullString(nil),
  1442. // BYTES / BYTES ARRAY
  1443. []byte("value"),
  1444. []byte(nil),
  1445. [][]byte{[]byte("value1"), nil, []byte("value3")},
  1446. [][]byte(nil),
  1447. // INT64 / INT64 ARRAY
  1448. int64(17),
  1449. NullInt64{},
  1450. []NullInt64{{int64(1), true}, {int64(2), true}, {}},
  1451. []NullInt64(nil),
  1452. // BOOL / BOOL ARRAY
  1453. true,
  1454. NullBool{},
  1455. []NullBool{{}, {true, true}, {false, true}},
  1456. []NullBool(nil),
  1457. // FLOAT64 / FLOAT64 ARRAY
  1458. 1.7,
  1459. NullFloat64{},
  1460. []NullFloat64{{}, {}, {1.7, true}},
  1461. []NullFloat64(nil),
  1462. // TIMESTAMP / TIMESTAMP ARRAY
  1463. tm,
  1464. NullTime{},
  1465. []NullTime{{}, {tm, true}},
  1466. []NullTime(nil),
  1467. // DATE / DATE ARRAY
  1468. dt,
  1469. NullDate{},
  1470. []NullDate{{}, {dt, true}},
  1471. []NullDate(nil),
  1472. // STRUCT ARRAY
  1473. []*struct {
  1474. Col1 int64
  1475. Col2 float64
  1476. Col3 string
  1477. }{
  1478. nil,
  1479. {3, 33.3, "three"},
  1480. nil,
  1481. },
  1482. []*struct {
  1483. Col1 int64
  1484. Col2 float64
  1485. Col3 string
  1486. }(nil),
  1487. }, // want
  1488. }
  1489. err := row.ToStruct(&s[0])
  1490. if err != nil {
  1491. t.Errorf("row.ToStruct() returns error: %v, want nil", err)
  1492. } else if !testEqual(s[0], s[1]) {
  1493. t.Errorf("row.ToStruct() fetches struct %v, want %v", s[0], s[1])
  1494. }
  1495. }
  1496. func TestToStructEmbedded(t *testing.T) {
  1497. type (
  1498. S1 struct{ F1 string }
  1499. S2 struct {
  1500. S1
  1501. F2 string
  1502. }
  1503. )
  1504. r := Row{
  1505. []*sppb.StructType_Field{
  1506. {Name: "F1", Type: stringType()},
  1507. {Name: "F2", Type: stringType()},
  1508. },
  1509. []*proto3.Value{
  1510. stringProto("v1"),
  1511. stringProto("v2"),
  1512. },
  1513. }
  1514. var got S2
  1515. if err := r.ToStruct(&got); err != nil {
  1516. t.Fatal(err)
  1517. }
  1518. want := S2{S1: S1{F1: "v1"}, F2: "v2"}
  1519. if !testEqual(got, want) {
  1520. t.Errorf("got %+v, want %+v", got, want)
  1521. }
  1522. }
  1523. // Test helpers for getting column names.
  1524. func TestColumnNameAndIndex(t *testing.T) {
  1525. // Test Row.Size().
  1526. if rs := row.Size(); rs != len(row.fields) {
  1527. t.Errorf("row.Size() returns %v, want %v", rs, len(row.fields))
  1528. }
  1529. // Test Row.Size() on empty Row.
  1530. if rs := (&Row{}).Size(); rs != 0 {
  1531. t.Errorf("empty_row.Size() returns %v, want %v", rs, 0)
  1532. }
  1533. // Test Row.ColumnName()
  1534. for i, col := range row.fields {
  1535. if cn := row.ColumnName(i); cn != col.Name {
  1536. t.Errorf("row.ColumnName(%v) returns %q, want %q", i, cn, col.Name)
  1537. }
  1538. goti, err := row.ColumnIndex(col.Name)
  1539. if err != nil {
  1540. t.Errorf("ColumnIndex(%q) error %v", col.Name, err)
  1541. continue
  1542. }
  1543. if goti != i {
  1544. t.Errorf("ColumnIndex(%q) = %d, want %d", col.Name, goti, i)
  1545. }
  1546. }
  1547. // Test Row.ColumnName on empty Row.
  1548. if cn := (&Row{}).ColumnName(0); cn != "" {
  1549. t.Errorf("empty_row.ColumnName(%v) returns %q, want %q", 0, cn, "")
  1550. }
  1551. // Test Row.ColumnIndex on empty Row.
  1552. if _, err := (&Row{}).ColumnIndex(""); err == nil {
  1553. t.Error("empty_row.ColumnIndex returns nil, want error")
  1554. }
  1555. }
  1556. func TestNewRow(t *testing.T) {
  1557. for _, test := range []struct {
  1558. names []string
  1559. values []interface{}
  1560. want *Row
  1561. wantErr error
  1562. }{
  1563. {
  1564. want: &Row{fields: []*sppb.StructType_Field{}, vals: []*proto3.Value{}},
  1565. },
  1566. {
  1567. names: []string{},
  1568. values: []interface{}{},
  1569. want: &Row{fields: []*sppb.StructType_Field{}, vals: []*proto3.Value{}},
  1570. },
  1571. {
  1572. names: []string{"a", "b"},
  1573. values: []interface{}{},
  1574. want: nil,
  1575. wantErr: errNamesValuesMismatch([]string{"a", "b"}, []interface{}{}),
  1576. },
  1577. {
  1578. names: []string{"a", "b", "c"},
  1579. values: []interface{}{5, "abc", GenericColumnValue{listType(intType()), listProto(intProto(91), nullProto(), intProto(87))}},
  1580. want: &Row{
  1581. []*sppb.StructType_Field{
  1582. {Name: "a", Type: intType()},
  1583. {Name: "b", Type: stringType()},
  1584. {Name: "c", Type: listType(intType())},
  1585. },
  1586. []*proto3.Value{
  1587. intProto(5),
  1588. stringProto("abc"),
  1589. listProto(intProto(91), nullProto(), intProto(87)),
  1590. },
  1591. },
  1592. },
  1593. } {
  1594. got, err := NewRow(test.names, test.values)
  1595. if !testEqual(err, test.wantErr) {
  1596. t.Errorf("NewRow(%v,%v).err = %s, want %s", test.names, test.values, err, test.wantErr)
  1597. continue
  1598. }
  1599. if !testEqual(got, test.want) {
  1600. t.Errorf("NewRow(%v,%v) = %s, want %s", test.names, test.values, got, test.want)
  1601. continue
  1602. }
  1603. }
  1604. }
  1605. func BenchmarkColumn(b *testing.B) {
  1606. var s string
  1607. for i := 0; i < b.N; i++ {
  1608. if err := row.Column(0, &s); err != nil {
  1609. b.Fatal(err)
  1610. }
  1611. }
  1612. }