32
32
import com .google .cloud .spanner .SpannerExceptionFactory ;
33
33
import com .google .cloud .spanner .Struct ;
34
34
import com .google .cloud .spanner .Type ;
35
+ import com .google .spanner .v1 .ResultSetMetadata ;
36
+ import com .google .spanner .v1 .StructType ;
35
37
import java .util .ArrayList ;
36
38
import java .util .BitSet ;
37
39
import java .util .Collection ;
@@ -103,7 +105,7 @@ public static Collection<Object[]> parameters() {
103
105
return params ;
104
106
}
105
107
106
- private MockedResults setupResults (boolean withErrors ) {
108
+ private MockedResults setupResults (boolean withErrors , boolean withEmptyResults ) {
107
109
Random random = new Random ();
108
110
Connection connection = mock (Connection .class );
109
111
List <String > partitions = new ArrayList <>();
@@ -122,10 +124,22 @@ private MockedResults setupResults(boolean withErrors) {
122
124
when (connection .runPartition (partition ))
123
125
.thenReturn (new ResultSetWithError (ResultSetsHelper .fromProto (proto ), errorIndex ));
124
126
} 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
+ }
129
143
}
130
144
}
131
145
}
@@ -135,7 +149,7 @@ private MockedResults setupResults(boolean withErrors) {
135
149
136
150
@ Test
137
151
public void testAllResultsAreReturned () {
138
- MockedResults results = setupResults (false );
152
+ MockedResults results = setupResults (/* withErrors= */ false , /* withEmptyResults= */ false );
139
153
BitSet rowsFound = new BitSet (results .allRows .size ());
140
154
try (MergedResultSet resultSet =
141
155
new MergedResultSet (results .connection , results .partitions , maxParallelism )) {
@@ -170,7 +184,7 @@ public void testAllResultsAreReturned() {
170
184
171
185
@ Test
172
186
public void testResultSetStopsAfterFirstError () {
173
- MockedResults results = setupResults (true );
187
+ MockedResults results = setupResults (/* withErrors= */ true , /* withEmptyResults= */ false );
174
188
try (MergedResultSet resultSet =
175
189
new MergedResultSet (results .connection , results .partitions , maxParallelism )) {
176
190
if (numPartitions > 0 ) {
@@ -194,6 +208,40 @@ public void testResultSetStopsAfterFirstError() {
194
208
}
195
209
}
196
210
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
+
197
245
private void assertRowExists (List <Struct > expectedRows , Struct row , BitSet rowsFound ) {
198
246
for (int i = 0 ; i < expectedRows .size (); i ++) {
199
247
if (row .equals (expectedRows .get (i ))) {
0 commit comments