@@ -16,12 +16,15 @@ package spannerdriver
1616
1717import (
1818 "database/sql/driver"
19+ "errors"
1920 "fmt"
2021 "io"
22+ "reflect"
2123 "testing"
2224
2325 "cloud.google.com/go/spanner"
2426 sppb "cloud.google.com/go/spanner/apiv1/spannerpb"
27+ "github.com/google/go-cmp/cmp"
2528 "google.golang.org/protobuf/types/known/structpb"
2629)
2730
@@ -153,3 +156,70 @@ func TestRows_Next_Unsupported(t *testing.T) {
153156 t .Fatalf ("expected error %q, but got %q" , expectedError , err .Error ())
154157 }
155158}
159+
160+ func TestEmptyRows (t * testing.T ) {
161+ r := createDriverResultRows (& result {}, & ExecOptions {})
162+
163+ if g , w := r .Columns (), []string {"affected_rows" }; ! cmp .Equal (g , w ) {
164+ t .Fatalf ("columns mismatch\n Got: %v\n Want: %v" , g , w )
165+ }
166+ if r .HasNextResultSet () {
167+ t .Fatalf ("unexpected next result set available" )
168+ }
169+ }
170+
171+ func TestEmptyRowsWithMetadataAndStats (t * testing.T ) {
172+ r := createDriverResultRows (& result {}, & ExecOptions {ReturnResultSetMetadata : true , ReturnResultSetStats : true })
173+
174+ // The first result set should contain ResultSetMetadata.
175+ if g , w := r .Columns (), []string {"metadata" }; ! cmp .Equal (g , w ) {
176+ t .Fatalf ("columns mismatch\n Got: %v\n Want: %v" , g , w )
177+ }
178+ values := make ([]driver.Value , 1 )
179+ if err := r .Next (values ); err != nil {
180+ t .Fatalf ("unexpected error from Next: %v" , err )
181+ }
182+ if g , w := reflect .TypeOf (values [0 ]), reflect .TypeOf (& sppb.ResultSetMetadata {}); g != w {
183+ t .Fatalf ("result set metadata type mismatch\n Got: %v\n Want: %v" , g , w )
184+ }
185+ if g , w := r .Next (values ), io .EOF ; ! errors .Is (g , w ) {
186+ t .Fatalf ("next result set mismatch\n Got: %v\n Want: %v" , g , w )
187+ }
188+
189+ // The second result set should contain the actual data (which is empty).
190+ if ! r .HasNextResultSet () {
191+ t .Fatalf ("missing next result set" )
192+ }
193+ if err := r .NextResultSet (); err != nil {
194+ t .Fatalf ("unexpected error from NextResultSet: %v" , err )
195+ }
196+ if g , w := r .Columns (), []string {"affected_rows" }; ! cmp .Equal (g , w ) {
197+ t .Fatalf ("columns mismatch\n Got: %v\n Want: %v" , g , w )
198+ }
199+ // There should be no data.
200+ if g , w := r .Next (values ), io .EOF ; ! errors .Is (g , w ) {
201+ t .Fatalf ("next result set mismatch\n Got: %v\n Want: %v" , g , w )
202+ }
203+
204+ // The third result set should contain ResultSetStats.
205+ if ! r .HasNextResultSet () {
206+ t .Fatalf ("missing next result set" )
207+ }
208+ if err := r .NextResultSet (); err != nil {
209+ t .Fatalf ("unexpected error from NextResultSet: %v" , err )
210+ }
211+ if err := r .Next (values ); err != nil {
212+ t .Fatalf ("unexpected error from Next: %v" , err )
213+ }
214+ if g , w := reflect .TypeOf (values [0 ]), reflect .TypeOf (& sppb.ResultSetStats {}); g != w {
215+ t .Fatalf ("result set stats type mismatch\n Got: %v\n Want: %v" , g , w )
216+ }
217+ if g , w := r .Next (values ), io .EOF ; ! errors .Is (g , w ) {
218+ t .Fatalf ("next result set mismatch\n Got: %v\n Want: %v" , g , w )
219+ }
220+
221+ // There should be no more result sets.
222+ if r .HasNextResultSet () {
223+ t .Fatalf ("unexpected next result set available" )
224+ }
225+ }
0 commit comments