3232import com .google .cloud .spanner .SpannerExceptionFactory ;
3333import com .google .cloud .spanner .Struct ;
3434import com .google .cloud .spanner .Type ;
35+ import com .google .spanner .v1 .ResultSetMetadata ;
36+ import com .google .spanner .v1 .StructType ;
3537import java .util .ArrayList ;
3638import java .util .BitSet ;
3739import java .util .Collection ;
@@ -103,7 +105,7 @@ public static Collection<Object[]> parameters() {
103105 return params ;
104106 }
105107
106- private MockedResults setupResults (boolean withErrors ) {
108+ private MockedResults setupResults (boolean withErrors , boolean withEmptyResults ) {
107109 Random random = new Random ();
108110 Connection connection = mock (Connection .class );
109111 List <String > partitions = new ArrayList <>();
@@ -122,10 +124,22 @@ private MockedResults setupResults(boolean withErrors) {
122124 when (connection .runPartition (partition ))
123125 .thenReturn (new ResultSetWithError (ResultSetsHelper .fromProto (proto ), errorIndex ));
124126 } else {
125- when (connection .runPartition (partition )).thenReturn (ResultSetsHelper .fromProto (proto ));
126- try (ResultSet resultSet = ResultSetsHelper .fromProto (proto )) {
127- while (resultSet .next ()) {
128- allRows .add (resultSet .getCurrentRowAsStruct ());
127+ if (withEmptyResults && numPartitions > 1 && index == 0 ) {
128+ when (connection .runPartition (partition ))
129+ .thenReturn (
130+ ResultSetsHelper .fromProto (
131+ com .google .spanner .v1 .ResultSet .newBuilder ()
132+ .setMetadata (
133+ ResultSetMetadata .newBuilder ()
134+ .setRowType (StructType .newBuilder ().build ())
135+ .build ())
136+ .build ()));
137+ } else {
138+ when (connection .runPartition (partition )).thenReturn (ResultSetsHelper .fromProto (proto ));
139+ try (ResultSet resultSet = ResultSetsHelper .fromProto (proto )) {
140+ while (resultSet .next ()) {
141+ allRows .add (resultSet .getCurrentRowAsStruct ());
142+ }
129143 }
130144 }
131145 }
@@ -135,7 +149,7 @@ private MockedResults setupResults(boolean withErrors) {
135149
136150 @ Test
137151 public void testAllResultsAreReturned () {
138- MockedResults results = setupResults (false );
152+ MockedResults results = setupResults (/* withErrors= */ false , /* withEmptyResults= */ false );
139153 BitSet rowsFound = new BitSet (results .allRows .size ());
140154 try (MergedResultSet resultSet =
141155 new MergedResultSet (results .connection , results .partitions , maxParallelism )) {
@@ -170,7 +184,7 @@ public void testAllResultsAreReturned() {
170184
171185 @ Test
172186 public void testResultSetStopsAfterFirstError () {
173- MockedResults results = setupResults (true );
187+ MockedResults results = setupResults (/* withErrors= */ true , /* withEmptyResults= */ false );
174188 try (MergedResultSet resultSet =
175189 new MergedResultSet (results .connection , results .partitions , maxParallelism )) {
176190 if (numPartitions > 0 ) {
@@ -194,6 +208,40 @@ public void testResultSetStopsAfterFirstError() {
194208 }
195209 }
196210
211+ @ Test
212+ public void testResultSetReturnsNonEmptyMetadata () {
213+ MockedResults results = setupResults (/* withErrors= */ false , /* withEmptyResults= */ true );
214+ BitSet rowsFound = new BitSet (results .allRows .size ());
215+ try (MergedResultSet resultSet =
216+ new MergedResultSet (results .connection , results .partitions , maxParallelism )) {
217+ if (numPartitions > 0 ) {
218+ assertNotNull (resultSet .getMetadata ());
219+ assertEquals (26 , resultSet .getMetadata ().getRowType ().getFieldsCount ());
220+ }
221+ while (resultSet .next ()) {
222+ assertRowExists (results .allRows , resultSet .getCurrentRowAsStruct (), rowsFound );
223+ }
224+ if (numPartitions == 0 ) {
225+ assertEquals (0 , resultSet .getColumnCount ());
226+ } else {
227+ assertEquals (26 , resultSet .getColumnCount ());
228+ assertEquals (Type .bool (), resultSet .getColumnType (0 ));
229+ assertEquals (Type .bool (), resultSet .getColumnType ("COL0" ));
230+ assertEquals (10 , resultSet .getColumnIndex ("COL10" ));
231+ }
232+ // Check that all rows were found.
233+ assertEquals (results .allRows .size (), rowsFound .nextClearBit (0 ));
234+ // Check extended metadata.
235+ assertEquals (numPartitions , resultSet .getNumPartitions ());
236+ if (maxParallelism > 0 ) {
237+ assertEquals (Math .min (numPartitions , maxParallelism ), resultSet .getParallelism ());
238+ } else {
239+ int processors = Runtime .getRuntime ().availableProcessors ();
240+ assertEquals (Math .min (numPartitions , processors ), resultSet .getParallelism ());
241+ }
242+ }
243+ }
244+
197245 private void assertRowExists (List <Struct > expectedRows , Struct row , BitSet rowsFound ) {
198246 for (int i = 0 ; i < expectedRows .size (); i ++) {
199247 if (row .equals (expectedRows .get (i ))) {
0 commit comments