func TestQueryAbortedHalfway_WithDifferentResultsInSecondHalf(t *testing.T) {
	t.Parallel()

	db, server, teardown := setupTestDBConnection(t)
	defer teardown()
	// Ensure that the second call to Next() will fail with an Aborted error.
	server.TestSpanner.AddPartialResultSetError(testutil.SelectFooFromBar, testutil.PartialResultSetExecutionTime{
		ResumeToken: testutil.EncodeResumeToken(2),
		Err:         status.Error(codes.Aborted, "Aborted"),
	})

	ctx := context.Background()
	tx, err := db.BeginTx(ctx, &sql.TxOptions{})
	if err != nil {
		t.Fatalf("begin failed: %v", err)
	}
	rows, err := tx.QueryContext(ctx, testutil.SelectFooFromBar)
	if err != nil {
		t.Fatalf("query failed: %v", err)
	}

	// The first row should succeed.
	next := rows.Next()
	if !next {
		t.Fatalf("next result mismatch\nGot: %v\nWant: %v", next, true)
	}
	err = rows.Err()
	if err != nil {
		t.Fatalf("next failed: %v", err)
	}
	var val int64
	err = rows.Scan(&val)
	if err != nil {
		t.Fatalf("scan failed: %v", err)
	}
	if g, w := val, int64(1); g != w {
		t.Fatalf("value mismatch\nGot: %v\nWant: %v", g, w)
	}
	// Replace the original query result with a new one with a different value
	// for the second row. This should not cause the transaction to fail with an
	// ErrAbortedDueToConcurrentModification error as the result has not yet
	// been seen by the user.
	server.TestSpanner.PutStatementResult(testutil.SelectFooFromBar, &testutil.StatementResult{
		Type:      testutil.StatementResultResultSet,
		ResultSet: testutil.CreateSingleColumnResultSet([]int64{1, 3}, "FOO"),
	})

	// This should succeed and return the new result.
	next = rows.Next()
	if !next {
		t.Fatalf("next result mismatch\nGot: %v\nWant: %v", next, true)
	}
	err = rows.Err()
	if err != nil {
		t.Fatalf("next failed: %v", err)
	}
	err = rows.Scan(&val)
	if err != nil {
		t.Fatalf("scan failed: %v", err)
	}
	if g, w := val, int64(3); g != w {
		t.Fatalf("value mismatch\nGot: %v\nWant: %v", g, w)
	}

	reqs := drainRequestsFromServer(server.TestSpanner)
	execReqs := requestsOfType(reqs, reflect.TypeOf(&sppb.ExecuteSqlRequest{}))
	if g, w := len(execReqs), 2; g != w {
		t.Fatalf("execute request count mismatch\nGot: %v\nWant: %v", g, w)
	}
}
// Tests that a change in the results of a result set that has not yet been seen
// by the user does not cause a retry failure.
Tests that a change in the results of a result set that has not yet been seen
by the user does not cause a retry failure.
// Tests that a change in the results of a result set that has not yet been seen // by the user does not cause a retry failure .
func TestQueryAbortedHalfway_WithDifferentResultsInSecondHalf(t *testing.T) {
	t.Parallel()
	db, server, teardown := setupTestDBConnection(t)
	defer teardown()
	server.TestSpanner.AddPartialResultSetError(testutil.SelectFooFromBar, testutil.PartialResultSetExecutionTime{
		ResumeToken: testutil.EncodeResumeToken(2),
		Err:         status.Error(codes.Aborted, "Aborted"),
	})
	ctx := context.Background()
	tx, err := db.BeginTx(ctx, &sql.TxOptions{})
	if err != nil {
		t.Fatalf("begin failed: %v", err)
	}
	rows, err := tx.QueryContext(ctx, testutil.SelectFooFromBar)
	if err != nil {
		t.Fatalf("query failed: %v", err)
	}
	next := rows.Next()
	if !next {
		t.Fatalf("next result mismatch\nGot: %v\nWant: %v", next, true)
	}
	err = rows.Err()
	if err != nil {
		t.Fatalf("next failed: %v", err)
	}
	var val int64
	err = rows.Scan(&val)
	if err != nil {
		t.Fatalf("scan failed: %v", err)
	}
	if g, w := val, int64(1); g != w {
		t.Fatalf("value mismatch\nGot: %v\nWant: %v", g, w)
	}
	server.TestSpanner.PutStatementResult(testutil.SelectFooFromBar, &testutil.StatementResult{
		Type:      testutil.StatementResultResultSet,
		ResultSet: testutil.CreateSingleColumnResultSet([]int64{1, 3}, "FOO"),
	})
	next = rows.Next()
	if !next {
		t.Fatalf("next result mismatch\nGot: %v\nWant: %v", next, true)
	}
	err = rows.Err()
	if err != nil {
		t.Fatalf("next failed: %v", err)
	}
	err = rows.Scan(&val)
	if err != nil {
		t.Fatalf("scan failed: %v", err)
	}
	if g, w := val, int64(3); g != w {
		t.Fatalf("value mismatch\nGot: %v\nWant: %v", g, w)
	}
	reqs := drainRequestsFromServer(server.TestSpanner)
	execReqs := requestsOfType(reqs, reflect.TypeOf(&sppb.ExecuteSqlRequest{}))
	if g, w := len(execReqs), 2; g != w {
		t.Fatalf("execute request count mismatch\nGot: %v\nWant: %v", g, w)
	}
}
func TestQueryAbortedHalfway_WithDifferentResultsInSecondHalf ( t * testing . T ) { t . Parallel ( ) db , server , teardown := setupTestDBConnection ( t ) defer teardown ( ) server . TestSpanner . AddPartialResultSetError ( testutil . SelectFooFromBar , testutil . PartialResultSetExecutionTime { ResumeToken : testutil . EncodeResumeToken ( 2 ) , Err : status . Error ( codes . Aborted , " " ) , } ) ctx := context . Background ( ) tx , err := db . BeginTx ( ctx , & sql . TxOptions { } ) if err != nil { t . Fatalf ( " " , err ) } rows , err := tx . QueryContext ( ctx , testutil . SelectFooFromBar ) if err != nil { t . Fatalf ( " " , err ) } next := rows . Next ( ) if ! next { t . Fatalf ( " \n \n " , next , true ) } err = rows . Err ( ) if err != nil { t . Fatalf ( " " , err ) } var val int64 err = rows . Scan ( & val ) if err != nil { t . Fatalf ( " " , err ) } if g , w := val , int64 ( 1 ) ; g != w { t . Fatalf ( " \n \n " , g , w ) } server . TestSpanner . PutStatementResult ( testutil . SelectFooFromBar , & testutil . StatementResult { Type : testutil . StatementResultResultSet , ResultSet : testutil . CreateSingleColumnResultSet ( [ ] int64 { 1 , 3 } , " " ) , } ) next = rows . Next ( ) if ! next { t . Fatalf ( " \n \n " , next , true ) } err = rows . Err ( ) if err != nil { t . Fatalf ( " " , err ) } err = rows . Scan ( & val ) if err != nil { t . Fatalf ( " " , err ) } if g , w := val , int64 ( 3 ) ; g != w { t . Fatalf ( " \n \n " , g , w ) } reqs := drainRequestsFromServer ( server . TestSpanner ) execReqs := requestsOfType ( reqs , reflect . TypeOf ( & sppb . ExecuteSqlRequest { } ) ) if g , w := len ( execReqs ) , 2 ; g != w { t . Fatalf ( " \n \n " , g , w ) } }
Tests that a change in the results of a result set that has not yet been seen
by the user does not cause a retry failure.
Tests that a change in the results of a result set that has not yet been seen by the user does not cause a retry failure .
// Ensure that the second call to Next() will fail with an Aborted error. // The first row should succeed. // Replace the original query result with a new one with a different value // for the second row. This should not cause the transaction to fail with an // ErrAbortedDueToConcurrentModification error as the result has not yet // been seen by the user. // This should succeed and return the new result.