integration_test.go 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321
  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. "context"
  16. "errors"
  17. "flag"
  18. "fmt"
  19. "log"
  20. "math"
  21. "os"
  22. "reflect"
  23. "strings"
  24. "sync"
  25. "testing"
  26. "time"
  27. "cloud.google.com/go/civil"
  28. "cloud.google.com/go/internal/testutil"
  29. "cloud.google.com/go/internal/uid"
  30. database "cloud.google.com/go/spanner/admin/database/apiv1"
  31. "google.golang.org/api/iterator"
  32. "google.golang.org/api/option"
  33. adminpb "google.golang.org/genproto/googleapis/spanner/admin/database/v1"
  34. "google.golang.org/grpc/codes"
  35. )
  36. var (
  37. // testProjectID specifies the project used for testing.
  38. // It can be changed by setting environment variable GCLOUD_TESTS_GOLANG_PROJECT_ID.
  39. testProjectID = testutil.ProjID()
  40. dbNameSpace = uid.NewSpace("gotest", &uid.Options{Sep: '_', Short: true})
  41. // TODO(deklerk) When we can programmatically create instances, we should use
  42. // uid.New as the test instance name.
  43. // testInstanceID specifies the Cloud Spanner instance used for testing.
  44. testInstanceID = "go-integration-test"
  45. testTable = "TestTable"
  46. testTableIndex = "TestTableByValue"
  47. testTableColumns = []string{"Key", "StringValue"}
  48. // admin is a spanner.DatabaseAdminClient.
  49. admin *database.DatabaseAdminClient
  50. singerDBStatements = []string{
  51. `CREATE TABLE Singers (
  52. SingerId INT64 NOT NULL,
  53. FirstName STRING(1024),
  54. LastName STRING(1024),
  55. SingerInfo BYTES(MAX)
  56. ) PRIMARY KEY (SingerId)`,
  57. `CREATE INDEX SingerByName ON Singers(FirstName, LastName)`,
  58. `CREATE TABLE Accounts (
  59. AccountId INT64 NOT NULL,
  60. Nickname STRING(100),
  61. Balance INT64 NOT NULL,
  62. ) PRIMARY KEY (AccountId)`,
  63. `CREATE INDEX AccountByNickname ON Accounts(Nickname) STORING (Balance)`,
  64. `CREATE TABLE Types (
  65. RowID INT64 NOT NULL,
  66. String STRING(MAX),
  67. StringArray ARRAY<STRING(MAX)>,
  68. Bytes BYTES(MAX),
  69. BytesArray ARRAY<BYTES(MAX)>,
  70. Int64a INT64,
  71. Int64Array ARRAY<INT64>,
  72. Bool BOOL,
  73. BoolArray ARRAY<BOOL>,
  74. Float64 FLOAT64,
  75. Float64Array ARRAY<FLOAT64>,
  76. Date DATE,
  77. DateArray ARRAY<DATE>,
  78. Timestamp TIMESTAMP,
  79. TimestampArray ARRAY<TIMESTAMP>,
  80. ) PRIMARY KEY (RowID)`,
  81. }
  82. readDBStatements = []string{
  83. `CREATE TABLE TestTable (
  84. Key STRING(MAX) NOT NULL,
  85. StringValue STRING(MAX)
  86. ) PRIMARY KEY (Key)`,
  87. `CREATE INDEX TestTableByValue ON TestTable(StringValue)`,
  88. `CREATE INDEX TestTableByValueDesc ON TestTable(StringValue DESC)`,
  89. }
  90. simpleDBStatements = []string{
  91. `CREATE TABLE test (
  92. a STRING(1024),
  93. b STRING(1024),
  94. ) PRIMARY KEY (a)`,
  95. }
  96. simpleDBTableColumns = []string{"a", "b"}
  97. ctsDBStatements = []string{
  98. `CREATE TABLE TestTable (
  99. Key STRING(MAX) NOT NULL,
  100. Ts TIMESTAMP OPTIONS (allow_commit_timestamp = true),
  101. ) PRIMARY KEY (Key)`,
  102. }
  103. )
  104. const (
  105. str1 = "alice"
  106. str2 = "a@example.com"
  107. )
  108. func TestMain(m *testing.M) {
  109. cleanup := initIntegrationTests()
  110. res := m.Run()
  111. cleanup()
  112. os.Exit(res)
  113. }
  114. func initIntegrationTests() func() {
  115. ctx := context.Background()
  116. flag.Parse() // needed for testing.Short()
  117. noop := func() {}
  118. if testing.Short() {
  119. log.Println("Integration tests skipped in -short mode.")
  120. return noop
  121. }
  122. if testProjectID == "" {
  123. log.Println("Integration tests skipped: GCLOUD_TESTS_GOLANG_PROJECT_ID is missing")
  124. return noop
  125. }
  126. ts := testutil.TokenSource(ctx, AdminScope, Scope)
  127. if ts == nil {
  128. log.Printf("Integration test skipped: cannot get service account credential from environment variable %v", "GCLOUD_TESTS_GOLANG_KEY")
  129. return noop
  130. }
  131. var err error
  132. // Create Admin client and Data client.
  133. admin, err = database.NewDatabaseAdminClient(ctx, option.WithTokenSource(ts), option.WithEndpoint(endpoint))
  134. if err != nil {
  135. log.Fatalf("cannot create admin client: %v", err)
  136. }
  137. return func() {
  138. cleanupDatabases()
  139. admin.Close()
  140. }
  141. }
  142. // Test SingleUse transaction.
  143. func TestIntegration_SingleUse(t *testing.T) {
  144. ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
  145. defer cancel()
  146. // Set up testing environment.
  147. client, _, cleanup := prepareIntegrationTest(ctx, t, singerDBStatements)
  148. defer cleanup()
  149. writes := []struct {
  150. row []interface{}
  151. ts time.Time
  152. }{
  153. {row: []interface{}{1, "Marc", "Foo"}},
  154. {row: []interface{}{2, "Tars", "Bar"}},
  155. {row: []interface{}{3, "Alpha", "Beta"}},
  156. {row: []interface{}{4, "Last", "End"}},
  157. }
  158. // Try to write four rows through the Apply API.
  159. for i, w := range writes {
  160. var err error
  161. m := InsertOrUpdate("Singers",
  162. []string{"SingerId", "FirstName", "LastName"},
  163. w.row)
  164. if writes[i].ts, err = client.Apply(ctx, []*Mutation{m}, ApplyAtLeastOnce()); err != nil {
  165. t.Fatal(err)
  166. }
  167. }
  168. // For testing timestamp bound staleness.
  169. <-time.After(time.Second)
  170. // Test reading rows with different timestamp bounds.
  171. for i, test := range []struct {
  172. want [][]interface{}
  173. tb TimestampBound
  174. checkTs func(time.Time) error
  175. }{
  176. {
  177. // strong
  178. [][]interface{}{{int64(1), "Marc", "Foo"}, {int64(3), "Alpha", "Beta"}, {int64(4), "Last", "End"}},
  179. StrongRead(),
  180. func(ts time.Time) error {
  181. // writes[3] is the last write, all subsequent strong read should have a timestamp larger than that.
  182. if ts.Before(writes[3].ts) {
  183. return fmt.Errorf("read got timestamp %v, want it to be no later than %v", ts, writes[3].ts)
  184. }
  185. return nil
  186. },
  187. },
  188. {
  189. // min_read_timestamp
  190. [][]interface{}{{int64(1), "Marc", "Foo"}, {int64(3), "Alpha", "Beta"}, {int64(4), "Last", "End"}},
  191. MinReadTimestamp(writes[3].ts),
  192. func(ts time.Time) error {
  193. if ts.Before(writes[3].ts) {
  194. return fmt.Errorf("read got timestamp %v, want it to be no later than %v", ts, writes[3].ts)
  195. }
  196. return nil
  197. },
  198. },
  199. {
  200. // max_staleness
  201. [][]interface{}{{int64(1), "Marc", "Foo"}, {int64(3), "Alpha", "Beta"}, {int64(4), "Last", "End"}},
  202. MaxStaleness(time.Second),
  203. func(ts time.Time) error {
  204. if ts.Before(writes[3].ts) {
  205. return fmt.Errorf("read got timestamp %v, want it to be no later than %v", ts, writes[3].ts)
  206. }
  207. return nil
  208. },
  209. },
  210. {
  211. // read_timestamp
  212. [][]interface{}{{int64(1), "Marc", "Foo"}, {int64(3), "Alpha", "Beta"}},
  213. ReadTimestamp(writes[2].ts),
  214. func(ts time.Time) error {
  215. if ts != writes[2].ts {
  216. return fmt.Errorf("read got timestamp %v, want %v", ts, writes[2].ts)
  217. }
  218. return nil
  219. },
  220. },
  221. {
  222. // exact_staleness
  223. nil,
  224. // Specify a staleness which should be already before this test because
  225. // context timeout is set to be 10s.
  226. ExactStaleness(11 * time.Second),
  227. func(ts time.Time) error {
  228. if ts.After(writes[0].ts) {
  229. return fmt.Errorf("read got timestamp %v, want it to be no earlier than %v", ts, writes[0].ts)
  230. }
  231. return nil
  232. },
  233. },
  234. } {
  235. // SingleUse.Query
  236. su := client.Single().WithTimestampBound(test.tb)
  237. got, err := readAll(su.Query(
  238. ctx,
  239. Statement{
  240. "SELECT SingerId, FirstName, LastName FROM Singers WHERE SingerId IN (@id1, @id3, @id4)",
  241. map[string]interface{}{"id1": int64(1), "id3": int64(3), "id4": int64(4)},
  242. }))
  243. if err != nil {
  244. t.Errorf("%d: SingleUse.Query returns error %v, want nil", i, err)
  245. }
  246. if !testEqual(got, test.want) {
  247. t.Errorf("%d: got unexpected result from SingleUse.Query: %v, want %v", i, got, test.want)
  248. }
  249. rts, err := su.Timestamp()
  250. if err != nil {
  251. t.Errorf("%d: SingleUse.Query doesn't return a timestamp, error: %v", i, err)
  252. }
  253. if err := test.checkTs(rts); err != nil {
  254. t.Errorf("%d: SingleUse.Query doesn't return expected timestamp: %v", i, err)
  255. }
  256. // SingleUse.Read
  257. su = client.Single().WithTimestampBound(test.tb)
  258. got, err = readAll(su.Read(ctx, "Singers", KeySets(Key{1}, Key{3}, Key{4}), []string{"SingerId", "FirstName", "LastName"}))
  259. if err != nil {
  260. t.Errorf("%d: SingleUse.Read returns error %v, want nil", i, err)
  261. }
  262. if !testEqual(got, test.want) {
  263. t.Errorf("%d: got unexpected result from SingleUse.Read: %v, want %v", i, got, test.want)
  264. }
  265. rts, err = su.Timestamp()
  266. if err != nil {
  267. t.Errorf("%d: SingleUse.Read doesn't return a timestamp, error: %v", i, err)
  268. }
  269. if err := test.checkTs(rts); err != nil {
  270. t.Errorf("%d: SingleUse.Read doesn't return expected timestamp: %v", i, err)
  271. }
  272. // SingleUse.ReadRow
  273. got = nil
  274. for _, k := range []Key{{1}, {3}, {4}} {
  275. su = client.Single().WithTimestampBound(test.tb)
  276. r, err := su.ReadRow(ctx, "Singers", k, []string{"SingerId", "FirstName", "LastName"})
  277. if err != nil {
  278. continue
  279. }
  280. v, err := rowToValues(r)
  281. if err != nil {
  282. continue
  283. }
  284. got = append(got, v)
  285. rts, err = su.Timestamp()
  286. if err != nil {
  287. t.Errorf("%d: SingleUse.ReadRow(%v) doesn't return a timestamp, error: %v", i, k, err)
  288. }
  289. if err := test.checkTs(rts); err != nil {
  290. t.Errorf("%d: SingleUse.ReadRow(%v) doesn't return expected timestamp: %v", i, k, err)
  291. }
  292. }
  293. if !testEqual(got, test.want) {
  294. t.Errorf("%d: got unexpected results from SingleUse.ReadRow: %v, want %v", i, got, test.want)
  295. }
  296. // SingleUse.ReadUsingIndex
  297. su = client.Single().WithTimestampBound(test.tb)
  298. got, err = readAll(su.ReadUsingIndex(ctx, "Singers", "SingerByName", KeySets(Key{"Marc", "Foo"}, Key{"Alpha", "Beta"}, Key{"Last", "End"}), []string{"SingerId", "FirstName", "LastName"}))
  299. if err != nil {
  300. t.Errorf("%d: SingleUse.ReadUsingIndex returns error %v, want nil", i, err)
  301. }
  302. // The results from ReadUsingIndex is sorted by the index rather than primary key.
  303. if len(got) != len(test.want) {
  304. t.Errorf("%d: got unexpected result from SingleUse.ReadUsingIndex: %v, want %v", i, got, test.want)
  305. }
  306. for j, g := range got {
  307. if j > 0 {
  308. prev := got[j-1][1].(string) + got[j-1][2].(string)
  309. curr := got[j][1].(string) + got[j][2].(string)
  310. if strings.Compare(prev, curr) > 0 {
  311. t.Errorf("%d: SingleUse.ReadUsingIndex fails to order rows by index keys, %v should be after %v", i, got[j-1], got[j])
  312. }
  313. }
  314. found := false
  315. for _, w := range test.want {
  316. if testEqual(g, w) {
  317. found = true
  318. }
  319. }
  320. if !found {
  321. t.Errorf("%d: got unexpected result from SingleUse.ReadUsingIndex: %v, want %v", i, got, test.want)
  322. break
  323. }
  324. }
  325. rts, err = su.Timestamp()
  326. if err != nil {
  327. t.Errorf("%d: SingleUse.ReadUsingIndex doesn't return a timestamp, error: %v", i, err)
  328. }
  329. if err := test.checkTs(rts); err != nil {
  330. t.Errorf("%d: SingleUse.ReadUsingIndex doesn't return expected timestamp: %v", i, err)
  331. }
  332. }
  333. // Reading with limit.
  334. su := client.Single()
  335. const limit = 1
  336. gotRows, err := readAll(su.ReadWithOptions(ctx, "Singers", KeySets(Key{1}, Key{3}, Key{4}),
  337. []string{"SingerId", "FirstName", "LastName"}, &ReadOptions{Limit: limit}))
  338. if err != nil {
  339. t.Errorf("SingleUse.ReadWithOptions returns error %v, want nil", err)
  340. }
  341. if got, want := len(gotRows), limit; got != want {
  342. t.Errorf("got %d, want %d", got, want)
  343. }
  344. }
  345. // Test ReadOnlyTransaction. The testsuite is mostly like SingleUse, except it
  346. // also tests for a single timestamp across multiple reads.
  347. func TestIntegration_ReadOnlyTransaction(t *testing.T) {
  348. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
  349. defer cancel()
  350. // Set up testing environment.
  351. client, _, cleanup := prepareIntegrationTest(ctx, t, singerDBStatements)
  352. defer cleanup()
  353. writes := []struct {
  354. row []interface{}
  355. ts time.Time
  356. }{
  357. {row: []interface{}{1, "Marc", "Foo"}},
  358. {row: []interface{}{2, "Tars", "Bar"}},
  359. {row: []interface{}{3, "Alpha", "Beta"}},
  360. {row: []interface{}{4, "Last", "End"}},
  361. }
  362. // Try to write four rows through the Apply API.
  363. for i, w := range writes {
  364. var err error
  365. m := InsertOrUpdate("Singers",
  366. []string{"SingerId", "FirstName", "LastName"},
  367. w.row)
  368. if writes[i].ts, err = client.Apply(ctx, []*Mutation{m}, ApplyAtLeastOnce()); err != nil {
  369. t.Fatal(err)
  370. }
  371. }
  372. // For testing timestamp bound staleness.
  373. <-time.After(time.Second)
  374. // Test reading rows with different timestamp bounds.
  375. for i, test := range []struct {
  376. want [][]interface{}
  377. tb TimestampBound
  378. checkTs func(time.Time) error
  379. }{
  380. // Note: min_read_timestamp and max_staleness are not supported by ReadOnlyTransaction. See
  381. // API document for more details.
  382. {
  383. // strong
  384. [][]interface{}{{int64(1), "Marc", "Foo"}, {int64(3), "Alpha", "Beta"}, {int64(4), "Last", "End"}},
  385. StrongRead(),
  386. func(ts time.Time) error {
  387. if ts.Before(writes[3].ts) {
  388. return fmt.Errorf("read got timestamp %v, want it to be no later than %v", ts, writes[3].ts)
  389. }
  390. return nil
  391. },
  392. },
  393. {
  394. // read_timestamp
  395. [][]interface{}{{int64(1), "Marc", "Foo"}, {int64(3), "Alpha", "Beta"}},
  396. ReadTimestamp(writes[2].ts),
  397. func(ts time.Time) error {
  398. if ts != writes[2].ts {
  399. return fmt.Errorf("read got timestamp %v, expect %v", ts, writes[2].ts)
  400. }
  401. return nil
  402. },
  403. },
  404. {
  405. // exact_staleness
  406. nil,
  407. // Specify a staleness which should be already before this test because
  408. // context timeout is set to be 10s.
  409. ExactStaleness(11 * time.Second),
  410. func(ts time.Time) error {
  411. if ts.After(writes[0].ts) {
  412. return fmt.Errorf("read got timestamp %v, want it to be no earlier than %v", ts, writes[0].ts)
  413. }
  414. return nil
  415. },
  416. },
  417. } {
  418. // ReadOnlyTransaction.Query
  419. ro := client.ReadOnlyTransaction().WithTimestampBound(test.tb)
  420. got, err := readAll(ro.Query(
  421. ctx,
  422. Statement{
  423. "SELECT SingerId, FirstName, LastName FROM Singers WHERE SingerId IN (@id1, @id3, @id4)",
  424. map[string]interface{}{"id1": int64(1), "id3": int64(3), "id4": int64(4)},
  425. }))
  426. if err != nil {
  427. t.Errorf("%d: ReadOnlyTransaction.Query returns error %v, want nil", i, err)
  428. }
  429. if !testEqual(got, test.want) {
  430. t.Errorf("%d: got unexpected result from ReadOnlyTransaction.Query: %v, want %v", i, got, test.want)
  431. }
  432. rts, err := ro.Timestamp()
  433. if err != nil {
  434. t.Errorf("%d: ReadOnlyTransaction.Query doesn't return a timestamp, error: %v", i, err)
  435. }
  436. if err := test.checkTs(rts); err != nil {
  437. t.Errorf("%d: ReadOnlyTransaction.Query doesn't return expected timestamp: %v", i, err)
  438. }
  439. roTs := rts
  440. // ReadOnlyTransaction.Read
  441. got, err = readAll(ro.Read(ctx, "Singers", KeySets(Key{1}, Key{3}, Key{4}), []string{"SingerId", "FirstName", "LastName"}))
  442. if err != nil {
  443. t.Errorf("%d: ReadOnlyTransaction.Read returns error %v, want nil", i, err)
  444. }
  445. if !testEqual(got, test.want) {
  446. t.Errorf("%d: got unexpected result from ReadOnlyTransaction.Read: %v, want %v", i, got, test.want)
  447. }
  448. rts, err = ro.Timestamp()
  449. if err != nil {
  450. t.Errorf("%d: ReadOnlyTransaction.Read doesn't return a timestamp, error: %v", i, err)
  451. }
  452. if err := test.checkTs(rts); err != nil {
  453. t.Errorf("%d: ReadOnlyTransaction.Read doesn't return expected timestamp: %v", i, err)
  454. }
  455. if roTs != rts {
  456. t.Errorf("%d: got two read timestamps: %v, %v, want ReadOnlyTransaction to return always the same read timestamp", i, roTs, rts)
  457. }
  458. // ReadOnlyTransaction.ReadRow
  459. got = nil
  460. for _, k := range []Key{{1}, {3}, {4}} {
  461. r, err := ro.ReadRow(ctx, "Singers", k, []string{"SingerId", "FirstName", "LastName"})
  462. if err != nil {
  463. continue
  464. }
  465. v, err := rowToValues(r)
  466. if err != nil {
  467. continue
  468. }
  469. got = append(got, v)
  470. rts, err = ro.Timestamp()
  471. if err != nil {
  472. t.Errorf("%d: ReadOnlyTransaction.ReadRow(%v) doesn't return a timestamp, error: %v", i, k, err)
  473. }
  474. if err := test.checkTs(rts); err != nil {
  475. t.Errorf("%d: ReadOnlyTransaction.ReadRow(%v) doesn't return expected timestamp: %v", i, k, err)
  476. }
  477. if roTs != rts {
  478. t.Errorf("%d: got two read timestamps: %v, %v, want ReadOnlyTransaction to return always the same read timestamp", i, roTs, rts)
  479. }
  480. }
  481. if !testEqual(got, test.want) {
  482. t.Errorf("%d: got unexpected results from ReadOnlyTransaction.ReadRow: %v, want %v", i, got, test.want)
  483. }
  484. // SingleUse.ReadUsingIndex
  485. got, err = readAll(ro.ReadUsingIndex(ctx, "Singers", "SingerByName", KeySets(Key{"Marc", "Foo"}, Key{"Alpha", "Beta"}, Key{"Last", "End"}), []string{"SingerId", "FirstName", "LastName"}))
  486. if err != nil {
  487. t.Errorf("%d: ReadOnlyTransaction.ReadUsingIndex returns error %v, want nil", i, err)
  488. }
  489. // The results from ReadUsingIndex is sorted by the index rather than primary key.
  490. if len(got) != len(test.want) {
  491. t.Errorf("%d: got unexpected result from ReadOnlyTransaction.ReadUsingIndex: %v, want %v", i, got, test.want)
  492. }
  493. for j, g := range got {
  494. if j > 0 {
  495. prev := got[j-1][1].(string) + got[j-1][2].(string)
  496. curr := got[j][1].(string) + got[j][2].(string)
  497. if strings.Compare(prev, curr) > 0 {
  498. t.Errorf("%d: ReadOnlyTransaction.ReadUsingIndex fails to order rows by index keys, %v should be after %v", i, got[j-1], got[j])
  499. }
  500. }
  501. found := false
  502. for _, w := range test.want {
  503. if testEqual(g, w) {
  504. found = true
  505. }
  506. }
  507. if !found {
  508. t.Errorf("%d: got unexpected result from ReadOnlyTransaction.ReadUsingIndex: %v, want %v", i, got, test.want)
  509. break
  510. }
  511. }
  512. rts, err = ro.Timestamp()
  513. if err != nil {
  514. t.Errorf("%d: ReadOnlyTransaction.ReadUsingIndex doesn't return a timestamp, error: %v", i, err)
  515. }
  516. if err := test.checkTs(rts); err != nil {
  517. t.Errorf("%d: ReadOnlyTransaction.ReadUsingIndex doesn't return expected timestamp: %v", i, err)
  518. }
  519. if roTs != rts {
  520. t.Errorf("%d: got two read timestamps: %v, %v, want ReadOnlyTransaction to return always the same read timestamp", i, roTs, rts)
  521. }
  522. ro.Close()
  523. }
  524. }
  525. // Test ReadOnlyTransaction with different timestamp bound when there's an update at the same time.
  526. func TestIntegration_UpdateDuringRead(t *testing.T) {
  527. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
  528. defer cancel()
  529. client, _, cleanup := prepareIntegrationTest(ctx, t, singerDBStatements)
  530. defer cleanup()
  531. for i, tb := range []TimestampBound{
  532. StrongRead(),
  533. ReadTimestamp(time.Now().Add(-time.Minute * 30)), // version GC is 1 hour
  534. ExactStaleness(time.Minute * 30),
  535. } {
  536. ro := client.ReadOnlyTransaction().WithTimestampBound(tb)
  537. _, err := ro.ReadRow(ctx, "Singers", Key{i}, []string{"SingerId"})
  538. if ErrCode(err) != codes.NotFound {
  539. t.Errorf("%d: ReadOnlyTransaction.ReadRow before write returns error: %v, want NotFound", i, err)
  540. }
  541. m := InsertOrUpdate("Singers", []string{"SingerId"}, []interface{}{i})
  542. if _, err := client.Apply(ctx, []*Mutation{m}, ApplyAtLeastOnce()); err != nil {
  543. t.Fatal(err)
  544. }
  545. _, err = ro.ReadRow(ctx, "Singers", Key{i}, []string{"SingerId"})
  546. if ErrCode(err) != codes.NotFound {
  547. t.Errorf("%d: ReadOnlyTransaction.ReadRow after write returns error: %v, want NotFound", i, err)
  548. }
  549. }
  550. }
  551. // Test ReadWriteTransaction.
  552. func TestIntegration_ReadWriteTransaction(t *testing.T) {
  553. // Give a longer deadline because of transaction backoffs.
  554. ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
  555. defer cancel()
  556. client, _, cleanup := prepareIntegrationTest(ctx, t, singerDBStatements)
  557. defer cleanup()
  558. // Set up two accounts
  559. accounts := []*Mutation{
  560. Insert("Accounts", []string{"AccountId", "Nickname", "Balance"}, []interface{}{int64(1), "Foo", int64(50)}),
  561. Insert("Accounts", []string{"AccountId", "Nickname", "Balance"}, []interface{}{int64(2), "Bar", int64(1)}),
  562. }
  563. if _, err := client.Apply(ctx, accounts, ApplyAtLeastOnce()); err != nil {
  564. t.Fatal(err)
  565. }
  566. wg := sync.WaitGroup{}
  567. readBalance := func(iter *RowIterator) (int64, error) {
  568. defer iter.Stop()
  569. var bal int64
  570. for {
  571. row, err := iter.Next()
  572. if err == iterator.Done {
  573. return bal, nil
  574. }
  575. if err != nil {
  576. return 0, err
  577. }
  578. if err := row.Column(0, &bal); err != nil {
  579. return 0, err
  580. }
  581. }
  582. }
  583. for i := 0; i < 20; i++ {
  584. wg.Add(1)
  585. go func(iter int) {
  586. defer wg.Done()
  587. _, err := client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error {
  588. // Query Foo's balance and Bar's balance.
  589. bf, e := readBalance(tx.Query(ctx,
  590. Statement{"SELECT Balance FROM Accounts WHERE AccountId = @id", map[string]interface{}{"id": int64(1)}}))
  591. if e != nil {
  592. return e
  593. }
  594. bb, e := readBalance(tx.Read(ctx, "Accounts", KeySets(Key{int64(2)}), []string{"Balance"}))
  595. if e != nil {
  596. return e
  597. }
  598. if bf <= 0 {
  599. return nil
  600. }
  601. bf--
  602. bb++
  603. return tx.BufferWrite([]*Mutation{
  604. Update("Accounts", []string{"AccountId", "Balance"}, []interface{}{int64(1), bf}),
  605. Update("Accounts", []string{"AccountId", "Balance"}, []interface{}{int64(2), bb}),
  606. })
  607. })
  608. if err != nil {
  609. t.Errorf("%d: failed to execute transaction: %v", iter, err)
  610. }
  611. }(i)
  612. }
  613. // Because of context timeout, all goroutines will eventually return.
  614. wg.Wait()
  615. _, err := client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error {
  616. var bf, bb int64
  617. r, e := tx.ReadRow(ctx, "Accounts", Key{int64(1)}, []string{"Balance"})
  618. if e != nil {
  619. return e
  620. }
  621. if ce := r.Column(0, &bf); ce != nil {
  622. return ce
  623. }
  624. bb, e = readBalance(tx.ReadUsingIndex(ctx, "Accounts", "AccountByNickname", KeySets(Key{"Bar"}), []string{"Balance"}))
  625. if e != nil {
  626. return e
  627. }
  628. if bf != 30 || bb != 21 {
  629. t.Errorf("Foo's balance is now %v and Bar's balance is now %v, want %v and %v", bf, bb, 30, 21)
  630. }
  631. return nil
  632. })
  633. if err != nil {
  634. t.Errorf("failed to check balances: %v", err)
  635. }
  636. }
  637. func TestIntegration_Reads(t *testing.T) {
  638. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
  639. defer cancel()
  640. // Set up testing environment.
  641. client, _, cleanup := prepareIntegrationTest(ctx, t, readDBStatements)
  642. defer cleanup()
  643. // Includes k0..k14. Strings sort lexically, eg "k1" < "k10" < "k2".
  644. var ms []*Mutation
  645. for i := 0; i < 15; i++ {
  646. ms = append(ms, InsertOrUpdate(testTable,
  647. testTableColumns,
  648. []interface{}{fmt.Sprintf("k%d", i), fmt.Sprintf("v%d", i)}))
  649. }
  650. // Don't use ApplyAtLeastOnce, so we can test the other code path.
  651. if _, err := client.Apply(ctx, ms); err != nil {
  652. t.Fatal(err)
  653. }
  654. // Empty read.
  655. rows, err := readAllTestTable(client.Single().Read(ctx, testTable,
  656. KeyRange{Start: Key{"k99"}, End: Key{"z"}}, testTableColumns))
  657. if err != nil {
  658. t.Fatal(err)
  659. }
  660. if got, want := len(rows), 0; got != want {
  661. t.Errorf("got %d, want %d", got, want)
  662. }
  663. // Index empty read.
  664. rows, err = readAllTestTable(client.Single().ReadUsingIndex(ctx, testTable, testTableIndex,
  665. KeyRange{Start: Key{"v99"}, End: Key{"z"}}, testTableColumns))
  666. if err != nil {
  667. t.Fatal(err)
  668. }
  669. if got, want := len(rows), 0; got != want {
  670. t.Errorf("got %d, want %d", got, want)
  671. }
  672. // Point read.
  673. row, err := client.Single().ReadRow(ctx, testTable, Key{"k1"}, testTableColumns)
  674. if err != nil {
  675. t.Fatal(err)
  676. }
  677. var got testTableRow
  678. if err := row.ToStruct(&got); err != nil {
  679. t.Fatal(err)
  680. }
  681. if want := (testTableRow{"k1", "v1"}); got != want {
  682. t.Errorf("got %v, want %v", got, want)
  683. }
  684. // Point read not found.
  685. _, err = client.Single().ReadRow(ctx, testTable, Key{"k999"}, testTableColumns)
  686. if ErrCode(err) != codes.NotFound {
  687. t.Fatalf("got %v, want NotFound", err)
  688. }
  689. // No index point read not found, because Go does not have ReadRowUsingIndex.
  690. rangeReads(ctx, t, client)
  691. indexRangeReads(ctx, t, client)
  692. }
  693. func TestIntegration_EarlyTimestamp(t *testing.T) {
  694. // Test that we can get the timestamp from a read-only transaction as
  695. // soon as we have read at least one row.
  696. ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
  697. defer cancel()
  698. // Set up testing environment.
  699. client, _, cleanup := prepareIntegrationTest(ctx, t, readDBStatements)
  700. defer cleanup()
  701. var ms []*Mutation
  702. for i := 0; i < 3; i++ {
  703. ms = append(ms, InsertOrUpdate(testTable,
  704. testTableColumns,
  705. []interface{}{fmt.Sprintf("k%d", i), fmt.Sprintf("v%d", i)}))
  706. }
  707. if _, err := client.Apply(ctx, ms, ApplyAtLeastOnce()); err != nil {
  708. t.Fatal(err)
  709. }
  710. txn := client.Single()
  711. iter := txn.Read(ctx, testTable, AllKeys(), testTableColumns)
  712. defer iter.Stop()
  713. // In single-use transaction, we should get an error before reading anything.
  714. if _, err := txn.Timestamp(); err == nil {
  715. t.Error("wanted error, got nil")
  716. }
  717. // After reading one row, the timestamp should be available.
  718. _, err := iter.Next()
  719. if err != nil {
  720. t.Fatal(err)
  721. }
  722. if _, err := txn.Timestamp(); err != nil {
  723. t.Errorf("got %v, want nil", err)
  724. }
  725. txn = client.ReadOnlyTransaction()
  726. defer txn.Close()
  727. iter = txn.Read(ctx, testTable, AllKeys(), testTableColumns)
  728. defer iter.Stop()
  729. // In an ordinary read-only transaction, the timestamp should be
  730. // available immediately.
  731. if _, err := txn.Timestamp(); err != nil {
  732. t.Errorf("got %v, want nil", err)
  733. }
  734. }
  735. func TestIntegration_NestedTransaction(t *testing.T) {
  736. // You cannot use a transaction from inside a read-write transaction.
  737. ctx := context.Background()
  738. client, _, cleanup := prepareIntegrationTest(ctx, t, singerDBStatements)
  739. defer cleanup()
  740. _, err := client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error {
  741. _, err := client.ReadWriteTransaction(ctx,
  742. func(context.Context, *ReadWriteTransaction) error { return nil })
  743. if ErrCode(err) != codes.FailedPrecondition {
  744. t.Fatalf("got %v, want FailedPrecondition", err)
  745. }
  746. _, err = client.Single().ReadRow(ctx, "Singers", Key{1}, []string{"SingerId"})
  747. if ErrCode(err) != codes.FailedPrecondition {
  748. t.Fatalf("got %v, want FailedPrecondition", err)
  749. }
  750. rot := client.ReadOnlyTransaction()
  751. defer rot.Close()
  752. _, err = rot.ReadRow(ctx, "Singers", Key{1}, []string{"SingerId"})
  753. if ErrCode(err) != codes.FailedPrecondition {
  754. t.Fatalf("got %v, want FailedPrecondition", err)
  755. }
  756. return nil
  757. })
  758. if err != nil {
  759. t.Fatal(err)
  760. }
  761. }
  762. // Test client recovery on database recreation.
  763. func TestIntegration_DbRemovalRecovery(t *testing.T) {
  764. ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
  765. defer cancel()
  766. client, dbPath, cleanup := prepareIntegrationTest(ctx, t, singerDBStatements)
  767. defer cleanup()
  768. // Drop the testing database.
  769. if err := admin.DropDatabase(ctx, &adminpb.DropDatabaseRequest{Database: dbPath}); err != nil {
  770. t.Fatalf("failed to drop testing database %v: %v", dbPath, err)
  771. }
  772. // Now, send the query.
  773. iter := client.Single().Query(ctx, Statement{SQL: "SELECT SingerId FROM Singers"})
  774. defer iter.Stop()
  775. if _, err := iter.Next(); err == nil {
  776. t.Errorf("client sends query to removed database successfully, want it to fail")
  777. }
  778. // Recreate database and table.
  779. dbName := dbPath[strings.LastIndex(dbPath, "/")+1:]
  780. op, err := admin.CreateDatabase(ctx, &adminpb.CreateDatabaseRequest{
  781. Parent: fmt.Sprintf("projects/%v/instances/%v", testProjectID, testInstanceID),
  782. CreateStatement: "CREATE DATABASE " + dbName,
  783. ExtraStatements: []string{
  784. `CREATE TABLE Singers (
  785. SingerId INT64 NOT NULL,
  786. FirstName STRING(1024),
  787. LastName STRING(1024),
  788. SingerInfo BYTES(MAX)
  789. ) PRIMARY KEY (SingerId)`,
  790. },
  791. })
  792. if err != nil {
  793. t.Fatalf("cannot recreate testing DB %v: %v", dbPath, err)
  794. }
  795. if _, err := op.Wait(ctx); err != nil {
  796. t.Fatalf("cannot recreate testing DB %v: %v", dbPath, err)
  797. }
  798. // Now, send the query again.
  799. iter = client.Single().Query(ctx, Statement{SQL: "SELECT SingerId FROM Singers"})
  800. defer iter.Stop()
  801. _, err = iter.Next()
  802. if err != nil && err != iterator.Done {
  803. t.Errorf("failed to send query to database %v: %v", dbPath, err)
  804. }
  805. }
  806. // Test encoding/decoding non-struct Cloud Spanner types.
  807. func TestIntegration_BasicTypes(t *testing.T) {
  808. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
  809. defer cancel()
  810. client, _, cleanup := prepareIntegrationTest(ctx, t, singerDBStatements)
  811. defer cleanup()
  812. t1, _ := time.Parse(time.RFC3339Nano, "2016-11-15T15:04:05.999999999Z")
  813. // Boundaries
  814. t2, _ := time.Parse(time.RFC3339Nano, "0001-01-01T00:00:00.000000000Z")
  815. t3, _ := time.Parse(time.RFC3339Nano, "9999-12-31T23:59:59.999999999Z")
  816. d1, _ := civil.ParseDate("2016-11-15")
  817. // Boundaries
  818. d2, _ := civil.ParseDate("0001-01-01")
  819. d3, _ := civil.ParseDate("9999-12-31")
  820. tests := []struct {
  821. col string
  822. val interface{}
  823. want interface{}
  824. }{
  825. {col: "String", val: ""},
  826. {col: "String", val: "", want: NullString{"", true}},
  827. {col: "String", val: "foo"},
  828. {col: "String", val: "foo", want: NullString{"foo", true}},
  829. {col: "String", val: NullString{"bar", true}, want: "bar"},
  830. {col: "String", val: NullString{"bar", false}, want: NullString{"", false}},
  831. {col: "String", val: nil, want: NullString{}},
  832. {col: "StringArray", val: []string(nil), want: []NullString(nil)},
  833. {col: "StringArray", val: []string{}, want: []NullString{}},
  834. {col: "StringArray", val: []string{"foo", "bar"}, want: []NullString{{"foo", true}, {"bar", true}}},
  835. {col: "StringArray", val: []NullString(nil)},
  836. {col: "StringArray", val: []NullString{}},
  837. {col: "StringArray", val: []NullString{{"foo", true}, {}}},
  838. {col: "Bytes", val: []byte{}},
  839. {col: "Bytes", val: []byte{1, 2, 3}},
  840. {col: "Bytes", val: []byte(nil)},
  841. {col: "BytesArray", val: [][]byte(nil)},
  842. {col: "BytesArray", val: [][]byte{}},
  843. {col: "BytesArray", val: [][]byte{{1}, {2, 3}}},
  844. {col: "Int64a", val: 0, want: int64(0)},
  845. {col: "Int64a", val: -1, want: int64(-1)},
  846. {col: "Int64a", val: 2, want: int64(2)},
  847. {col: "Int64a", val: int64(3)},
  848. {col: "Int64a", val: 4, want: NullInt64{4, true}},
  849. {col: "Int64a", val: NullInt64{5, true}, want: int64(5)},
  850. {col: "Int64a", val: NullInt64{6, true}, want: int64(6)},
  851. {col: "Int64a", val: NullInt64{7, false}, want: NullInt64{0, false}},
  852. {col: "Int64a", val: nil, want: NullInt64{}},
  853. {col: "Int64Array", val: []int(nil), want: []NullInt64(nil)},
  854. {col: "Int64Array", val: []int{}, want: []NullInt64{}},
  855. {col: "Int64Array", val: []int{1, 2}, want: []NullInt64{{1, true}, {2, true}}},
  856. {col: "Int64Array", val: []int64(nil), want: []NullInt64(nil)},
  857. {col: "Int64Array", val: []int64{}, want: []NullInt64{}},
  858. {col: "Int64Array", val: []int64{1, 2}, want: []NullInt64{{1, true}, {2, true}}},
  859. {col: "Int64Array", val: []NullInt64(nil)},
  860. {col: "Int64Array", val: []NullInt64{}},
  861. {col: "Int64Array", val: []NullInt64{{1, true}, {}}},
  862. {col: "Bool", val: false},
  863. {col: "Bool", val: true},
  864. {col: "Bool", val: false, want: NullBool{false, true}},
  865. {col: "Bool", val: true, want: NullBool{true, true}},
  866. {col: "Bool", val: NullBool{true, true}},
  867. {col: "Bool", val: NullBool{false, false}},
  868. {col: "Bool", val: nil, want: NullBool{}},
  869. {col: "BoolArray", val: []bool(nil), want: []NullBool(nil)},
  870. {col: "BoolArray", val: []bool{}, want: []NullBool{}},
  871. {col: "BoolArray", val: []bool{true, false}, want: []NullBool{{true, true}, {false, true}}},
  872. {col: "BoolArray", val: []NullBool(nil)},
  873. {col: "BoolArray", val: []NullBool{}},
  874. {col: "BoolArray", val: []NullBool{{false, true}, {true, true}, {}}},
  875. {col: "Float64", val: 0.0},
  876. {col: "Float64", val: 3.14},
  877. {col: "Float64", val: math.NaN()},
  878. {col: "Float64", val: math.Inf(1)},
  879. {col: "Float64", val: math.Inf(-1)},
  880. {col: "Float64", val: 2.78, want: NullFloat64{2.78, true}},
  881. {col: "Float64", val: NullFloat64{2.71, true}, want: 2.71},
  882. {col: "Float64", val: NullFloat64{1.41, true}, want: NullFloat64{1.41, true}},
  883. {col: "Float64", val: NullFloat64{0, false}},
  884. {col: "Float64", val: nil, want: NullFloat64{}},
  885. {col: "Float64Array", val: []float64(nil), want: []NullFloat64(nil)},
  886. {col: "Float64Array", val: []float64{}, want: []NullFloat64{}},
  887. {col: "Float64Array", val: []float64{2.72, 3.14, math.Inf(1)}, want: []NullFloat64{{2.72, true}, {3.14, true}, {math.Inf(1), true}}},
  888. {col: "Float64Array", val: []NullFloat64(nil)},
  889. {col: "Float64Array", val: []NullFloat64{}},
  890. {col: "Float64Array", val: []NullFloat64{{2.72, true}, {math.Inf(1), true}, {}}},
  891. {col: "Date", val: d1},
  892. {col: "Date", val: d1, want: NullDate{d1, true}},
  893. {col: "Date", val: NullDate{d1, true}},
  894. {col: "Date", val: NullDate{d1, true}, want: d1},
  895. {col: "Date", val: NullDate{civil.Date{}, false}},
  896. {col: "DateArray", val: []civil.Date(nil), want: []NullDate(nil)},
  897. {col: "DateArray", val: []civil.Date{}, want: []NullDate{}},
  898. {col: "DateArray", val: []civil.Date{d1, d2, d3}, want: []NullDate{{d1, true}, {d2, true}, {d3, true}}},
  899. {col: "Timestamp", val: t1},
  900. {col: "Timestamp", val: t1, want: NullTime{t1, true}},
  901. {col: "Timestamp", val: NullTime{t1, true}},
  902. {col: "Timestamp", val: NullTime{t1, true}, want: t1},
  903. {col: "Timestamp", val: NullTime{}},
  904. {col: "Timestamp", val: nil, want: NullTime{}},
  905. {col: "TimestampArray", val: []time.Time(nil), want: []NullTime(nil)},
  906. {col: "TimestampArray", val: []time.Time{}, want: []NullTime{}},
  907. {col: "TimestampArray", val: []time.Time{t1, t2, t3}, want: []NullTime{{t1, true}, {t2, true}, {t3, true}}},
  908. }
  909. // Write rows into table first.
  910. var muts []*Mutation
  911. for i, test := range tests {
  912. muts = append(muts, InsertOrUpdate("Types", []string{"RowID", test.col}, []interface{}{i, test.val}))
  913. }
  914. if _, err := client.Apply(ctx, muts, ApplyAtLeastOnce()); err != nil {
  915. t.Fatal(err)
  916. }
  917. for i, test := range tests {
  918. row, err := client.Single().ReadRow(ctx, "Types", []interface{}{i}, []string{test.col})
  919. if err != nil {
  920. t.Fatalf("Unable to fetch row %v: %v", i, err)
  921. }
  922. // Create new instance of type of test.want.
  923. want := test.want
  924. if want == nil {
  925. want = test.val
  926. }
  927. gotp := reflect.New(reflect.TypeOf(want))
  928. if err := row.Column(0, gotp.Interface()); err != nil {
  929. t.Errorf("%d: col:%v val:%#v, %v", i, test.col, test.val, err)
  930. continue
  931. }
  932. got := reflect.Indirect(gotp).Interface()
  933. // One of the test cases is checking NaN handling. Given
  934. // NaN!=NaN, we can't use reflect to test for it.
  935. if isNaN(got) && isNaN(want) {
  936. continue
  937. }
  938. // Check non-NaN cases.
  939. if !testEqual(got, want) {
  940. t.Errorf("%d: col:%v val:%#v, got %#v, want %#v", i, test.col, test.val, got, want)
  941. continue
  942. }
  943. }
  944. }
  945. // Test decoding Cloud Spanner STRUCT type.
  946. func TestIntegration_StructTypes(t *testing.T) {
  947. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
  948. defer cancel()
  949. client, _, cleanup := prepareIntegrationTest(ctx, t, singerDBStatements)
  950. defer cleanup()
  951. tests := []struct {
  952. q Statement
  953. want func(r *Row) error
  954. }{
  955. {
  956. q: Statement{SQL: `SELECT ARRAY(SELECT STRUCT(1, 2))`},
  957. want: func(r *Row) error {
  958. // Test STRUCT ARRAY decoding to []NullRow.
  959. var rows []NullRow
  960. if err := r.Column(0, &rows); err != nil {
  961. return err
  962. }
  963. if len(rows) != 1 {
  964. return fmt.Errorf("len(rows) = %d; want 1", len(rows))
  965. }
  966. if !rows[0].Valid {
  967. return fmt.Errorf("rows[0] is NULL")
  968. }
  969. var i, j int64
  970. if err := rows[0].Row.Columns(&i, &j); err != nil {
  971. return err
  972. }
  973. if i != 1 || j != 2 {
  974. return fmt.Errorf("got (%d,%d), want (1,2)", i, j)
  975. }
  976. return nil
  977. },
  978. },
  979. {
  980. q: Statement{SQL: `SELECT ARRAY(SELECT STRUCT(1 as foo, 2 as bar)) as col1`},
  981. want: func(r *Row) error {
  982. // Test Row.ToStruct.
  983. s := struct {
  984. Col1 []*struct {
  985. Foo int64 `spanner:"foo"`
  986. Bar int64 `spanner:"bar"`
  987. } `spanner:"col1"`
  988. }{}
  989. if err := r.ToStruct(&s); err != nil {
  990. return err
  991. }
  992. want := struct {
  993. Col1 []*struct {
  994. Foo int64 `spanner:"foo"`
  995. Bar int64 `spanner:"bar"`
  996. } `spanner:"col1"`
  997. }{
  998. Col1: []*struct {
  999. Foo int64 `spanner:"foo"`
  1000. Bar int64 `spanner:"bar"`
  1001. }{
  1002. {
  1003. Foo: 1,
  1004. Bar: 2,
  1005. },
  1006. },
  1007. }
  1008. if !testEqual(want, s) {
  1009. return fmt.Errorf("unexpected decoding result: %v, want %v", s, want)
  1010. }
  1011. return nil
  1012. },
  1013. },
  1014. }
  1015. for i, test := range tests {
  1016. iter := client.Single().Query(ctx, test.q)
  1017. defer iter.Stop()
  1018. row, err := iter.Next()
  1019. if err != nil {
  1020. t.Errorf("%d: %v", i, err)
  1021. continue
  1022. }
  1023. if err := test.want(row); err != nil {
  1024. t.Errorf("%d: %v", i, err)
  1025. continue
  1026. }
  1027. }
  1028. }
  1029. func TestIntegration_StructParametersUnsupported(t *testing.T) {
  1030. ctx := context.Background()
  1031. client, _, cleanup := prepareIntegrationTest(ctx, t, nil)
  1032. defer cleanup()
  1033. for _, test := range []struct {
  1034. param interface{}
  1035. wantCode codes.Code
  1036. wantMsgPart string
  1037. }{
  1038. {
  1039. struct {
  1040. Field int
  1041. }{10},
  1042. codes.Unimplemented,
  1043. "Unsupported query shape: " +
  1044. "A struct value cannot be returned as a column value. " +
  1045. "Rewrite the query to flatten the struct fields in the result.",
  1046. },
  1047. {
  1048. []struct {
  1049. Field int
  1050. }{{10}, {20}},
  1051. codes.Unimplemented,
  1052. "Unsupported query shape: " +
  1053. "This query can return a null-valued array of struct, " +
  1054. "which is not supported by Spanner.",
  1055. },
  1056. } {
  1057. iter := client.Single().Query(ctx, Statement{
  1058. SQL: "SELECT @p",
  1059. Params: map[string]interface{}{"p": test.param},
  1060. })
  1061. _, err := iter.Next()
  1062. iter.Stop()
  1063. if msg, ok := matchError(err, test.wantCode, test.wantMsgPart); !ok {
  1064. t.Fatal(msg)
  1065. }
  1066. }
  1067. }
  1068. // Test queries of the form "SELECT expr".
  1069. func TestIntegration_QueryExpressions(t *testing.T) {
  1070. ctx := context.Background()
  1071. client, _, cleanup := prepareIntegrationTest(ctx, t, nil)
  1072. defer cleanup()
  1073. newRow := func(vals []interface{}) *Row {
  1074. row, err := NewRow(make([]string, len(vals)), vals)
  1075. if err != nil {
  1076. t.Fatal(err)
  1077. }
  1078. return row
  1079. }
  1080. tests := []struct {
  1081. expr string
  1082. want interface{}
  1083. }{
  1084. {"1", int64(1)},
  1085. {"[1, 2, 3]", []NullInt64{{1, true}, {2, true}, {3, true}}},
  1086. {"[1, NULL, 3]", []NullInt64{{1, true}, {0, false}, {3, true}}},
  1087. {"IEEE_DIVIDE(1, 0)", math.Inf(1)},
  1088. {"IEEE_DIVIDE(-1, 0)", math.Inf(-1)},
  1089. {"IEEE_DIVIDE(0, 0)", math.NaN()},
  1090. // TODO(jba): add IEEE_DIVIDE(0, 0) to the following array when we have a better equality predicate.
  1091. {"[IEEE_DIVIDE(1, 0), IEEE_DIVIDE(-1, 0)]", []NullFloat64{{math.Inf(1), true}, {math.Inf(-1), true}}},
  1092. {"ARRAY(SELECT AS STRUCT * FROM (SELECT 'a', 1) WHERE 0 = 1)", []NullRow{}},
  1093. {"ARRAY(SELECT STRUCT(1, 2))", []NullRow{{Row: *newRow([]interface{}{1, 2}), Valid: true}}},
  1094. }
  1095. for _, test := range tests {
  1096. iter := client.Single().Query(ctx, Statement{SQL: "SELECT " + test.expr})
  1097. defer iter.Stop()
  1098. row, err := iter.Next()
  1099. if err != nil {
  1100. t.Errorf("%q: %v", test.expr, err)
  1101. continue
  1102. }
  1103. // Create new instance of type of test.want.
  1104. gotp := reflect.New(reflect.TypeOf(test.want))
  1105. if err := row.Column(0, gotp.Interface()); err != nil {
  1106. t.Errorf("%q: Column returned error %v", test.expr, err)
  1107. continue
  1108. }
  1109. got := reflect.Indirect(gotp).Interface()
  1110. // TODO(jba): remove isNaN special case when we have a better equality predicate.
  1111. if isNaN(got) && isNaN(test.want) {
  1112. continue
  1113. }
  1114. if !testEqual(got, test.want) {
  1115. t.Errorf("%q\n got %#v\nwant %#v", test.expr, got, test.want)
  1116. }
  1117. }
  1118. }
  1119. func TestIntegration_QueryStats(t *testing.T) {
  1120. ctx := context.Background()
  1121. client, _, cleanup := prepareIntegrationTest(ctx, t, singerDBStatements)
  1122. defer cleanup()
  1123. accounts := []*Mutation{
  1124. Insert("Accounts", []string{"AccountId", "Nickname", "Balance"}, []interface{}{int64(1), "Foo", int64(50)}),
  1125. Insert("Accounts", []string{"AccountId", "Nickname", "Balance"}, []interface{}{int64(2), "Bar", int64(1)}),
  1126. }
  1127. if _, err := client.Apply(ctx, accounts, ApplyAtLeastOnce()); err != nil {
  1128. t.Fatal(err)
  1129. }
  1130. const sql = "SELECT Balance FROM Accounts"
  1131. qp, err := client.Single().AnalyzeQuery(ctx, Statement{sql, nil})
  1132. if err != nil {
  1133. t.Fatal(err)
  1134. }
  1135. if len(qp.PlanNodes) == 0 {
  1136. t.Error("got zero plan nodes, expected at least one")
  1137. }
  1138. iter := client.Single().QueryWithStats(ctx, Statement{sql, nil})
  1139. defer iter.Stop()
  1140. for {
  1141. _, err := iter.Next()
  1142. if err == iterator.Done {
  1143. break
  1144. }
  1145. if err != nil {
  1146. t.Fatal(err)
  1147. }
  1148. }
  1149. if iter.QueryPlan == nil {
  1150. t.Error("got nil QueryPlan, expected one")
  1151. }
  1152. if iter.QueryStats == nil {
  1153. t.Error("got nil QueryStats, expected some")
  1154. }
  1155. }
  1156. func TestIntegration_InvalidDatabase(t *testing.T) {
  1157. if testProjectID == "" {
  1158. t.Skip("Integration tests skipped: GCLOUD_TESTS_GOLANG_PROJECT_ID is missing")
  1159. }
  1160. ctx := context.Background()
  1161. dbPath := fmt.Sprintf("projects/%v/instances/%v/databases/invalid", testProjectID, testInstanceID)
  1162. c, err := createClient(ctx, dbPath)
  1163. // Client creation should succeed even if the database is invalid.
  1164. if err != nil {
  1165. t.Fatal(err)
  1166. }
  1167. _, err = c.Single().ReadRow(ctx, "TestTable", Key{1}, []string{"col1"})
  1168. if msg, ok := matchError(err, codes.NotFound, ""); !ok {
  1169. t.Fatal(msg)
  1170. }
  1171. }
  1172. func TestIntegration_ReadErrors(t *testing.T) {
  1173. ctx := context.Background()
  1174. client, _, cleanup := prepareIntegrationTest(ctx, t, readDBStatements)
  1175. defer cleanup()
  1176. // Read over invalid table fails
  1177. _, err := client.Single().ReadRow(ctx, "badTable", Key{1}, []string{"StringValue"})
  1178. if msg, ok := matchError(err, codes.NotFound, "badTable"); !ok {
  1179. t.Error(msg)
  1180. }
  1181. // Read over invalid column fails
  1182. _, err = client.Single().ReadRow(ctx, "TestTable", Key{1}, []string{"badcol"})
  1183. if msg, ok := matchError(err, codes.NotFound, "badcol"); !ok {
  1184. t.Error(msg)
  1185. }
  1186. // Invalid query fails
  1187. iter := client.Single().Query(ctx, Statement{SQL: "SELECT Apples AND Oranges"})
  1188. defer iter.Stop()
  1189. _, err = iter.Next()
  1190. if msg, ok := matchError(err, codes.InvalidArgument, "unrecognized name"); !ok {
  1191. t.Error(msg)
  1192. }
  1193. // Read should fail on cancellation.
  1194. cctx, cancel := context.WithCancel(ctx)
  1195. cancel()
  1196. _, err = client.Single().ReadRow(cctx, "TestTable", Key{1}, []string{"StringValue"})
  1197. if msg, ok := matchError(err, codes.Canceled, ""); !ok {
  1198. t.Error(msg)
  1199. }
  1200. // Read should fail if deadline exceeded.
  1201. dctx, cancel := context.WithTimeout(ctx, time.Nanosecond)
  1202. defer cancel()
  1203. <-dctx.Done()
  1204. _, err = client.Single().ReadRow(dctx, "TestTable", Key{1}, []string{"StringValue"})
  1205. if msg, ok := matchError(err, codes.DeadlineExceeded, ""); !ok {
  1206. t.Error(msg)
  1207. }
  1208. }
  1209. // Test TransactionRunner. Test that transactions are aborted and retried as expected.
  1210. func TestIntegration_TransactionRunner(t *testing.T) {
  1211. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
  1212. defer cancel()
  1213. client, _, cleanup := prepareIntegrationTest(ctx, t, singerDBStatements)
  1214. defer cleanup()
  1215. // Test 1: User error should abort the transaction.
  1216. _, _ = client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error {
  1217. tx.BufferWrite([]*Mutation{
  1218. Insert("Accounts", []string{"AccountId", "Nickname", "Balance"}, []interface{}{int64(1), "Foo", int64(50)})})
  1219. return errors.New("user error")
  1220. })
  1221. // Empty read.
  1222. rows, err := readAllTestTable(client.Single().Read(ctx, "Accounts", Key{1}, []string{"AccountId", "Nickname", "Balance"}))
  1223. if err != nil {
  1224. t.Fatal(err)
  1225. }
  1226. if got, want := len(rows), 0; got != want {
  1227. t.Errorf("Empty read, got %d, want %d.", got, want)
  1228. }
  1229. // Test 2: Expect abort and retry.
  1230. // We run two ReadWriteTransactions concurrently and make txn1 abort txn2 by committing writes to the column txn2 have read,
  1231. // and expect the following read to abort and txn2 retries.
  1232. // Set up two accounts
  1233. accounts := []*Mutation{
  1234. Insert("Accounts", []string{"AccountId", "Balance"}, []interface{}{int64(1), int64(0)}),
  1235. Insert("Accounts", []string{"AccountId", "Balance"}, []interface{}{int64(2), int64(1)}),
  1236. }
  1237. if _, err := client.Apply(ctx, accounts, ApplyAtLeastOnce()); err != nil {
  1238. t.Fatal(err)
  1239. }
  1240. var (
  1241. cTxn1Start = make(chan struct{})
  1242. cTxn1Commit = make(chan struct{})
  1243. cTxn2Start = make(chan struct{})
  1244. wg sync.WaitGroup
  1245. )
  1246. // read balance, check error if we don't expect abort.
  1247. readBalance := func(tx interface {
  1248. ReadRow(ctx context.Context, table string, key Key, columns []string) (*Row, error)
  1249. }, key int64, expectAbort bool) (int64, error) {
  1250. var b int64
  1251. r, e := tx.ReadRow(ctx, "Accounts", Key{int64(key)}, []string{"Balance"})
  1252. if e != nil {
  1253. if expectAbort && !isAbortErr(e) {
  1254. t.Errorf("ReadRow got %v, want Abort error.", e)
  1255. }
  1256. return b, e
  1257. }
  1258. if ce := r.Column(0, &b); ce != nil {
  1259. return b, ce
  1260. }
  1261. return b, nil
  1262. }
  1263. wg.Add(2)
  1264. // Txn 1
  1265. go func() {
  1266. defer wg.Done()
  1267. var once sync.Once
  1268. _, e := client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error {
  1269. b, e := readBalance(tx, 1, false)
  1270. if e != nil {
  1271. return e
  1272. }
  1273. // txn 1 can abort, in that case we skip closing the channel on retry.
  1274. once.Do(func() { close(cTxn1Start) })
  1275. e = tx.BufferWrite([]*Mutation{
  1276. Update("Accounts", []string{"AccountId", "Balance"}, []interface{}{int64(1), int64(b + 1)})})
  1277. if e != nil {
  1278. return e
  1279. }
  1280. // Wait for second transaction.
  1281. <-cTxn2Start
  1282. return nil
  1283. })
  1284. close(cTxn1Commit)
  1285. if e != nil {
  1286. t.Errorf("Transaction 1 commit, got %v, want nil.", e)
  1287. }
  1288. }()
  1289. // Txn 2
  1290. go func() {
  1291. // Wait until txn 1 starts.
  1292. <-cTxn1Start
  1293. defer wg.Done()
  1294. var (
  1295. once sync.Once
  1296. b1 int64
  1297. b2 int64
  1298. e error
  1299. )
  1300. _, e = client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error {
  1301. if b1, e = readBalance(tx, 1, false); e != nil {
  1302. return e
  1303. }
  1304. // Skip closing channel on retry.
  1305. once.Do(func() { close(cTxn2Start) })
  1306. // Wait until txn 1 successfully commits.
  1307. <-cTxn1Commit
  1308. // Txn1 has committed and written a balance to the account.
  1309. // Now this transaction (txn2) reads and re-writes the balance.
  1310. // The first time through, it will abort because it overlaps with txn1.
  1311. // Then it will retry after txn1 commits, and succeed.
  1312. if b2, e = readBalance(tx, 2, true); e != nil {
  1313. return e
  1314. }
  1315. return tx.BufferWrite([]*Mutation{
  1316. Update("Accounts", []string{"AccountId", "Balance"}, []interface{}{int64(2), int64(b1 + b2)})})
  1317. })
  1318. if e != nil {
  1319. t.Errorf("Transaction 2 commit, got %v, want nil.", e)
  1320. }
  1321. }()
  1322. wg.Wait()
  1323. // Check that both transactions' effects are visible.
  1324. for i := int64(1); i <= int64(2); i++ {
  1325. if b, e := readBalance(client.Single(), i, false); e != nil {
  1326. t.Fatalf("ReadBalance for key %d error %v.", i, e)
  1327. } else if b != i {
  1328. t.Errorf("Balance for key %d, got %d, want %d.", i, b, i)
  1329. }
  1330. }
  1331. }
  1332. // Test PartitionQuery of BatchReadOnlyTransaction, create partitions then
  1333. // serialize and deserialize both transaction and partition to be used in
  1334. // execution on another client, and compare results.
  1335. func TestIntegration_BatchQuery(t *testing.T) {
  1336. // Set up testing environment.
  1337. var (
  1338. client2 *Client
  1339. err error
  1340. )
  1341. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
  1342. defer cancel()
  1343. client, dbPath, cleanup := prepareIntegrationTest(ctx, t, simpleDBStatements)
  1344. defer cleanup()
  1345. if err = populate(ctx, client); err != nil {
  1346. t.Fatal(err)
  1347. }
  1348. if client2, err = createClient(ctx, dbPath); err != nil {
  1349. t.Fatal(err)
  1350. }
  1351. defer client2.Close()
  1352. // PartitionQuery
  1353. var (
  1354. txn *BatchReadOnlyTransaction
  1355. partitions []*Partition
  1356. stmt = Statement{SQL: "SELECT * FROM test;"}
  1357. )
  1358. if txn, err = client.BatchReadOnlyTransaction(ctx, StrongRead()); err != nil {
  1359. t.Fatal(err)
  1360. }
  1361. defer txn.Cleanup(ctx)
  1362. if partitions, err = txn.PartitionQuery(ctx, stmt, PartitionOptions{0, 3}); err != nil {
  1363. t.Fatal(err)
  1364. }
  1365. // Reconstruct BatchReadOnlyTransactionID and execute partitions
  1366. var (
  1367. tid2 BatchReadOnlyTransactionID
  1368. data []byte
  1369. gotResult bool // if we get matching result from two separate txns
  1370. )
  1371. if data, err = txn.ID.MarshalBinary(); err != nil {
  1372. t.Fatalf("encoding failed %v", err)
  1373. }
  1374. if err = tid2.UnmarshalBinary(data); err != nil {
  1375. t.Fatalf("decoding failed %v", err)
  1376. }
  1377. txn2 := client2.BatchReadOnlyTransactionFromID(tid2)
  1378. // Execute Partitions and compare results
  1379. for i, p := range partitions {
  1380. iter := txn.Execute(ctx, p)
  1381. defer iter.Stop()
  1382. p2 := serdesPartition(t, i, p)
  1383. iter2 := txn2.Execute(ctx, &p2)
  1384. defer iter2.Stop()
  1385. row1, err1 := iter.Next()
  1386. row2, err2 := iter2.Next()
  1387. if err1 != err2 {
  1388. t.Fatalf("execution failed for different reasons: %v, %v", err1, err2)
  1389. continue
  1390. }
  1391. if !testEqual(row1, row2) {
  1392. t.Fatalf("execution returned different values: %v, %v", row1, row2)
  1393. continue
  1394. }
  1395. if row1 == nil {
  1396. continue
  1397. }
  1398. var a, b string
  1399. if err = row1.Columns(&a, &b); err != nil {
  1400. t.Fatalf("failed to parse row %v", err)
  1401. continue
  1402. }
  1403. if a == str1 && b == str2 {
  1404. gotResult = true
  1405. }
  1406. }
  1407. if !gotResult {
  1408. t.Fatalf("execution didn't return expected values")
  1409. }
  1410. }
  1411. // Test PartitionRead of BatchReadOnlyTransaction, similar to TestBatchQuery
  1412. func TestIntegration_BatchRead(t *testing.T) {
  1413. // Set up testing environment.
  1414. var (
  1415. client2 *Client
  1416. err error
  1417. )
  1418. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
  1419. defer cancel()
  1420. client, dbPath, cleanup := prepareIntegrationTest(ctx, t, simpleDBStatements)
  1421. defer cleanup()
  1422. if err = populate(ctx, client); err != nil {
  1423. t.Fatal(err)
  1424. }
  1425. if client2, err = createClient(ctx, dbPath); err != nil {
  1426. t.Fatal(err)
  1427. }
  1428. defer client2.Close()
  1429. // PartitionRead
  1430. var (
  1431. txn *BatchReadOnlyTransaction
  1432. partitions []*Partition
  1433. )
  1434. if txn, err = client.BatchReadOnlyTransaction(ctx, StrongRead()); err != nil {
  1435. t.Fatal(err)
  1436. }
  1437. defer txn.Cleanup(ctx)
  1438. if partitions, err = txn.PartitionRead(ctx, "test", AllKeys(), simpleDBTableColumns, PartitionOptions{0, 3}); err != nil {
  1439. t.Fatal(err)
  1440. }
  1441. // Reconstruct BatchReadOnlyTransactionID and execute partitions
  1442. var (
  1443. tid2 BatchReadOnlyTransactionID
  1444. data []byte
  1445. gotResult bool // if we get matching result from two separate txns
  1446. )
  1447. if data, err = txn.ID.MarshalBinary(); err != nil {
  1448. t.Fatalf("encoding failed %v", err)
  1449. }
  1450. if err = tid2.UnmarshalBinary(data); err != nil {
  1451. t.Fatalf("decoding failed %v", err)
  1452. }
  1453. txn2 := client2.BatchReadOnlyTransactionFromID(tid2)
  1454. // Execute Partitions and compare results
  1455. for i, p := range partitions {
  1456. iter := txn.Execute(ctx, p)
  1457. defer iter.Stop()
  1458. p2 := serdesPartition(t, i, p)
  1459. iter2 := txn2.Execute(ctx, &p2)
  1460. defer iter2.Stop()
  1461. row1, err1 := iter.Next()
  1462. row2, err2 := iter2.Next()
  1463. if err1 != err2 {
  1464. t.Fatalf("execution failed for different reasons: %v, %v", err1, err2)
  1465. continue
  1466. }
  1467. if !testEqual(row1, row2) {
  1468. t.Fatalf("execution returned different values: %v, %v", row1, row2)
  1469. continue
  1470. }
  1471. if row1 == nil {
  1472. continue
  1473. }
  1474. var a, b string
  1475. if err = row1.Columns(&a, &b); err != nil {
  1476. t.Fatalf("failed to parse row %v", err)
  1477. continue
  1478. }
  1479. if a == str1 && b == str2 {
  1480. gotResult = true
  1481. }
  1482. }
  1483. if !gotResult {
  1484. t.Fatalf("execution didn't return expected values")
  1485. }
  1486. }
  1487. // Test normal txReadEnv method on BatchReadOnlyTransaction.
  1488. func TestIntegration_BROTNormal(t *testing.T) {
  1489. // Set up testing environment and create txn.
  1490. var (
  1491. txn *BatchReadOnlyTransaction
  1492. err error
  1493. row *Row
  1494. i int64
  1495. )
  1496. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
  1497. defer cancel()
  1498. client, _, cleanup := prepareIntegrationTest(ctx, t, simpleDBStatements)
  1499. defer cleanup()
  1500. if txn, err = client.BatchReadOnlyTransaction(ctx, StrongRead()); err != nil {
  1501. t.Fatal(err)
  1502. }
  1503. defer txn.Cleanup(ctx)
  1504. if _, err := txn.PartitionRead(ctx, "test", AllKeys(), simpleDBTableColumns, PartitionOptions{0, 3}); err != nil {
  1505. t.Fatal(err)
  1506. }
  1507. // Normal query should work with BatchReadOnlyTransaction
  1508. stmt2 := Statement{SQL: "SELECT 1"}
  1509. iter := txn.Query(ctx, stmt2)
  1510. defer iter.Stop()
  1511. row, err = iter.Next()
  1512. if err != nil {
  1513. t.Errorf("query failed with %v", err)
  1514. }
  1515. if err = row.Columns(&i); err != nil {
  1516. t.Errorf("failed to parse row %v", err)
  1517. }
  1518. }
  1519. func TestIntegration_CommitTimestamp(t *testing.T) {
  1520. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
  1521. defer cancel()
  1522. client, _, cleanup := prepareIntegrationTest(ctx, t, ctsDBStatements)
  1523. defer cleanup()
  1524. type testTableRow struct {
  1525. Key string
  1526. Ts NullTime
  1527. }
  1528. var (
  1529. cts1, cts2, ts1, ts2 time.Time
  1530. err error
  1531. )
  1532. // Apply mutation in sequence, expect to see commit timestamp in good order, check also the commit timestamp returned
  1533. for _, it := range []struct {
  1534. k string
  1535. t *time.Time
  1536. }{
  1537. {"a", &cts1},
  1538. {"b", &cts2},
  1539. } {
  1540. tt := testTableRow{Key: it.k, Ts: NullTime{CommitTimestamp, true}}
  1541. m, err := InsertStruct("TestTable", tt)
  1542. if err != nil {
  1543. t.Fatal(err)
  1544. }
  1545. *it.t, err = client.Apply(ctx, []*Mutation{m}, ApplyAtLeastOnce())
  1546. if err != nil {
  1547. t.Fatal(err)
  1548. }
  1549. }
  1550. txn := client.ReadOnlyTransaction()
  1551. for _, it := range []struct {
  1552. k string
  1553. t *time.Time
  1554. }{
  1555. {"a", &ts1},
  1556. {"b", &ts2},
  1557. } {
  1558. if r, e := txn.ReadRow(ctx, "TestTable", Key{it.k}, []string{"Ts"}); e != nil {
  1559. t.Fatal(err)
  1560. } else {
  1561. var got testTableRow
  1562. if err := r.ToStruct(&got); err != nil {
  1563. t.Fatal(err)
  1564. }
  1565. *it.t = got.Ts.Time
  1566. }
  1567. }
  1568. if !cts1.Equal(ts1) {
  1569. t.Errorf("Expect commit timestamp returned and read to match for txn1, got %v and %v.", cts1, ts1)
  1570. }
  1571. if !cts2.Equal(ts2) {
  1572. t.Errorf("Expect commit timestamp returned and read to match for txn2, got %v and %v.", cts2, ts2)
  1573. }
  1574. // Try writing a timestamp in the future to commit timestamp, expect error
  1575. _, err = client.Apply(ctx, []*Mutation{InsertOrUpdate("TestTable", []string{"Key", "Ts"}, []interface{}{"a", time.Now().Add(time.Hour)})}, ApplyAtLeastOnce())
  1576. if msg, ok := matchError(err, codes.FailedPrecondition, "Cannot write timestamps in the future"); !ok {
  1577. t.Error(msg)
  1578. }
  1579. }
  1580. func TestIntegration_DML(t *testing.T) {
  1581. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
  1582. defer cancel()
  1583. client, _, cleanup := prepareIntegrationTest(ctx, t, singerDBStatements)
  1584. defer cleanup()
  1585. // Function that reads a single row's first name from within a transaction.
  1586. readFirstName := func(tx *ReadWriteTransaction, key int) (string, error) {
  1587. row, err := tx.ReadRow(ctx, "Singers", Key{key}, []string{"FirstName"})
  1588. if err != nil {
  1589. return "", err
  1590. }
  1591. var fn string
  1592. if err := row.Column(0, &fn); err != nil {
  1593. return "", err
  1594. }
  1595. return fn, nil
  1596. }
  1597. // Function that reads multiple rows' first names from outside a read/write transaction.
  1598. readFirstNames := func(keys ...int) []string {
  1599. var ks []KeySet
  1600. for _, k := range keys {
  1601. ks = append(ks, Key{k})
  1602. }
  1603. iter := client.Single().Read(ctx, "Singers", KeySets(ks...), []string{"FirstName"})
  1604. var got []string
  1605. var fn string
  1606. err := iter.Do(func(row *Row) error {
  1607. if err := row.Column(0, &fn); err != nil {
  1608. return err
  1609. }
  1610. got = append(got, fn)
  1611. return nil
  1612. })
  1613. if err != nil {
  1614. t.Fatalf("readFirstNames(%v): %v", keys, err)
  1615. }
  1616. return got
  1617. }
  1618. // Use ReadWriteTransaction.Query to execute a DML statement.
  1619. _, err := client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error {
  1620. iter := tx.Query(ctx, Statement{
  1621. SQL: `INSERT INTO Singers (SingerId, FirstName, LastName) VALUES (1, "Umm", "Kulthum")`,
  1622. })
  1623. defer iter.Stop()
  1624. if row, err := iter.Next(); err != iterator.Done {
  1625. t.Fatalf("got results from iterator, want none: %#v, err = %v\n", row, err)
  1626. }
  1627. if iter.RowCount != 1 {
  1628. t.Errorf("row count: got %d, want 1", iter.RowCount)
  1629. }
  1630. // The results of the DML statement should be visible to the transaction.
  1631. got, err := readFirstName(tx, 1)
  1632. if err != nil {
  1633. return err
  1634. }
  1635. if want := "Umm"; got != want {
  1636. t.Errorf("got %q, want %q", got, want)
  1637. }
  1638. return nil
  1639. })
  1640. if err != nil {
  1641. t.Fatal(err)
  1642. }
  1643. // Use ReadWriteTransaction.Update to execute a DML statement.
  1644. _, err = client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error {
  1645. count, err := tx.Update(ctx, Statement{
  1646. SQL: `Insert INTO Singers (SingerId, FirstName, LastName) VALUES (2, "Eduard", "Khil")`,
  1647. })
  1648. if err != nil {
  1649. t.Fatal(err)
  1650. }
  1651. if count != 1 {
  1652. t.Errorf("row count: got %d, want 1", count)
  1653. }
  1654. got, err := readFirstName(tx, 2)
  1655. if err != nil {
  1656. return err
  1657. }
  1658. if want := "Eduard"; got != want {
  1659. t.Errorf("got %q, want %q", got, want)
  1660. }
  1661. return nil
  1662. })
  1663. if err != nil {
  1664. t.Fatal(err)
  1665. }
  1666. // Roll back a DML statement and confirm that it didn't happen.
  1667. var fail = errors.New("fail")
  1668. _, err = client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error {
  1669. _, err := tx.Update(ctx, Statement{
  1670. SQL: `INSERT INTO Singers (SingerId, FirstName, LastName) VALUES (3, "Audra", "McDonald")`,
  1671. })
  1672. if err != nil {
  1673. return err
  1674. }
  1675. return fail
  1676. })
  1677. if err != fail {
  1678. t.Fatalf("rolling back: got error %v, want the error 'fail'", err)
  1679. }
  1680. _, err = client.Single().ReadRow(ctx, "Singers", Key{3}, []string{"FirstName"})
  1681. if got, want := ErrCode(err), codes.NotFound; got != want {
  1682. t.Errorf("got %s, want %s", got, want)
  1683. }
  1684. // Run two DML statements in the same transaction.
  1685. _, err = client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error {
  1686. _, err := tx.Update(ctx, Statement{SQL: `UPDATE Singers SET FirstName = "Oum" WHERE SingerId = 1`})
  1687. if err != nil {
  1688. return err
  1689. }
  1690. _, err = tx.Update(ctx, Statement{SQL: `UPDATE Singers SET FirstName = "Eddie" WHERE SingerId = 2`})
  1691. if err != nil {
  1692. return err
  1693. }
  1694. return nil
  1695. })
  1696. if err != nil {
  1697. t.Fatal(err)
  1698. }
  1699. got := readFirstNames(1, 2)
  1700. want := []string{"Oum", "Eddie"}
  1701. if !testEqual(got, want) {
  1702. t.Errorf("got %v, want %v", got, want)
  1703. }
  1704. // Run a DML statement and an ordinary mutation in the same transaction.
  1705. _, err = client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error {
  1706. _, err := tx.Update(ctx, Statement{
  1707. SQL: `INSERT INTO Singers (SingerId, FirstName, LastName) VALUES (3, "Audra", "McDonald")`,
  1708. })
  1709. if err != nil {
  1710. return err
  1711. }
  1712. tx.BufferWrite([]*Mutation{
  1713. Insert("Singers", []string{"SingerId", "FirstName", "LastName"},
  1714. []interface{}{4, "Andy", "Irvine"}),
  1715. })
  1716. return nil
  1717. })
  1718. if err != nil {
  1719. t.Fatal(err)
  1720. }
  1721. got = readFirstNames(3, 4)
  1722. want = []string{"Audra", "Andy"}
  1723. if !testEqual(got, want) {
  1724. t.Errorf("got %v, want %v", got, want)
  1725. }
  1726. // Attempt to run a query using update.
  1727. _, err = client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error {
  1728. _, err := tx.Update(ctx, Statement{SQL: `SELECT FirstName from Singers`})
  1729. return err
  1730. })
  1731. if got, want := ErrCode(err), codes.InvalidArgument; got != want {
  1732. t.Errorf("got %s, want %s", got, want)
  1733. }
  1734. }
  1735. func TestIntegration_StructParametersBind(t *testing.T) {
  1736. t.Parallel()
  1737. ctx := context.Background()
  1738. client, _, cleanup := prepareIntegrationTest(ctx, t, nil)
  1739. defer cleanup()
  1740. type tRow []interface{}
  1741. type tRows []struct{ trow tRow }
  1742. type allFields struct {
  1743. Stringf string
  1744. Intf int
  1745. Boolf bool
  1746. Floatf float64
  1747. Bytef []byte
  1748. Timef time.Time
  1749. Datef civil.Date
  1750. }
  1751. allColumns := []string{
  1752. "Stringf",
  1753. "Intf",
  1754. "Boolf",
  1755. "Floatf",
  1756. "Bytef",
  1757. "Timef",
  1758. "Datef",
  1759. }
  1760. s1 := allFields{"abc", 300, false, 3.45, []byte("foo"), t1, d1}
  1761. s2 := allFields{"def", -300, false, -3.45, []byte("bar"), t2, d2}
  1762. dynamicStructType := reflect.StructOf([]reflect.StructField{
  1763. {Name: "A", Type: reflect.TypeOf(t1), Tag: `spanner:"ff1"`},
  1764. })
  1765. s3 := reflect.New(dynamicStructType)
  1766. s3.Elem().Field(0).Set(reflect.ValueOf(t1))
  1767. for i, test := range []struct {
  1768. param interface{}
  1769. sql string
  1770. cols []string
  1771. trows tRows
  1772. }{
  1773. // Struct value.
  1774. {
  1775. s1,
  1776. "SELECT" +
  1777. " @p.Stringf," +
  1778. " @p.Intf," +
  1779. " @p.Boolf," +
  1780. " @p.Floatf," +
  1781. " @p.Bytef," +
  1782. " @p.Timef," +
  1783. " @p.Datef",
  1784. allColumns,
  1785. tRows{
  1786. {tRow{"abc", 300, false, 3.45, []byte("foo"), t1, d1}},
  1787. },
  1788. },
  1789. // Array of struct value.
  1790. {
  1791. []allFields{s1, s2},
  1792. "SELECT * FROM UNNEST(@p)",
  1793. allColumns,
  1794. tRows{
  1795. {tRow{"abc", 300, false, 3.45, []byte("foo"), t1, d1}},
  1796. {tRow{"def", -300, false, -3.45, []byte("bar"), t2, d2}},
  1797. },
  1798. },
  1799. // Null struct.
  1800. {
  1801. (*allFields)(nil),
  1802. "SELECT @p IS NULL",
  1803. []string{""},
  1804. tRows{
  1805. {tRow{true}},
  1806. },
  1807. },
  1808. // Null Array of struct.
  1809. {
  1810. []allFields(nil),
  1811. "SELECT @p IS NULL",
  1812. []string{""},
  1813. tRows{
  1814. {tRow{true}},
  1815. },
  1816. },
  1817. // Empty struct.
  1818. {
  1819. struct{}{},
  1820. "SELECT @p IS NULL ",
  1821. []string{""},
  1822. tRows{
  1823. {tRow{false}},
  1824. },
  1825. },
  1826. // Empty array of struct.
  1827. {
  1828. []allFields{},
  1829. "SELECT * FROM UNNEST(@p) ",
  1830. allColumns,
  1831. tRows{},
  1832. },
  1833. // Struct with duplicate fields.
  1834. {
  1835. struct {
  1836. A int `spanner:"field"`
  1837. B int `spanner:"field"`
  1838. }{10, 20},
  1839. "SELECT * FROM UNNEST([@p]) ",
  1840. []string{"field", "field"},
  1841. tRows{
  1842. {tRow{10, 20}},
  1843. },
  1844. },
  1845. // Struct with unnamed fields.
  1846. {
  1847. struct {
  1848. A string `spanner:""`
  1849. }{"hello"},
  1850. "SELECT * FROM UNNEST([@p]) ",
  1851. []string{""},
  1852. tRows{
  1853. {tRow{"hello"}},
  1854. },
  1855. },
  1856. // Mixed struct.
  1857. {
  1858. struct {
  1859. DynamicStructField interface{} `spanner:"f1"`
  1860. ArrayStructField []*allFields `spanner:"f2"`
  1861. }{
  1862. DynamicStructField: s3.Interface(),
  1863. ArrayStructField: []*allFields{nil},
  1864. },
  1865. "SELECT @p.f1.ff1, ARRAY_LENGTH(@p.f2), @p.f2[OFFSET(0)] IS NULL ",
  1866. []string{"ff1", "", ""},
  1867. tRows{
  1868. {tRow{t1, 1, true}},
  1869. },
  1870. },
  1871. } {
  1872. iter := client.Single().Query(ctx, Statement{
  1873. SQL: test.sql,
  1874. Params: map[string]interface{}{"p": test.param},
  1875. })
  1876. var gotRows []*Row
  1877. err := iter.Do(func(r *Row) error {
  1878. gotRows = append(gotRows, r)
  1879. return nil
  1880. })
  1881. if err != nil {
  1882. t.Errorf("Failed to execute test case %d, error: %v", i, err)
  1883. }
  1884. var wantRows []*Row
  1885. for j, row := range test.trows {
  1886. r, err := NewRow(test.cols, row.trow)
  1887. if err != nil {
  1888. t.Errorf("Invalid row %d in test case %d", j, i)
  1889. }
  1890. wantRows = append(wantRows, r)
  1891. }
  1892. if !testEqual(gotRows, wantRows) {
  1893. t.Errorf("%d: Want result %v, got result %v", i, wantRows, gotRows)
  1894. }
  1895. }
  1896. }
  1897. func TestIntegration_PDML(t *testing.T) {
  1898. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
  1899. defer cancel()
  1900. client, _, cleanup := prepareIntegrationTest(ctx, t, singerDBStatements)
  1901. defer cleanup()
  1902. columns := []string{"SingerId", "FirstName", "LastName"}
  1903. // Populate the Singers table.
  1904. var muts []*Mutation
  1905. for _, row := range [][]interface{}{
  1906. {1, "Umm", "Kulthum"},
  1907. {2, "Eduard", "Khil"},
  1908. {3, "Audra", "McDonald"},
  1909. } {
  1910. muts = append(muts, Insert("Singers", columns, row))
  1911. }
  1912. if _, err := client.Apply(ctx, muts); err != nil {
  1913. t.Fatal(err)
  1914. }
  1915. // Identifiers in PDML statements must be fully qualified.
  1916. // TODO(jba): revisit the above.
  1917. count, err := client.PartitionedUpdate(ctx, Statement{
  1918. SQL: `UPDATE Singers SET Singers.FirstName = "changed" WHERE Singers.SingerId >= 1 AND Singers.SingerId <= 3`,
  1919. })
  1920. if err != nil {
  1921. t.Fatal(err)
  1922. }
  1923. if want := int64(3); count != want {
  1924. t.Errorf("got %d, want %d", count, want)
  1925. }
  1926. got, err := readAll(client.Single().Read(ctx, "Singers", AllKeys(), columns))
  1927. if err != nil {
  1928. t.Fatal(err)
  1929. }
  1930. want := [][]interface{}{
  1931. {int64(1), "changed", "Kulthum"},
  1932. {int64(2), "changed", "Khil"},
  1933. {int64(3), "changed", "McDonald"},
  1934. }
  1935. if !testEqual(got, want) {
  1936. t.Errorf("\ngot %v\nwant%v", got, want)
  1937. }
  1938. }
  1939. // Prepare initializes Cloud Spanner testing DB and clients.
  1940. func prepareIntegrationTest(ctx context.Context, t *testing.T, statements []string) (*Client, string, func()) {
  1941. if admin == nil {
  1942. t.Skip("Integration tests skipped")
  1943. }
  1944. // Construct a unique test DB name.
  1945. dbName := dbNameSpace.New()
  1946. dbPath := fmt.Sprintf("projects/%v/instances/%v/databases/%v", testProjectID, testInstanceID, dbName)
  1947. // Create database and tables.
  1948. op, err := admin.CreateDatabase(ctx, &adminpb.CreateDatabaseRequest{
  1949. Parent: fmt.Sprintf("projects/%v/instances/%v", testProjectID, testInstanceID),
  1950. CreateStatement: "CREATE DATABASE " + dbName,
  1951. ExtraStatements: statements,
  1952. })
  1953. if err != nil {
  1954. t.Fatalf("cannot create testing DB %v: %v", dbPath, err)
  1955. }
  1956. if _, err := op.Wait(ctx); err != nil {
  1957. t.Fatalf("cannot create testing DB %v: %v", dbPath, err)
  1958. }
  1959. client, err := createClient(ctx, dbPath)
  1960. if err != nil {
  1961. t.Fatalf("cannot create data client on DB %v: %v", dbPath, err)
  1962. }
  1963. return client, dbPath, func() {
  1964. client.Close()
  1965. if err := admin.DropDatabase(ctx, &adminpb.DropDatabaseRequest{Database: dbPath}); err != nil {
  1966. t.Logf("failed to drop database %s (error %v), might need a manual removal",
  1967. dbPath, err)
  1968. }
  1969. }
  1970. }
  1971. func cleanupDatabases() {
  1972. if admin == nil {
  1973. // Integration tests skipped.
  1974. return
  1975. }
  1976. ctx := context.Background()
  1977. dbsParent := fmt.Sprintf("projects/%v/instances/%v", testProjectID, testInstanceID)
  1978. dbsIter := admin.ListDatabases(ctx, &adminpb.ListDatabasesRequest{Parent: dbsParent})
  1979. expireAge := 24 * time.Hour
  1980. for {
  1981. db, err := dbsIter.Next()
  1982. if err == iterator.Done {
  1983. break
  1984. }
  1985. if err != nil {
  1986. panic(err)
  1987. }
  1988. // TODO(deklerk) When we have the ability to programmatically create
  1989. // instances, we can create an instance with uid.New and delete all
  1990. // tables in it. For now, we rely on matching prefixes.
  1991. if dbNameSpace.Older(db.Name, expireAge) {
  1992. log.Printf("Dropping database %s", db.Name)
  1993. if err := admin.DropDatabase(ctx, &adminpb.DropDatabaseRequest{Database: db.Name}); err != nil {
  1994. log.Printf("failed to drop database %s (error %v), might need a manual removal",
  1995. db.Name, err)
  1996. }
  1997. }
  1998. }
  1999. }
  2000. func rangeReads(ctx context.Context, t *testing.T, client *Client) {
  2001. checkRange := func(ks KeySet, wantNums ...int) {
  2002. if msg, ok := compareRows(client.Single().Read(ctx, testTable, ks, testTableColumns), wantNums); !ok {
  2003. t.Errorf("key set %+v: %s", ks, msg)
  2004. }
  2005. }
  2006. checkRange(Key{"k1"}, 1)
  2007. checkRange(KeyRange{Key{"k3"}, Key{"k5"}, ClosedOpen}, 3, 4)
  2008. checkRange(KeyRange{Key{"k3"}, Key{"k5"}, ClosedClosed}, 3, 4, 5)
  2009. checkRange(KeyRange{Key{"k3"}, Key{"k5"}, OpenClosed}, 4, 5)
  2010. checkRange(KeyRange{Key{"k3"}, Key{"k5"}, OpenOpen}, 4)
  2011. // Partial key specification.
  2012. checkRange(KeyRange{Key{"k7"}, Key{}, ClosedClosed}, 7, 8, 9)
  2013. checkRange(KeyRange{Key{"k7"}, Key{}, OpenClosed}, 8, 9)
  2014. checkRange(KeyRange{Key{}, Key{"k11"}, ClosedOpen}, 0, 1, 10)
  2015. checkRange(KeyRange{Key{}, Key{"k11"}, ClosedClosed}, 0, 1, 10, 11)
  2016. // The following produce empty ranges.
  2017. // TODO(jba): Consider a multi-part key to illustrate partial key behavior.
  2018. // checkRange(KeyRange{Key{"k7"}, Key{}, ClosedOpen})
  2019. // checkRange(KeyRange{Key{"k7"}, Key{}, OpenOpen})
  2020. // checkRange(KeyRange{Key{}, Key{"k11"}, OpenOpen})
  2021. // checkRange(KeyRange{Key{}, Key{"k11"}, OpenClosed})
  2022. // Prefix is component-wise, not string prefix.
  2023. checkRange(Key{"k1"}.AsPrefix(), 1)
  2024. checkRange(KeyRange{Key{"k1"}, Key{"k2"}, ClosedOpen}, 1, 10, 11, 12, 13, 14)
  2025. checkRange(AllKeys(), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)
  2026. }
  2027. func indexRangeReads(ctx context.Context, t *testing.T, client *Client) {
  2028. checkRange := func(ks KeySet, wantNums ...int) {
  2029. if msg, ok := compareRows(client.Single().ReadUsingIndex(ctx, testTable, testTableIndex, ks, testTableColumns),
  2030. wantNums); !ok {
  2031. t.Errorf("key set %+v: %s", ks, msg)
  2032. }
  2033. }
  2034. checkRange(Key{"v1"}, 1)
  2035. checkRange(KeyRange{Key{"v3"}, Key{"v5"}, ClosedOpen}, 3, 4)
  2036. checkRange(KeyRange{Key{"v3"}, Key{"v5"}, ClosedClosed}, 3, 4, 5)
  2037. checkRange(KeyRange{Key{"v3"}, Key{"v5"}, OpenClosed}, 4, 5)
  2038. checkRange(KeyRange{Key{"v3"}, Key{"v5"}, OpenOpen}, 4)
  2039. // // Partial key specification.
  2040. checkRange(KeyRange{Key{"v7"}, Key{}, ClosedClosed}, 7, 8, 9)
  2041. checkRange(KeyRange{Key{"v7"}, Key{}, OpenClosed}, 8, 9)
  2042. checkRange(KeyRange{Key{}, Key{"v11"}, ClosedOpen}, 0, 1, 10)
  2043. checkRange(KeyRange{Key{}, Key{"v11"}, ClosedClosed}, 0, 1, 10, 11)
  2044. // // The following produce empty ranges.
  2045. // checkRange(KeyRange{Key{"v7"}, Key{}, ClosedOpen})
  2046. // checkRange(KeyRange{Key{"v7"}, Key{}, OpenOpen})
  2047. // checkRange(KeyRange{Key{}, Key{"v11"}, OpenOpen})
  2048. // checkRange(KeyRange{Key{}, Key{"v11"}, OpenClosed})
  2049. // // Prefix is component-wise, not string prefix.
  2050. checkRange(Key{"v1"}.AsPrefix(), 1)
  2051. checkRange(KeyRange{Key{"v1"}, Key{"v2"}, ClosedOpen}, 1, 10, 11, 12, 13, 14)
  2052. checkRange(AllKeys(), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)
  2053. // Read from an index with DESC ordering.
  2054. wantNums := []int{14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
  2055. if msg, ok := compareRows(client.Single().ReadUsingIndex(ctx, testTable, "TestTableByValueDesc", AllKeys(), testTableColumns),
  2056. wantNums); !ok {
  2057. t.Errorf("desc: %s", msg)
  2058. }
  2059. }
  2060. type testTableRow struct{ Key, StringValue string }
  2061. func compareRows(iter *RowIterator, wantNums []int) (string, bool) {
  2062. rows, err := readAllTestTable(iter)
  2063. if err != nil {
  2064. return err.Error(), false
  2065. }
  2066. want := map[string]string{}
  2067. for _, n := range wantNums {
  2068. want[fmt.Sprintf("k%d", n)] = fmt.Sprintf("v%d", n)
  2069. }
  2070. got := map[string]string{}
  2071. for _, r := range rows {
  2072. got[r.Key] = r.StringValue
  2073. }
  2074. if !testEqual(got, want) {
  2075. return fmt.Sprintf("got %v, want %v", got, want), false
  2076. }
  2077. return "", true
  2078. }
  2079. func isNaN(x interface{}) bool {
  2080. f, ok := x.(float64)
  2081. if !ok {
  2082. return false
  2083. }
  2084. return math.IsNaN(f)
  2085. }
  2086. // createClient creates Cloud Spanner data client.
  2087. func createClient(ctx context.Context, dbPath string) (client *Client, err error) {
  2088. client, err = NewClientWithConfig(ctx, dbPath, ClientConfig{
  2089. SessionPoolConfig: SessionPoolConfig{WriteSessions: 0.2},
  2090. }, option.WithTokenSource(testutil.TokenSource(ctx, Scope)), option.WithEndpoint(endpoint))
  2091. if err != nil {
  2092. return nil, fmt.Errorf("cannot create data client on DB %v: %v", dbPath, err)
  2093. }
  2094. return client, nil
  2095. }
  2096. // populate prepares the database with some data.
  2097. func populate(ctx context.Context, client *Client) error {
  2098. // Populate data
  2099. var err error
  2100. m := InsertMap("test", map[string]interface{}{
  2101. "a": str1,
  2102. "b": str2,
  2103. })
  2104. _, err = client.Apply(ctx, []*Mutation{m})
  2105. return err
  2106. }
  2107. func matchError(got error, wantCode codes.Code, wantMsgPart string) (string, bool) {
  2108. if ErrCode(got) != wantCode || !strings.Contains(strings.ToLower(ErrDesc(got)), strings.ToLower(wantMsgPart)) {
  2109. return fmt.Sprintf("got error <%v>\n"+`want <code = %q, "...%s...">`, got, wantCode, wantMsgPart), false
  2110. }
  2111. return "", true
  2112. }
  2113. func rowToValues(r *Row) ([]interface{}, error) {
  2114. var x int64
  2115. var y, z string
  2116. if err := r.Column(0, &x); err != nil {
  2117. return nil, err
  2118. }
  2119. if err := r.Column(1, &y); err != nil {
  2120. return nil, err
  2121. }
  2122. if err := r.Column(2, &z); err != nil {
  2123. return nil, err
  2124. }
  2125. return []interface{}{x, y, z}, nil
  2126. }
  2127. func readAll(iter *RowIterator) ([][]interface{}, error) {
  2128. defer iter.Stop()
  2129. var vals [][]interface{}
  2130. for {
  2131. row, err := iter.Next()
  2132. if err == iterator.Done {
  2133. return vals, nil
  2134. }
  2135. if err != nil {
  2136. return nil, err
  2137. }
  2138. v, err := rowToValues(row)
  2139. if err != nil {
  2140. return nil, err
  2141. }
  2142. vals = append(vals, v)
  2143. }
  2144. }
  2145. func readAllTestTable(iter *RowIterator) ([]testTableRow, error) {
  2146. defer iter.Stop()
  2147. var vals []testTableRow
  2148. for {
  2149. row, err := iter.Next()
  2150. if err == iterator.Done {
  2151. return vals, nil
  2152. }
  2153. if err != nil {
  2154. return nil, err
  2155. }
  2156. var ttr testTableRow
  2157. if err := row.ToStruct(&ttr); err != nil {
  2158. return nil, err
  2159. }
  2160. vals = append(vals, ttr)
  2161. }
  2162. }