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.
 
 
 

1396 lines
37 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. "math"
  16. "reflect"
  17. "testing"
  18. "time"
  19. "cloud.google.com/go/civil"
  20. "github.com/golang/protobuf/proto"
  21. proto3 "github.com/golang/protobuf/ptypes/struct"
  22. sppb "google.golang.org/genproto/googleapis/spanner/v1"
  23. )
  24. var (
  25. t1 = mustParseTime("2016-11-15T15:04:05.999999999Z")
  26. // Boundaries
  27. t2 = mustParseTime("0000-01-01T00:00:00.000000000Z")
  28. t3 = mustParseTime("9999-12-31T23:59:59.999999999Z")
  29. // Local timezone
  30. t4 = time.Now()
  31. d1 = mustParseDate("2016-11-15")
  32. d2 = mustParseDate("1678-01-01")
  33. )
  34. func mustParseTime(s string) time.Time {
  35. t, err := time.Parse(time.RFC3339Nano, s)
  36. if err != nil {
  37. panic(err)
  38. }
  39. return t
  40. }
  41. func mustParseDate(s string) civil.Date {
  42. d, err := civil.ParseDate(s)
  43. if err != nil {
  44. panic(err)
  45. }
  46. return d
  47. }
  48. // Test encoding Values.
  49. func TestEncodeValue(t *testing.T) {
  50. var (
  51. tString = stringType()
  52. tInt = intType()
  53. tBool = boolType()
  54. tFloat = floatType()
  55. tBytes = bytesType()
  56. tTime = timeType()
  57. tDate = dateType()
  58. )
  59. for i, test := range []struct {
  60. in interface{}
  61. want *proto3.Value
  62. wantType *sppb.Type
  63. }{
  64. // STRING / STRING ARRAY
  65. {"abc", stringProto("abc"), tString},
  66. {NullString{"abc", true}, stringProto("abc"), tString},
  67. {NullString{"abc", false}, nullProto(), tString},
  68. {[]string(nil), nullProto(), listType(tString)},
  69. {[]string{"abc", "bcd"}, listProto(stringProto("abc"), stringProto("bcd")), listType(tString)},
  70. {[]NullString{{"abcd", true}, {"xyz", false}}, listProto(stringProto("abcd"), nullProto()), listType(tString)},
  71. // BYTES / BYTES ARRAY
  72. {[]byte("foo"), bytesProto([]byte("foo")), tBytes},
  73. {[]byte(nil), nullProto(), tBytes},
  74. {[][]byte{nil, []byte("ab")}, listProto(nullProto(), bytesProto([]byte("ab"))), listType(tBytes)},
  75. {[][]byte(nil), nullProto(), listType(tBytes)},
  76. // INT64 / INT64 ARRAY
  77. {7, intProto(7), tInt},
  78. {[]int(nil), nullProto(), listType(tInt)},
  79. {[]int{31, 127}, listProto(intProto(31), intProto(127)), listType(tInt)},
  80. {int64(81), intProto(81), tInt},
  81. {[]int64(nil), nullProto(), listType(tInt)},
  82. {[]int64{33, 129}, listProto(intProto(33), intProto(129)), listType(tInt)},
  83. {NullInt64{11, true}, intProto(11), tInt},
  84. {NullInt64{11, false}, nullProto(), tInt},
  85. {[]NullInt64{{35, true}, {131, false}}, listProto(intProto(35), nullProto()), listType(tInt)},
  86. // BOOL / BOOL ARRAY
  87. {true, boolProto(true), tBool},
  88. {NullBool{true, true}, boolProto(true), tBool},
  89. {NullBool{true, false}, nullProto(), tBool},
  90. {[]bool{true, false}, listProto(boolProto(true), boolProto(false)), listType(tBool)},
  91. {[]NullBool{{true, true}, {true, false}}, listProto(boolProto(true), nullProto()), listType(tBool)},
  92. // FLOAT64 / FLOAT64 ARRAY
  93. {3.14, floatProto(3.14), tFloat},
  94. {NullFloat64{3.1415, true}, floatProto(3.1415), tFloat},
  95. {NullFloat64{math.Inf(1), true}, floatProto(math.Inf(1)), tFloat},
  96. {NullFloat64{3.14159, false}, nullProto(), tFloat},
  97. {[]float64(nil), nullProto(), listType(tFloat)},
  98. {[]float64{3.141, 0.618, math.Inf(-1)}, listProto(floatProto(3.141), floatProto(0.618), floatProto(math.Inf(-1))), listType(tFloat)},
  99. {[]NullFloat64{{3.141, true}, {0.618, false}}, listProto(floatProto(3.141), nullProto()), listType(tFloat)},
  100. // TIMESTAMP / TIMESTAMP ARRAY
  101. {t1, timeProto(t1), tTime},
  102. {NullTime{t1, true}, timeProto(t1), tTime},
  103. {NullTime{t1, false}, nullProto(), tTime},
  104. {[]time.Time(nil), nullProto(), listType(tTime)},
  105. {[]time.Time{t1, t2, t3, t4}, listProto(timeProto(t1), timeProto(t2), timeProto(t3), timeProto(t4)), listType(tTime)},
  106. {[]NullTime{{t1, true}, {t1, false}}, listProto(timeProto(t1), nullProto()), listType(tTime)},
  107. // DATE / DATE ARRAY
  108. {d1, dateProto(d1), tDate},
  109. {NullDate{d1, true}, dateProto(d1), tDate},
  110. {NullDate{civil.Date{}, false}, nullProto(), tDate},
  111. {[]civil.Date(nil), nullProto(), listType(tDate)},
  112. {[]civil.Date{d1, d2}, listProto(dateProto(d1), dateProto(d2)), listType(tDate)},
  113. {[]NullDate{{d1, true}, {civil.Date{}, false}}, listProto(dateProto(d1), nullProto()), listType(tDate)},
  114. // GenericColumnValue
  115. {GenericColumnValue{tString, stringProto("abc")}, stringProto("abc"), tString},
  116. {GenericColumnValue{tString, nullProto()}, nullProto(), tString},
  117. // not actually valid (stringProto inside int list), but demonstrates pass-through.
  118. {
  119. GenericColumnValue{
  120. Type: listType(tInt),
  121. Value: listProto(intProto(5), nullProto(), stringProto("bcd")),
  122. },
  123. listProto(intProto(5), nullProto(), stringProto("bcd")),
  124. listType(tInt),
  125. },
  126. // placeholder
  127. {CommitTimestamp, stringProto(commitTimestampPlaceholderString), tTime},
  128. } {
  129. got, gotType, err := encodeValue(test.in)
  130. if err != nil {
  131. t.Fatalf("#%d: got error during encoding: %v, want nil", i, err)
  132. }
  133. if !testEqual(got, test.want) {
  134. t.Errorf("#%d: got encode result: %v, want %v", i, got, test.want)
  135. }
  136. if !testEqual(gotType, test.wantType) {
  137. t.Errorf("#%d: got encode type: %v, want %v", i, gotType, test.wantType)
  138. }
  139. }
  140. }
  141. type encodeTest struct {
  142. desc string
  143. in interface{}
  144. want *proto3.Value
  145. wantType *sppb.Type
  146. }
  147. func checkStructEncoding(desc string, got *proto3.Value, gotType *sppb.Type,
  148. want *proto3.Value, wantType *sppb.Type, t *testing.T) {
  149. if !testEqual(got, want) {
  150. t.Errorf("Test %s: got encode result: %v, want %v", desc, got, want)
  151. }
  152. if !testEqual(gotType, wantType) {
  153. t.Errorf("Test %s: got encode type: %v, want %v", desc, gotType, wantType)
  154. }
  155. }
  156. // Testcase code
  157. func encodeStructValue(test encodeTest, t *testing.T) {
  158. got, gotType, err := encodeValue(test.in)
  159. if err != nil {
  160. t.Fatalf("Test %s: got error during encoding: %v, want nil", test.desc, err)
  161. }
  162. checkStructEncoding(test.desc, got, gotType, test.want, test.wantType, t)
  163. }
  164. func TestEncodeStructValuePointers(t *testing.T) {
  165. type structf struct {
  166. F int `spanner:"ff2"`
  167. }
  168. nestedStructProto := structType(mkField("ff2", intType()))
  169. type testType struct {
  170. Stringf string
  171. Structf *structf
  172. ArrStructf []*structf
  173. }
  174. testTypeProto := structType(
  175. mkField("Stringf", stringType()),
  176. mkField("Structf", nestedStructProto),
  177. mkField("ArrStructf", listType(nestedStructProto)))
  178. for _, test := range []encodeTest{
  179. {
  180. "Pointer to Go struct with pointers-to-(array)-struct fields.",
  181. &testType{"hello", &structf{50}, []*structf{{30}, {40}}},
  182. listProto(
  183. stringProto("hello"),
  184. listProto(intProto(50)),
  185. listProto(
  186. listProto(intProto(30)),
  187. listProto(intProto(40)))),
  188. testTypeProto,
  189. },
  190. {
  191. "Nil pointer to Go struct representing a NULL struct value.",
  192. (*testType)(nil),
  193. nullProto(),
  194. testTypeProto,
  195. },
  196. {
  197. "Slice of pointers to Go structs with NULL and non-NULL elements.",
  198. []*testType{
  199. (*testType)(nil),
  200. {"hello", nil, []*structf{nil, {40}}},
  201. {"world", &structf{70}, nil},
  202. },
  203. listProto(
  204. nullProto(),
  205. listProto(
  206. stringProto("hello"),
  207. nullProto(),
  208. listProto(nullProto(), listProto(intProto(40)))),
  209. listProto(
  210. stringProto("world"),
  211. listProto(intProto(70)),
  212. nullProto())),
  213. listType(testTypeProto),
  214. },
  215. {
  216. "Nil slice of pointers to structs representing a NULL array of structs.",
  217. []*testType(nil),
  218. nullProto(),
  219. listType(testTypeProto),
  220. },
  221. {
  222. "Empty slice of pointers to structs representing an empty array of structs.",
  223. []*testType{},
  224. listProto(),
  225. listType(testTypeProto),
  226. },
  227. } {
  228. encodeStructValue(test, t)
  229. }
  230. }
  231. func TestEncodeStructValueErrors(t *testing.T) {
  232. type Embedded struct {
  233. A int
  234. }
  235. type embedded struct {
  236. B bool
  237. }
  238. x := 0
  239. for _, test := range []struct {
  240. desc string
  241. in interface{}
  242. wantErr error
  243. }{
  244. {
  245. "Unsupported embedded fields.",
  246. struct{ Embedded }{Embedded{10}},
  247. errUnsupportedEmbeddedStructFields("Embedded"),
  248. },
  249. {
  250. "Unsupported pointer to embedded fields.",
  251. struct{ *Embedded }{&Embedded{10}},
  252. errUnsupportedEmbeddedStructFields("Embedded"),
  253. },
  254. {
  255. "Unsupported embedded + unexported fields.",
  256. struct {
  257. int
  258. *bool
  259. embedded
  260. }{10, nil, embedded{false}},
  261. errUnsupportedEmbeddedStructFields("int"),
  262. },
  263. {
  264. "Unsupported type.",
  265. (**struct{})(nil),
  266. errEncoderUnsupportedType((**struct{})(nil)),
  267. },
  268. {
  269. "Unsupported type.",
  270. 3,
  271. errEncoderUnsupportedType(3),
  272. },
  273. {
  274. "Unsupported type.",
  275. &x,
  276. errEncoderUnsupportedType(&x),
  277. },
  278. } {
  279. _, _, got := encodeStruct(test.in)
  280. if got == nil || !testEqual(test.wantErr, got) {
  281. t.Errorf("Test: %s, expected error %v during decoding, got %v", test.desc, test.wantErr, got)
  282. }
  283. }
  284. }
  285. func TestEncodeStructValueArrayStructFields(t *testing.T) {
  286. type structf struct {
  287. Intff int
  288. }
  289. structfType := structType(mkField("Intff", intType()))
  290. for _, test := range []encodeTest{
  291. {
  292. "Unnamed array-of-struct-typed field.",
  293. struct {
  294. Intf int
  295. ArrStructf []structf `spanner:""`
  296. }{10, []structf{{1}, {2}}},
  297. listProto(
  298. intProto(10),
  299. listProto(
  300. listProto(intProto(1)),
  301. listProto(intProto(2)))),
  302. structType(
  303. mkField("Intf", intType()),
  304. mkField("", listType(structfType))),
  305. },
  306. {
  307. "Null array-of-struct-typed field.",
  308. struct {
  309. Intf int
  310. ArrStructf []structf
  311. }{10, []structf(nil)},
  312. listProto(intProto(10), nullProto()),
  313. structType(
  314. mkField("Intf", intType()),
  315. mkField("ArrStructf", listType(structfType))),
  316. },
  317. {
  318. "Array-of-struct-typed field representing empty array.",
  319. struct {
  320. Intf int
  321. ArrStructf []structf
  322. }{10, []structf{}},
  323. listProto(intProto(10), listProto([]*proto3.Value{}...)),
  324. structType(
  325. mkField("Intf", intType()),
  326. mkField("ArrStructf", listType(structfType))),
  327. },
  328. {
  329. "Array-of-struct-typed field with nullable struct elements.",
  330. struct {
  331. Intf int
  332. ArrStructf []*structf
  333. }{
  334. 10,
  335. []*structf{(*structf)(nil), {1}},
  336. },
  337. listProto(
  338. intProto(10),
  339. listProto(
  340. nullProto(),
  341. listProto(intProto(1)))),
  342. structType(
  343. mkField("Intf", intType()),
  344. mkField("ArrStructf", listType(structfType))),
  345. },
  346. } {
  347. encodeStructValue(test, t)
  348. }
  349. }
  350. func TestEncodeStructValueStructFields(t *testing.T) {
  351. type structf struct {
  352. Intff int
  353. }
  354. structfType := structType(mkField("Intff", intType()))
  355. for _, test := range []encodeTest{
  356. {
  357. "Named struct-type field.",
  358. struct {
  359. Intf int
  360. Structf structf
  361. }{10, structf{10}},
  362. listProto(intProto(10), listProto(intProto(10))),
  363. structType(
  364. mkField("Intf", intType()),
  365. mkField("Structf", structfType)),
  366. },
  367. {
  368. "Unnamed struct-type field.",
  369. struct {
  370. Intf int
  371. Structf structf `spanner:""`
  372. }{10, structf{10}},
  373. listProto(intProto(10), listProto(intProto(10))),
  374. structType(
  375. mkField("Intf", intType()),
  376. mkField("", structfType)),
  377. },
  378. {
  379. "Duplicate struct-typed field.",
  380. struct {
  381. Structf1 structf `spanner:""`
  382. Structf2 structf `spanner:""`
  383. }{structf{10}, structf{20}},
  384. listProto(listProto(intProto(10)), listProto(intProto(20))),
  385. structType(
  386. mkField("", structfType),
  387. mkField("", structfType)),
  388. },
  389. {
  390. "Null struct-typed field.",
  391. struct {
  392. Intf int
  393. Structf *structf
  394. }{10, nil},
  395. listProto(intProto(10), nullProto()),
  396. structType(
  397. mkField("Intf", intType()),
  398. mkField("Structf", structfType)),
  399. },
  400. {
  401. "Empty struct-typed field.",
  402. struct {
  403. Intf int
  404. Structf struct{}
  405. }{10, struct{}{}},
  406. listProto(intProto(10), listProto([]*proto3.Value{}...)),
  407. structType(
  408. mkField("Intf", intType()),
  409. mkField("Structf", structType([]*sppb.StructType_Field{}...))),
  410. },
  411. } {
  412. encodeStructValue(test, t)
  413. }
  414. }
  415. func TestEncodeStructValueFieldNames(t *testing.T) {
  416. type embedded struct {
  417. B bool
  418. }
  419. for _, test := range []encodeTest{
  420. {
  421. "Duplicate fields.",
  422. struct {
  423. Field1 int `spanner:"field"`
  424. DupField1 int `spanner:"field"`
  425. }{10, 20},
  426. listProto(intProto(10), intProto(20)),
  427. structType(
  428. mkField("field", intType()),
  429. mkField("field", intType())),
  430. },
  431. {
  432. "Duplicate Fields (different types).",
  433. struct {
  434. IntField int `spanner:"field"`
  435. StringField string `spanner:"field"`
  436. }{10, "abc"},
  437. listProto(intProto(10), stringProto("abc")),
  438. structType(
  439. mkField("field", intType()),
  440. mkField("field", stringType())),
  441. },
  442. {
  443. "Duplicate unnamed fields.",
  444. struct {
  445. Dup int `spanner:""`
  446. Dup1 int `spanner:""`
  447. }{10, 20},
  448. listProto(intProto(10), intProto(20)),
  449. structType(
  450. mkField("", intType()),
  451. mkField("", intType())),
  452. },
  453. {
  454. "Named and unnamed fields.",
  455. struct {
  456. Field string
  457. Field1 int `spanner:""`
  458. Field2 string `spanner:"field"`
  459. }{"abc", 10, "def"},
  460. listProto(stringProto("abc"), intProto(10), stringProto("def")),
  461. structType(
  462. mkField("Field", stringType()),
  463. mkField("", intType()),
  464. mkField("field", stringType())),
  465. },
  466. {
  467. "Ignored unexported fields.",
  468. struct {
  469. Field int
  470. field bool
  471. Field1 string `spanner:"field"`
  472. }{10, false, "abc"},
  473. listProto(intProto(10), stringProto("abc")),
  474. structType(
  475. mkField("Field", intType()),
  476. mkField("field", stringType())),
  477. },
  478. {
  479. "Ignored unexported struct/slice fields.",
  480. struct {
  481. a []*embedded
  482. b []embedded
  483. c embedded
  484. d *embedded
  485. Field1 string `spanner:"field"`
  486. }{nil, nil, embedded{}, nil, "def"},
  487. listProto(stringProto("def")),
  488. structType(
  489. mkField("field", stringType())),
  490. },
  491. } {
  492. encodeStructValue(test, t)
  493. }
  494. }
  495. func TestEncodeStructValueBasicFields(t *testing.T) {
  496. StructTypeProto := structType(
  497. mkField("Stringf", stringType()),
  498. mkField("Intf", intType()),
  499. mkField("Boolf", boolType()),
  500. mkField("Floatf", floatType()),
  501. mkField("Bytef", bytesType()),
  502. mkField("Timef", timeType()),
  503. mkField("Datef", dateType()))
  504. for _, test := range []encodeTest{
  505. {
  506. "Basic types.",
  507. struct {
  508. Stringf string
  509. Intf int
  510. Boolf bool
  511. Floatf float64
  512. Bytef []byte
  513. Timef time.Time
  514. Datef civil.Date
  515. }{"abc", 300, false, 3.45, []byte("foo"), t1, d1},
  516. listProto(
  517. stringProto("abc"),
  518. intProto(300),
  519. boolProto(false),
  520. floatProto(3.45),
  521. bytesProto([]byte("foo")),
  522. timeProto(t1),
  523. dateProto(d1)),
  524. StructTypeProto,
  525. },
  526. {
  527. "Basic types null values.",
  528. struct {
  529. Stringf NullString
  530. Intf NullInt64
  531. Boolf NullBool
  532. Floatf NullFloat64
  533. Bytef []byte
  534. Timef NullTime
  535. Datef NullDate
  536. }{
  537. NullString{"abc", false},
  538. NullInt64{4, false},
  539. NullBool{false, false},
  540. NullFloat64{5.6, false},
  541. nil,
  542. NullTime{t1, false},
  543. NullDate{d1, false},
  544. },
  545. listProto(
  546. nullProto(),
  547. nullProto(),
  548. nullProto(),
  549. nullProto(),
  550. nullProto(),
  551. nullProto(),
  552. nullProto()),
  553. StructTypeProto,
  554. },
  555. } {
  556. encodeStructValue(test, t)
  557. }
  558. }
  559. func TestEncodeStructValueArrayFields(t *testing.T) {
  560. StructTypeProto := structType(
  561. mkField("Stringf", listType(stringType())),
  562. mkField("Intf", listType(intType())),
  563. mkField("Int64f", listType(intType())),
  564. mkField("Boolf", listType(boolType())),
  565. mkField("Floatf", listType(floatType())),
  566. mkField("Bytef", listType(bytesType())),
  567. mkField("Timef", listType(timeType())),
  568. mkField("Datef", listType(dateType())))
  569. for _, test := range []encodeTest{
  570. {
  571. "Arrays of basic types with non-nullable elements",
  572. struct {
  573. Stringf []string
  574. Intf []int
  575. Int64f []int64
  576. Boolf []bool
  577. Floatf []float64
  578. Bytef [][]byte
  579. Timef []time.Time
  580. Datef []civil.Date
  581. }{
  582. []string{"abc", "def"},
  583. []int{4, 67},
  584. []int64{5, 68},
  585. []bool{false, true},
  586. []float64{3.45, 0.93},
  587. [][]byte{[]byte("foo"), nil},
  588. []time.Time{t1, t2},
  589. []civil.Date{d1, d2},
  590. },
  591. listProto(
  592. listProto(stringProto("abc"), stringProto("def")),
  593. listProto(intProto(4), intProto(67)),
  594. listProto(intProto(5), intProto(68)),
  595. listProto(boolProto(false), boolProto(true)),
  596. listProto(floatProto(3.45), floatProto(0.93)),
  597. listProto(bytesProto([]byte("foo")), nullProto()),
  598. listProto(timeProto(t1), timeProto(t2)),
  599. listProto(dateProto(d1), dateProto(d2))),
  600. StructTypeProto,
  601. },
  602. {
  603. "Arrays of basic types with nullable elements.",
  604. struct {
  605. Stringf []NullString
  606. Intf []NullInt64
  607. Int64f []NullInt64
  608. Boolf []NullBool
  609. Floatf []NullFloat64
  610. Bytef [][]byte
  611. Timef []NullTime
  612. Datef []NullDate
  613. }{
  614. []NullString{{"abc", false}, {"def", true}},
  615. []NullInt64{{4, false}, {67, true}},
  616. []NullInt64{{5, false}, {68, true}},
  617. []NullBool{{true, false}, {false, true}},
  618. []NullFloat64{{3.45, false}, {0.93, true}},
  619. [][]byte{[]byte("foo"), nil},
  620. []NullTime{{t1, false}, {t2, true}},
  621. []NullDate{{d1, false}, {d2, true}},
  622. },
  623. listProto(
  624. listProto(nullProto(), stringProto("def")),
  625. listProto(nullProto(), intProto(67)),
  626. listProto(nullProto(), intProto(68)),
  627. listProto(nullProto(), boolProto(false)),
  628. listProto(nullProto(), floatProto(0.93)),
  629. listProto(bytesProto([]byte("foo")), nullProto()),
  630. listProto(nullProto(), timeProto(t2)),
  631. listProto(nullProto(), dateProto(d2))),
  632. StructTypeProto,
  633. },
  634. {
  635. "Null arrays of basic types.",
  636. struct {
  637. Stringf []NullString
  638. Intf []NullInt64
  639. Int64f []NullInt64
  640. Boolf []NullBool
  641. Floatf []NullFloat64
  642. Bytef [][]byte
  643. Timef []NullTime
  644. Datef []NullDate
  645. }{
  646. nil,
  647. nil,
  648. nil,
  649. nil,
  650. nil,
  651. nil,
  652. nil,
  653. nil,
  654. },
  655. listProto(
  656. nullProto(),
  657. nullProto(),
  658. nullProto(),
  659. nullProto(),
  660. nullProto(),
  661. nullProto(),
  662. nullProto(),
  663. nullProto()),
  664. StructTypeProto,
  665. },
  666. } {
  667. encodeStructValue(test, t)
  668. }
  669. }
  670. // Test decoding Values.
  671. func TestDecodeValue(t *testing.T) {
  672. for i, test := range []struct {
  673. in *proto3.Value
  674. t *sppb.Type
  675. want interface{}
  676. fail bool
  677. }{
  678. // STRING
  679. {stringProto("abc"), stringType(), "abc", false},
  680. {nullProto(), stringType(), "abc", true},
  681. {stringProto("abc"), stringType(), NullString{"abc", true}, false},
  682. {nullProto(), stringType(), NullString{}, false},
  683. // STRING ARRAY with []NullString
  684. {
  685. listProto(stringProto("abc"), nullProto(), stringProto("bcd")),
  686. listType(stringType()),
  687. []NullString{{"abc", true}, {}, {"bcd", true}},
  688. false,
  689. },
  690. {nullProto(), listType(stringType()), []NullString(nil), false},
  691. // STRING ARRAY with []string
  692. {
  693. listProto(stringProto("abc"), stringProto("bcd")),
  694. listType(stringType()),
  695. []string{"abc", "bcd"},
  696. false,
  697. },
  698. // BYTES
  699. {bytesProto([]byte("ab")), bytesType(), []byte("ab"), false},
  700. {nullProto(), bytesType(), []byte(nil), false},
  701. // BYTES ARRAY
  702. {listProto(bytesProto([]byte("ab")), nullProto()), listType(bytesType()), [][]byte{[]byte("ab"), nil}, false},
  703. {nullProto(), listType(bytesType()), [][]byte(nil), false},
  704. //INT64
  705. {intProto(15), intType(), int64(15), false},
  706. {nullProto(), intType(), int64(0), true},
  707. {intProto(15), intType(), NullInt64{15, true}, false},
  708. {nullProto(), intType(), NullInt64{}, false},
  709. // INT64 ARRAY with []NullInt64
  710. {listProto(intProto(91), nullProto(), intProto(87)), listType(intType()), []NullInt64{{91, true}, {}, {87, true}}, false},
  711. {nullProto(), listType(intType()), []NullInt64(nil), false},
  712. // INT64 ARRAY with []int64
  713. {listProto(intProto(91), intProto(87)), listType(intType()), []int64{91, 87}, false},
  714. // BOOL
  715. {boolProto(true), boolType(), true, false},
  716. {nullProto(), boolType(), true, true},
  717. {boolProto(true), boolType(), NullBool{true, true}, false},
  718. {nullProto(), boolType(), NullBool{}, false},
  719. // BOOL ARRAY with []NullBool
  720. {listProto(boolProto(true), boolProto(false), nullProto()), listType(boolType()), []NullBool{{true, true}, {false, true}, {}}, false},
  721. {nullProto(), listType(boolType()), []NullBool(nil), false},
  722. // BOOL ARRAY with []bool
  723. {listProto(boolProto(true), boolProto(false)), listType(boolType()), []bool{true, false}, false},
  724. // FLOAT64
  725. {floatProto(3.14), floatType(), 3.14, false},
  726. {nullProto(), floatType(), 0.00, true},
  727. {floatProto(3.14), floatType(), NullFloat64{3.14, true}, false},
  728. {nullProto(), floatType(), NullFloat64{}, false},
  729. // FLOAT64 ARRAY with []NullFloat64
  730. {
  731. listProto(floatProto(math.Inf(1)), floatProto(math.Inf(-1)), nullProto(), floatProto(3.1)),
  732. listType(floatType()),
  733. []NullFloat64{{math.Inf(1), true}, {math.Inf(-1), true}, {}, {3.1, true}},
  734. false,
  735. },
  736. {nullProto(), listType(floatType()), []NullFloat64(nil), false},
  737. // FLOAT64 ARRAY with []float64
  738. {
  739. listProto(floatProto(math.Inf(1)), floatProto(math.Inf(-1)), floatProto(3.1)),
  740. listType(floatType()),
  741. []float64{math.Inf(1), math.Inf(-1), 3.1},
  742. false,
  743. },
  744. // TIMESTAMP
  745. {timeProto(t1), timeType(), t1, false},
  746. {timeProto(t1), timeType(), NullTime{t1, true}, false},
  747. {nullProto(), timeType(), NullTime{}, false},
  748. // TIMESTAMP ARRAY with []NullTime
  749. {listProto(timeProto(t1), timeProto(t2), timeProto(t3), nullProto()), listType(timeType()), []NullTime{{t1, true}, {t2, true}, {t3, true}, {}}, false},
  750. {nullProto(), listType(timeType()), []NullTime(nil), false},
  751. // TIMESTAMP ARRAY with []time.Time
  752. {listProto(timeProto(t1), timeProto(t2), timeProto(t3)), listType(timeType()), []time.Time{t1, t2, t3}, false},
  753. // DATE
  754. {dateProto(d1), dateType(), d1, false},
  755. {dateProto(d1), dateType(), NullDate{d1, true}, false},
  756. {nullProto(), dateType(), NullDate{}, false},
  757. // DATE ARRAY with []NullDate
  758. {listProto(dateProto(d1), dateProto(d2), nullProto()), listType(dateType()), []NullDate{{d1, true}, {d2, true}, {}}, false},
  759. {nullProto(), listType(dateType()), []NullDate(nil), false},
  760. // DATE ARRAY with []civil.Date
  761. {listProto(dateProto(d1), dateProto(d2)), listType(dateType()), []civil.Date{d1, d2}, false},
  762. // STRUCT ARRAY
  763. // STRUCT schema is equal to the following Go struct:
  764. // type s struct {
  765. // Col1 NullInt64
  766. // Col2 []struct {
  767. // SubCol1 float64
  768. // SubCol2 string
  769. // }
  770. // }
  771. {
  772. in: listProto(
  773. listProto(
  774. intProto(3),
  775. listProto(
  776. listProto(floatProto(3.14), stringProto("this")),
  777. listProto(floatProto(0.57), stringProto("siht")),
  778. ),
  779. ),
  780. listProto(
  781. nullProto(),
  782. nullProto(),
  783. ),
  784. nullProto(),
  785. ),
  786. t: listType(
  787. structType(
  788. mkField("Col1", intType()),
  789. mkField(
  790. "Col2",
  791. listType(
  792. structType(
  793. mkField("SubCol1", floatType()),
  794. mkField("SubCol2", stringType()),
  795. ),
  796. ),
  797. ),
  798. ),
  799. ),
  800. want: []NullRow{
  801. {
  802. Row: Row{
  803. fields: []*sppb.StructType_Field{
  804. mkField("Col1", intType()),
  805. mkField(
  806. "Col2",
  807. listType(
  808. structType(
  809. mkField("SubCol1", floatType()),
  810. mkField("SubCol2", stringType()),
  811. ),
  812. ),
  813. ),
  814. },
  815. vals: []*proto3.Value{
  816. intProto(3),
  817. listProto(
  818. listProto(floatProto(3.14), stringProto("this")),
  819. listProto(floatProto(0.57), stringProto("siht")),
  820. ),
  821. },
  822. },
  823. Valid: true,
  824. },
  825. {
  826. Row: Row{
  827. fields: []*sppb.StructType_Field{
  828. mkField("Col1", intType()),
  829. mkField(
  830. "Col2",
  831. listType(
  832. structType(
  833. mkField("SubCol1", floatType()),
  834. mkField("SubCol2", stringType()),
  835. ),
  836. ),
  837. ),
  838. },
  839. vals: []*proto3.Value{
  840. nullProto(),
  841. nullProto(),
  842. },
  843. },
  844. Valid: true,
  845. },
  846. {},
  847. },
  848. fail: false,
  849. },
  850. {
  851. in: listProto(
  852. listProto(
  853. intProto(3),
  854. listProto(
  855. listProto(floatProto(3.14), stringProto("this")),
  856. listProto(floatProto(0.57), stringProto("siht")),
  857. ),
  858. ),
  859. listProto(
  860. nullProto(),
  861. nullProto(),
  862. ),
  863. nullProto(),
  864. ),
  865. t: listType(
  866. structType(
  867. mkField("Col1", intType()),
  868. mkField(
  869. "Col2",
  870. listType(
  871. structType(
  872. mkField("SubCol1", floatType()),
  873. mkField("SubCol2", stringType()),
  874. ),
  875. ),
  876. ),
  877. ),
  878. ),
  879. want: []*struct {
  880. Col1 NullInt64
  881. StructCol []*struct {
  882. SubCol1 NullFloat64
  883. SubCol2 string
  884. } `spanner:"Col2"`
  885. }{
  886. {
  887. Col1: NullInt64{3, true},
  888. StructCol: []*struct {
  889. SubCol1 NullFloat64
  890. SubCol2 string
  891. }{
  892. {
  893. SubCol1: NullFloat64{3.14, true},
  894. SubCol2: "this",
  895. },
  896. {
  897. SubCol1: NullFloat64{0.57, true},
  898. SubCol2: "siht",
  899. },
  900. },
  901. },
  902. {
  903. Col1: NullInt64{},
  904. StructCol: []*struct {
  905. SubCol1 NullFloat64
  906. SubCol2 string
  907. }(nil),
  908. },
  909. nil,
  910. },
  911. fail: false,
  912. },
  913. // GenericColumnValue
  914. {stringProto("abc"), stringType(), GenericColumnValue{stringType(), stringProto("abc")}, false},
  915. {nullProto(), stringType(), GenericColumnValue{stringType(), nullProto()}, false},
  916. // not actually valid (stringProto inside int list), but demonstrates pass-through.
  917. {
  918. in: listProto(intProto(5), nullProto(), stringProto("bcd")),
  919. t: listType(intType()),
  920. want: GenericColumnValue{
  921. Type: listType(intType()),
  922. Value: listProto(intProto(5), nullProto(), stringProto("bcd")),
  923. },
  924. fail: false,
  925. },
  926. } {
  927. gotp := reflect.New(reflect.TypeOf(test.want))
  928. if err := decodeValue(test.in, test.t, gotp.Interface()); err != nil {
  929. if !test.fail {
  930. t.Errorf("%d: cannot decode %v(%v): %v", i, test.in, test.t, err)
  931. }
  932. continue
  933. }
  934. if test.fail {
  935. t.Errorf("%d: decoding %v(%v) succeeds unexpectedly, want error", i, test.in, test.t)
  936. continue
  937. }
  938. got := reflect.Indirect(gotp).Interface()
  939. if !testEqual(got, test.want) {
  940. t.Errorf("%d: unexpected decoding result - got %v, want %v", i, got, test.want)
  941. continue
  942. }
  943. }
  944. }
  945. // Test error cases for decodeValue.
  946. func TestDecodeValueErrors(t *testing.T) {
  947. var s string
  948. for i, test := range []struct {
  949. in *proto3.Value
  950. t *sppb.Type
  951. v interface{}
  952. }{
  953. {nullProto(), stringType(), nil},
  954. {nullProto(), stringType(), 1},
  955. {timeProto(t1), timeType(), &s},
  956. } {
  957. err := decodeValue(test.in, test.t, test.v)
  958. if err == nil {
  959. t.Errorf("#%d: want error, got nil", i)
  960. }
  961. }
  962. }
  963. // Test NaN encoding/decoding.
  964. func TestNaN(t *testing.T) {
  965. // Decode NaN value.
  966. f := 0.0
  967. nf := NullFloat64{}
  968. // To float64
  969. if err := decodeValue(floatProto(math.NaN()), floatType(), &f); err != nil {
  970. t.Errorf("decodeValue returns %q for %v, want nil", err, floatProto(math.NaN()))
  971. }
  972. if !math.IsNaN(f) {
  973. t.Errorf("f = %v, want %v", f, math.NaN())
  974. }
  975. // To NullFloat64
  976. if err := decodeValue(floatProto(math.NaN()), floatType(), &nf); err != nil {
  977. t.Errorf("decodeValue returns %q for %v, want nil", err, floatProto(math.NaN()))
  978. }
  979. if !math.IsNaN(nf.Float64) || !nf.Valid {
  980. t.Errorf("f = %v, want %v", f, NullFloat64{math.NaN(), true})
  981. }
  982. // Encode NaN value
  983. // From float64
  984. v, _, err := encodeValue(math.NaN())
  985. if err != nil {
  986. t.Errorf("encodeValue returns %q for NaN, want nil", err)
  987. }
  988. x, ok := v.GetKind().(*proto3.Value_NumberValue)
  989. if !ok {
  990. t.Errorf("incorrect type for v.GetKind(): %T, want *proto3.Value_NumberValue", v.GetKind())
  991. }
  992. if !math.IsNaN(x.NumberValue) {
  993. t.Errorf("x.NumberValue = %v, want %v", x.NumberValue, math.NaN())
  994. }
  995. // From NullFloat64
  996. v, _, err = encodeValue(NullFloat64{math.NaN(), true})
  997. if err != nil {
  998. t.Errorf("encodeValue returns %q for NaN, want nil", err)
  999. }
  1000. x, ok = v.GetKind().(*proto3.Value_NumberValue)
  1001. if !ok {
  1002. t.Errorf("incorrect type for v.GetKind(): %T, want *proto3.Value_NumberValue", v.GetKind())
  1003. }
  1004. if !math.IsNaN(x.NumberValue) {
  1005. t.Errorf("x.NumberValue = %v, want %v", x.NumberValue, math.NaN())
  1006. }
  1007. }
  1008. func TestGenericColumnValue(t *testing.T) {
  1009. for _, test := range []struct {
  1010. in GenericColumnValue
  1011. want interface{}
  1012. fail bool
  1013. }{
  1014. {GenericColumnValue{stringType(), stringProto("abc")}, "abc", false},
  1015. {GenericColumnValue{stringType(), stringProto("abc")}, 5, true},
  1016. {GenericColumnValue{listType(intType()), listProto(intProto(91), nullProto(), intProto(87))}, []NullInt64{{91, true}, {}, {87, true}}, false},
  1017. {GenericColumnValue{intType(), intProto(42)}, GenericColumnValue{intType(), intProto(42)}, false}, // trippy! :-)
  1018. } {
  1019. gotp := reflect.New(reflect.TypeOf(test.want))
  1020. if err := test.in.Decode(gotp.Interface()); err != nil {
  1021. if !test.fail {
  1022. t.Errorf("cannot decode %v to %v: %v", test.in, test.want, err)
  1023. }
  1024. continue
  1025. }
  1026. if test.fail {
  1027. t.Errorf("decoding %v to %v succeeds unexpectedly", test.in, test.want)
  1028. }
  1029. // Test we can go backwards as well.
  1030. v, err := newGenericColumnValue(test.want)
  1031. if err != nil {
  1032. t.Errorf("NewGenericColumnValue failed: %v", err)
  1033. continue
  1034. }
  1035. if !testEqual(*v, test.in) {
  1036. t.Errorf("unexpected encode result - got %v, want %v", v, test.in)
  1037. }
  1038. }
  1039. }
  1040. func TestDecodeStruct(t *testing.T) {
  1041. stype := &sppb.StructType{Fields: []*sppb.StructType_Field{
  1042. {Name: "Id", Type: stringType()},
  1043. {Name: "Time", Type: timeType()},
  1044. }}
  1045. lv := listValueProto(stringProto("id"), timeProto(t1))
  1046. type (
  1047. S1 struct {
  1048. ID string
  1049. Time time.Time
  1050. }
  1051. S2 struct {
  1052. ID string
  1053. Time string
  1054. }
  1055. )
  1056. var (
  1057. s1 S1
  1058. s2 S2
  1059. )
  1060. for i, test := range []struct {
  1061. ptr interface{}
  1062. want interface{}
  1063. fail bool
  1064. }{
  1065. {
  1066. ptr: &s1,
  1067. want: &S1{ID: "id", Time: t1},
  1068. },
  1069. {
  1070. ptr: &s2,
  1071. fail: true,
  1072. },
  1073. } {
  1074. err := decodeStruct(stype, lv, test.ptr)
  1075. if (err != nil) != test.fail {
  1076. t.Errorf("#%d: got error %v, wanted fail: %v", i, err, test.fail)
  1077. }
  1078. if err == nil && !testEqual(test.ptr, test.want) {
  1079. t.Errorf("#%d: got %+v, want %+v", i, test.ptr, test.want)
  1080. }
  1081. }
  1082. }
  1083. func TestEncodeStructValueDynamicStructs(t *testing.T) {
  1084. dynStructType := reflect.StructOf([]reflect.StructField{
  1085. {Name: "A", Type: reflect.TypeOf(0), Tag: `spanner:"a"`},
  1086. {Name: "B", Type: reflect.TypeOf(""), Tag: `spanner:"b"`},
  1087. })
  1088. dynNullableStructType := reflect.PtrTo(dynStructType)
  1089. dynStructArrType := reflect.SliceOf(dynStructType)
  1090. dynNullableStructArrType := reflect.SliceOf(dynNullableStructType)
  1091. dynStructValue := reflect.New(dynStructType)
  1092. dynStructValue.Elem().Field(0).SetInt(10)
  1093. dynStructValue.Elem().Field(1).SetString("abc")
  1094. dynStructArrValue := reflect.MakeSlice(dynNullableStructArrType, 2, 2)
  1095. dynStructArrValue.Index(0).Set(reflect.Zero(dynNullableStructType))
  1096. dynStructArrValue.Index(1).Set(dynStructValue)
  1097. structProtoType := structType(
  1098. mkField("a", intType()),
  1099. mkField("b", stringType()))
  1100. arrProtoType := listType(structProtoType)
  1101. for _, test := range []encodeTest{
  1102. {
  1103. "Dynanic non-NULL struct value.",
  1104. dynStructValue.Elem().Interface(),
  1105. listProto(intProto(10), stringProto("abc")),
  1106. structProtoType,
  1107. },
  1108. {
  1109. "Dynanic NULL struct value.",
  1110. reflect.Zero(dynNullableStructType).Interface(),
  1111. nullProto(),
  1112. structProtoType,
  1113. },
  1114. {
  1115. "Empty array of dynamic structs.",
  1116. reflect.MakeSlice(dynStructArrType, 0, 0).Interface(),
  1117. listProto([]*proto3.Value{}...),
  1118. arrProtoType,
  1119. },
  1120. {
  1121. "NULL array of non-NULL-able dynamic structs.",
  1122. reflect.Zero(dynStructArrType).Interface(),
  1123. nullProto(),
  1124. arrProtoType,
  1125. },
  1126. {
  1127. "NULL array of NULL-able(nil) dynamic structs.",
  1128. reflect.Zero(dynNullableStructArrType).Interface(),
  1129. nullProto(),
  1130. arrProtoType,
  1131. },
  1132. {
  1133. "Array containing NULL(nil) dynamic-typed struct elements.",
  1134. dynStructArrValue.Interface(),
  1135. listProto(
  1136. nullProto(),
  1137. listProto(intProto(10), stringProto("abc"))),
  1138. arrProtoType,
  1139. },
  1140. } {
  1141. encodeStructValue(test, t)
  1142. }
  1143. }
  1144. func TestEncodeStructValueEmptyStruct(t *testing.T) {
  1145. emptyListValue := listProto([]*proto3.Value{}...)
  1146. emptyStructType := structType([]*sppb.StructType_Field{}...)
  1147. emptyStruct := struct{}{}
  1148. nullEmptyStruct := (*struct{})(nil)
  1149. dynamicEmptyStructType := reflect.StructOf(make([]reflect.StructField, 0, 0))
  1150. dynamicStructArrType := reflect.SliceOf(reflect.PtrTo((dynamicEmptyStructType)))
  1151. dynamicEmptyStruct := reflect.New(dynamicEmptyStructType)
  1152. dynamicNullEmptyStruct := reflect.Zero(reflect.PtrTo(dynamicEmptyStructType))
  1153. dynamicStructArrValue := reflect.MakeSlice(dynamicStructArrType, 2, 2)
  1154. dynamicStructArrValue.Index(0).Set(dynamicNullEmptyStruct)
  1155. dynamicStructArrValue.Index(1).Set(dynamicEmptyStruct)
  1156. for _, test := range []encodeTest{
  1157. {
  1158. "Go empty struct.",
  1159. emptyStruct,
  1160. emptyListValue,
  1161. emptyStructType,
  1162. },
  1163. {
  1164. "Dynamic empty struct.",
  1165. dynamicEmptyStruct.Interface(),
  1166. emptyListValue,
  1167. emptyStructType,
  1168. },
  1169. {
  1170. "Go NULL empty struct.",
  1171. nullEmptyStruct,
  1172. nullProto(),
  1173. emptyStructType,
  1174. },
  1175. {
  1176. "Dynamic NULL empty struct.",
  1177. dynamicNullEmptyStruct.Interface(),
  1178. nullProto(),
  1179. emptyStructType,
  1180. },
  1181. {
  1182. "Non-empty array of dynamic NULL and non-NULL empty structs.",
  1183. dynamicStructArrValue.Interface(),
  1184. listProto(nullProto(), emptyListValue),
  1185. listType(emptyStructType),
  1186. },
  1187. {
  1188. "Non-empty array of nullable empty structs.",
  1189. []*struct{}{nullEmptyStruct, &emptyStruct},
  1190. listProto(nullProto(), emptyListValue),
  1191. listType(emptyStructType),
  1192. },
  1193. {
  1194. "Empty array of empty struct.",
  1195. []struct{}{},
  1196. emptyListValue,
  1197. listType(emptyStructType),
  1198. },
  1199. {
  1200. "Null array of empty structs.",
  1201. []struct{}(nil),
  1202. nullProto(),
  1203. listType(emptyStructType),
  1204. },
  1205. } {
  1206. encodeStructValue(test, t)
  1207. }
  1208. }
  1209. func TestEncodeStructValueMixedStructTypes(t *testing.T) {
  1210. type staticStruct struct {
  1211. F int `spanner:"fStatic"`
  1212. }
  1213. s1 := staticStruct{10}
  1214. s2 := (*staticStruct)(nil)
  1215. var f float64
  1216. dynStructType := reflect.StructOf([]reflect.StructField{
  1217. {Name: "A", Type: reflect.TypeOf(f), Tag: `spanner:"fDynamic"`},
  1218. })
  1219. s3 := reflect.New(dynStructType)
  1220. s3.Elem().Field(0).SetFloat(3.14)
  1221. for _, test := range []encodeTest{
  1222. {
  1223. "'struct' with static and dynamic *struct, []*struct, []struct fields",
  1224. struct {
  1225. A []staticStruct
  1226. B []*staticStruct
  1227. C interface{}
  1228. }{
  1229. []staticStruct{s1, s1},
  1230. []*staticStruct{&s1, s2},
  1231. s3.Interface(),
  1232. },
  1233. listProto(
  1234. listProto(listProto(intProto(10)), listProto(intProto(10))),
  1235. listProto(listProto(intProto(10)), nullProto()),
  1236. listProto(floatProto(3.14))),
  1237. structType(
  1238. mkField("A", listType(structType(mkField("fStatic", intType())))),
  1239. mkField("B", listType(structType(mkField("fStatic", intType())))),
  1240. mkField("C", structType(mkField("fDynamic", floatType())))),
  1241. },
  1242. } {
  1243. encodeStructValue(test, t)
  1244. }
  1245. }
  1246. func TestBindParamsDynamic(t *testing.T) {
  1247. // Verify Statement.bindParams generates correct values and types.
  1248. st := Statement{
  1249. SQL: "SELECT id from t_foo WHERE col = @var",
  1250. Params: map[string]interface{}{"var": nil},
  1251. }
  1252. want := &sppb.ExecuteSqlRequest{
  1253. Params: &proto3.Struct{
  1254. Fields: map[string]*proto3.Value{"var": nil},
  1255. },
  1256. ParamTypes: map[string]*sppb.Type{"var": nil},
  1257. }
  1258. var (
  1259. t1, _ = time.Parse(time.RFC3339Nano, "2016-11-15T15:04:05.999999999Z")
  1260. // Boundaries
  1261. t2, _ = time.Parse(time.RFC3339Nano, "0001-01-01T00:00:00.000000000Z")
  1262. )
  1263. dynamicStructType := reflect.StructOf([]reflect.StructField{
  1264. {Name: "A", Type: reflect.TypeOf(t1), Tag: `spanner:"field"`},
  1265. {Name: "B", Type: reflect.TypeOf(3.14), Tag: `spanner:""`},
  1266. })
  1267. dynamicStructArrType := reflect.SliceOf(reflect.PtrTo(dynamicStructType))
  1268. dynamicEmptyStructType := reflect.StructOf(make([]reflect.StructField, 0, 0))
  1269. dynamicStructTypeProto := structType(
  1270. mkField("field", timeType()),
  1271. mkField("", floatType()))
  1272. s3 := reflect.New(dynamicStructType)
  1273. s3.Elem().Field(0).Set(reflect.ValueOf(t1))
  1274. s3.Elem().Field(1).SetFloat(1.4)
  1275. s4 := reflect.New(dynamicStructType)
  1276. s4.Elem().Field(0).Set(reflect.ValueOf(t2))
  1277. s4.Elem().Field(1).SetFloat(-13.3)
  1278. dynamicStructArrayVal := reflect.MakeSlice(dynamicStructArrType, 2, 2)
  1279. dynamicStructArrayVal.Index(0).Set(s3)
  1280. dynamicStructArrayVal.Index(1).Set(s4)
  1281. for _, test := range []struct {
  1282. val interface{}
  1283. wantField *proto3.Value
  1284. wantType *sppb.Type
  1285. }{
  1286. {
  1287. s3.Interface(),
  1288. listProto(timeProto(t1), floatProto(1.4)),
  1289. structType(
  1290. mkField("field", timeType()),
  1291. mkField("", floatType())),
  1292. },
  1293. {
  1294. reflect.Zero(reflect.PtrTo(dynamicEmptyStructType)).Interface(),
  1295. nullProto(),
  1296. structType([]*sppb.StructType_Field{}...),
  1297. },
  1298. {
  1299. dynamicStructArrayVal.Interface(),
  1300. listProto(
  1301. listProto(timeProto(t1), floatProto(1.4)),
  1302. listProto(timeProto(t2), floatProto(-13.3))),
  1303. listType(dynamicStructTypeProto),
  1304. },
  1305. {
  1306. []*struct {
  1307. F1 time.Time `spanner:"field"`
  1308. F2 float64 `spanner:""`
  1309. }{
  1310. nil,
  1311. {t1, 1.4},
  1312. },
  1313. listProto(
  1314. nullProto(),
  1315. listProto(timeProto(t1), floatProto(1.4))),
  1316. listType(dynamicStructTypeProto),
  1317. },
  1318. } {
  1319. st.Params["var"] = test.val
  1320. want.Params.Fields["var"] = test.wantField
  1321. want.ParamTypes["var"] = test.wantType
  1322. gotParams, gotParamTypes, gotErr := st.convertParams()
  1323. if gotErr != nil {
  1324. t.Error(gotErr)
  1325. continue
  1326. }
  1327. gotParamField := gotParams.Fields["var"]
  1328. if !proto.Equal(gotParamField, test.wantField) {
  1329. // handle NaN
  1330. if test.wantType.Code == floatType().Code && proto.MarshalTextString(gotParamField) == proto.MarshalTextString(test.wantField) {
  1331. continue
  1332. }
  1333. t.Errorf("%#v: got %v, want %v\n", test.val, gotParamField, test.wantField)
  1334. }
  1335. gotParamType := gotParamTypes["var"]
  1336. if !proto.Equal(gotParamType, test.wantType) {
  1337. t.Errorf("%#v: got %v, want %v\n", test.val, gotParamType, test.wantField)
  1338. }
  1339. }
  1340. }