1 // Copyright 2019 Google LLC
2 //
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 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "google/cloud/spanner/row.h"
16 #include "google/cloud/testing_util/assert_ok.h"
17 #include <gmock/gmock.h>
18 #include <tuple>
19 #include <utility>
20
21 namespace google {
22 namespace cloud {
23 namespace spanner {
24 inline namespace SPANNER_CLIENT_NS {
25 namespace {
26
27 using ::testing::HasSubstr;
28
29 // Given a `vector<StatusOr<Row>>` creates a 'Row::Source' object. This is
30 // helpeful for unit testing and letting the test inject a non-OK Status.
MakeRowStreamIteratorSource(std::vector<StatusOr<Row>> const & rows)31 RowStreamIterator::Source MakeRowStreamIteratorSource(
32 std::vector<StatusOr<Row>> const& rows) {
33 std::size_t index = 0;
34 return [=]() mutable -> StatusOr<Row> {
35 if (index == rows.size()) return Row{};
36 return rows[index++];
37 };
38 }
39
40 // Given a `vector<Row>` creates a 'Row::Source' object.
MakeRowStreamIteratorSource(std::vector<Row> const & rows={})41 RowStreamIterator::Source MakeRowStreamIteratorSource(
42 std::vector<Row> const& rows = {}) {
43 return MakeRowStreamIteratorSource(
44 std::vector<StatusOr<Row>>(rows.begin(), rows.end()));
45 }
46
47 class RowRange {
48 public:
RowRange(RowStreamIterator::Source s)49 explicit RowRange(RowStreamIterator::Source s) : s_(std::move(s)) {}
begin()50 RowStreamIterator begin() { return RowStreamIterator(s_); }
51 // NOLINTNEXTLINE(readability-convert-member-functions-to-static)
end()52 RowStreamIterator end() { return RowStreamIterator(); }
53
54 private:
55 RowStreamIterator::Source s_;
56 };
57
TEST(Row,DefaultConstruct)58 TEST(Row, DefaultConstruct) {
59 Row row;
60 EXPECT_EQ(0, row.size());
61 }
62
TEST(Row,ValueSemantics)63 TEST(Row, ValueSemantics) {
64 Row row = MakeTestRow(1, "blah", true);
65
66 Row copy = row;
67 EXPECT_EQ(copy, row);
68
69 copy = row;
70 EXPECT_EQ(copy, row);
71
72 Row move = std::move(row);
73 EXPECT_EQ(move, copy);
74
75 row = copy;
76 move = std::move(row);
77 EXPECT_EQ(move, copy);
78 }
79
TEST(Row,BasicAccessors)80 TEST(Row, BasicAccessors) {
81 auto values = std::vector<Value>{Value(1), Value("blah"), Value(true)};
82 auto columns = std::vector<std::string>{"a", "b", "c"};
83 Row row = MakeTestRow({
84 {columns[0], values[0]}, //
85 {columns[1], values[1]}, //
86 {columns[2], values[2]} //
87 });
88
89 EXPECT_EQ(3, row.size());
90 EXPECT_EQ(values, row.values());
91 EXPECT_EQ(columns, row.columns());
92 EXPECT_EQ(values, std::move(row).values());
93 }
94
TEST(Row,GetByPosition)95 TEST(Row, GetByPosition) {
96 Row row = MakeTestRow(1, "blah", true);
97
98 EXPECT_STATUS_OK(row.get(0));
99 EXPECT_STATUS_OK(row.get(1));
100 EXPECT_STATUS_OK(row.get(2));
101 EXPECT_FALSE(row.get(3).ok());
102
103 EXPECT_EQ(Value(1), *row.get(0));
104 EXPECT_EQ(Value("blah"), *row.get(1));
105 EXPECT_EQ(Value(true), *row.get(2));
106 }
107
TEST(Row,GetByColumnName)108 TEST(Row, GetByColumnName) {
109 Row row = MakeTestRow({
110 {"a", Value(1)}, //
111 {"b", Value("blah")}, //
112 {"c", Value(true)} //
113 });
114
115 EXPECT_STATUS_OK(row.get("a"));
116 EXPECT_STATUS_OK(row.get("b"));
117 EXPECT_STATUS_OK(row.get("c"));
118 EXPECT_FALSE(row.get("not a column name").ok());
119
120 EXPECT_EQ(Value(1), *row.get("a"));
121 EXPECT_EQ(Value("blah"), *row.get("b"));
122 EXPECT_EQ(Value(true), *row.get("c"));
123 }
124
TEST(Row,TemplatedGetByPosition)125 TEST(Row, TemplatedGetByPosition) {
126 Row row = MakeTestRow(1, "blah", true);
127
128 EXPECT_STATUS_OK(row.get<std::int64_t>(0));
129 EXPECT_STATUS_OK(row.get<std::string>(1));
130 EXPECT_STATUS_OK(row.get<bool>(2));
131
132 // Ensures that the wrong type specification results in a failure.
133 EXPECT_FALSE(row.get<bool>(0).ok());
134 EXPECT_FALSE(row.get<std::int64_t>(1).ok());
135 EXPECT_FALSE(row.get<std::string>(2).ok());
136 EXPECT_FALSE(row.get<std::int64_t>(3).ok());
137
138 EXPECT_EQ(1, *row.get<std::int64_t>(0));
139 EXPECT_EQ("blah", *row.get<std::string>(1));
140 EXPECT_EQ(true, *row.get<bool>(2));
141 }
142
TEST(Row,TemplatedGetByColumnName)143 TEST(Row, TemplatedGetByColumnName) {
144 Row row = MakeTestRow({
145 {"a", Value(1)}, //
146 {"b", Value("blah")}, //
147 {"c", Value(true)} //
148 });
149
150 EXPECT_STATUS_OK(row.get<std::int64_t>("a"));
151 EXPECT_STATUS_OK(row.get<std::string>("b"));
152 EXPECT_STATUS_OK(row.get<bool>("c"));
153
154 // Ensures that the wrong type specification results in a failure.
155 EXPECT_FALSE(row.get<bool>("a").ok());
156 EXPECT_FALSE(row.get<std::int64_t>("b").ok());
157 EXPECT_FALSE(row.get<std::string>("c").ok());
158 EXPECT_FALSE(row.get<std::string>("column does not exist").ok());
159
160 EXPECT_EQ(1, *row.get<std::int64_t>("a"));
161 EXPECT_EQ("blah", *row.get<std::string>("b"));
162 EXPECT_EQ(true, *row.get<bool>("c"));
163 }
164
TEST(Row,TemplatedGetAsTuple)165 TEST(Row, TemplatedGetAsTuple) {
166 Row row = MakeTestRow(1, "blah", true);
167
168 using RowType = std::tuple<std::int64_t, std::string, bool>;
169 EXPECT_STATUS_OK(row.get<RowType>());
170 EXPECT_EQ(std::make_tuple(1, "blah", true), *row.get<RowType>());
171
172 using TooFewTypes = std::tuple<std::int64_t, std::string>;
173 EXPECT_FALSE(row.get<TooFewTypes>().ok());
174 Row copy = row;
175 EXPECT_FALSE(std::move(copy).get<TooFewTypes>().ok());
176
177 using TooManyTypes = std::tuple<std::int64_t, std::string, bool, bool>;
178 EXPECT_FALSE(row.get<TooManyTypes>().ok());
179 copy = row;
180 EXPECT_FALSE(std::move(copy).get<TooManyTypes>().ok());
181
182 using WrongType = std::tuple<std::int64_t, std::string, std::int64_t>;
183 EXPECT_FALSE(row.get<WrongType>().ok());
184 copy = row;
185 EXPECT_FALSE(std::move(copy).get<WrongType>().ok());
186
187 EXPECT_EQ(std::make_tuple(1, "blah", true), *std::move(row).get<RowType>());
188 }
189
TEST(MakeTestRow,ExplicitColumNames)190 TEST(MakeTestRow, ExplicitColumNames) {
191 auto row = MakeTestRow({{"a", Value(42)}, {"b", Value(52)}});
192 EXPECT_EQ(Value(42), *row.get("a"));
193 EXPECT_EQ(Value(52), *row.get("b"));
194 }
195
TEST(MakeTestRow,ImplicitColumNames)196 TEST(MakeTestRow, ImplicitColumNames) {
197 auto row = MakeTestRow(42, 52);
198 EXPECT_EQ(Value(42), *row.get("0"));
199 EXPECT_EQ(Value(52), *row.get("1"));
200 }
201
TEST(RowStreamIterator,Basics)202 TEST(RowStreamIterator, Basics) {
203 RowStreamIterator end;
204 EXPECT_EQ(end, end);
205
206 std::vector<Row> rows;
207 rows.emplace_back(MakeTestRow(1, "foo", true));
208 rows.emplace_back(MakeTestRow(2, "bar", true));
209 rows.emplace_back(MakeTestRow(3, "baz", true));
210
211 auto it = RowStreamIterator(MakeRowStreamIteratorSource(rows));
212 EXPECT_EQ(it, it);
213 EXPECT_NE(it, end);
214 EXPECT_STATUS_OK(*it);
215 EXPECT_EQ(rows[0], **it);
216
217 ++it;
218 EXPECT_EQ(it, it);
219 EXPECT_NE(it, end);
220 EXPECT_STATUS_OK(*it);
221 EXPECT_EQ(rows[1], **it);
222
223 it++;
224 EXPECT_EQ(it, it);
225 EXPECT_NE(it, end);
226 EXPECT_STATUS_OK(*it);
227 EXPECT_EQ(rows[2], **it);
228
229 // Tests const op*() and op->()
230 auto const copy = it;
231 EXPECT_EQ(copy, it);
232 EXPECT_NE(copy, end);
233 EXPECT_STATUS_OK(*copy);
234 EXPECT_STATUS_OK(copy->status());
235
236 ++it;
237 EXPECT_EQ(it, it);
238 EXPECT_EQ(it, end);
239 }
240
TEST(RowStreamIterator,Empty)241 TEST(RowStreamIterator, Empty) {
242 RowStreamIterator end;
243 auto it = RowStreamIterator(MakeRowStreamIteratorSource());
244 EXPECT_EQ(it, end);
245 }
246
TEST(RowStreamIterator,OneRow)247 TEST(RowStreamIterator, OneRow) {
248 RowStreamIterator end;
249 std::vector<Row> rows;
250 rows.emplace_back(MakeTestRow(1, "foo", true));
251 auto it = RowStreamIterator(MakeRowStreamIteratorSource(rows));
252 EXPECT_NE(it, end);
253 EXPECT_STATUS_OK(*it);
254 EXPECT_EQ(rows[0], **it);
255
256 ++it;
257 EXPECT_EQ(it, it);
258 EXPECT_EQ(it, end);
259 }
260
TEST(RowStreamIterator,IterationError)261 TEST(RowStreamIterator, IterationError) {
262 RowStreamIterator end;
263 std::vector<StatusOr<Row>> rows;
264 rows.emplace_back(MakeTestRow(1, "foo", true));
265 rows.emplace_back(Status(StatusCode::kUnknown, "some error"));
266 rows.emplace_back(MakeTestRow(2, "bar", true));
267
268 auto it = RowStreamIterator(MakeRowStreamIteratorSource(rows));
269 EXPECT_NE(it, end);
270 EXPECT_STATUS_OK(*it);
271 EXPECT_EQ(rows[0], *it);
272
273 ++it;
274 EXPECT_EQ(it, it);
275 EXPECT_NE(it, end);
276 EXPECT_FALSE(*it);
277 EXPECT_EQ(StatusCode::kUnknown, it->status().code());
278 EXPECT_EQ("some error", it->status().message());
279
280 ++it;
281 EXPECT_EQ(it, it);
282 EXPECT_EQ(it, end);
283 }
284
TEST(RowStreamIterator,ForLoop)285 TEST(RowStreamIterator, ForLoop) {
286 std::vector<Row> rows;
287 rows.emplace_back(MakeTestRow({{"num", Value(2)}}));
288 rows.emplace_back(MakeTestRow({{"num", Value(3)}}));
289 rows.emplace_back(MakeTestRow({{"num", Value(5)}}));
290
291 auto source = MakeRowStreamIteratorSource(rows);
292 std::int64_t product = 1;
293 for (RowStreamIterator it(source), end; it != end; ++it) {
294 EXPECT_STATUS_OK(*it);
295 auto num = (*it)->get<std::int64_t>("num");
296 EXPECT_STATUS_OK(num);
297 product *= *num;
298 }
299 EXPECT_EQ(product, 30);
300 }
301
TEST(RowStreamIterator,RangeForLoop)302 TEST(RowStreamIterator, RangeForLoop) {
303 std::vector<Row> rows;
304 rows.emplace_back(MakeTestRow({{"num", Value(2)}}));
305 rows.emplace_back(MakeTestRow({{"num", Value(3)}}));
306 rows.emplace_back(MakeTestRow({{"num", Value(5)}}));
307
308 RowRange range(MakeRowStreamIteratorSource(rows));
309 std::int64_t product = 1;
310 for (auto const& row : range) {
311 EXPECT_STATUS_OK(row);
312 auto num = row->get<std::int64_t>("num");
313 EXPECT_STATUS_OK(num);
314 product *= *num;
315 }
316 EXPECT_EQ(product, 30);
317 }
318
TEST(TupleStreamIterator,Basics)319 TEST(TupleStreamIterator, Basics) {
320 std::vector<Row> rows;
321 rows.emplace_back(MakeTestRow(1, "foo", true));
322 rows.emplace_back(MakeTestRow(2, "bar", true));
323 rows.emplace_back(MakeTestRow(3, "baz", true));
324
325 using RowType = std::tuple<std::int64_t, std::string, bool>;
326 using TupleIterator = TupleStreamIterator<RowType>;
327
328 auto end = TupleIterator();
329 EXPECT_EQ(end, end);
330
331 auto it = TupleIterator(RowStreamIterator(MakeRowStreamIteratorSource(rows)),
332 RowStreamIterator());
333
334 EXPECT_EQ(it, it);
335 EXPECT_NE(it, end);
336 EXPECT_STATUS_OK(*it);
337 EXPECT_EQ(std::make_tuple(1, "foo", true), **it);
338
339 ++it;
340 EXPECT_EQ(it, it);
341 EXPECT_NE(it, end);
342 EXPECT_STATUS_OK(*it);
343 EXPECT_EQ(std::make_tuple(2, "bar", true), **it);
344
345 ++it;
346 EXPECT_EQ(it, it);
347 EXPECT_NE(it, end);
348 EXPECT_STATUS_OK(*it);
349 EXPECT_EQ(std::make_tuple(3, "baz", true), **it);
350
351 // Tests const op*() and op->()
352 auto const copy = it;
353 EXPECT_EQ(copy, it);
354 EXPECT_NE(copy, end);
355 EXPECT_STATUS_OK(*copy);
356 EXPECT_STATUS_OK(copy->status());
357
358 ++it;
359 EXPECT_EQ(it, it);
360 EXPECT_EQ(it, end);
361 }
362
TEST(TupleStreamIterator,Empty)363 TEST(TupleStreamIterator, Empty) {
364 using RowType = std::tuple<std::int64_t, std::string, bool>;
365 using TupleIterator = TupleStreamIterator<RowType>;
366
367 auto end = TupleIterator();
368 EXPECT_EQ(end, end);
369
370 auto it = TupleIterator(RowStreamIterator(MakeRowStreamIteratorSource()),
371 RowStreamIterator());
372 EXPECT_EQ(it, end);
373 }
374
TEST(TupleStreamIterator,Error)375 TEST(TupleStreamIterator, Error) {
376 std::vector<Row> rows;
377 rows.emplace_back(MakeTestRow(1, "foo", true));
378 rows.emplace_back(MakeTestRow(2, "bar", "should be a bool"));
379 rows.emplace_back(MakeTestRow(3, "baz", true));
380
381 using RowType = std::tuple<std::int64_t, std::string, bool>;
382 using TupleIterator = TupleStreamIterator<RowType>;
383
384 auto end = TupleIterator();
385 EXPECT_EQ(end, end);
386
387 auto it = TupleIterator(RowStreamIterator(MakeRowStreamIteratorSource(rows)),
388 RowStreamIterator());
389
390 EXPECT_EQ(it, it);
391 EXPECT_NE(it, end);
392 EXPECT_STATUS_OK(*it);
393 EXPECT_EQ(std::make_tuple(1, "foo", true), **it);
394
395 ++it;
396 EXPECT_EQ(it, it);
397 EXPECT_NE(it, end);
398 EXPECT_FALSE(it->ok()); // Error parsing the 2nd element
399
400 ++it; // Due to the previous error, jumps straight to "end"
401 EXPECT_EQ(it, it);
402 EXPECT_EQ(it, end);
403 }
404
TEST(TupleStream,Basics)405 TEST(TupleStream, Basics) {
406 std::vector<Row> rows;
407 rows.emplace_back(MakeTestRow(1, "foo", true));
408 rows.emplace_back(MakeTestRow(2, "bar", true));
409 rows.emplace_back(MakeTestRow(3, "baz", true));
410
411 using RowType = std::tuple<std::int64_t, std::string, bool>;
412 RowRange range(MakeRowStreamIteratorSource(rows));
413 auto parser = StreamOf<RowType>(range);
414 auto it = parser.begin();
415 auto end = parser.end();
416 EXPECT_EQ(end, end);
417
418 EXPECT_EQ(it, it);
419 EXPECT_NE(it, end);
420 EXPECT_STATUS_OK(*it);
421 EXPECT_EQ(std::make_tuple(1, "foo", true), **it);
422
423 ++it;
424 EXPECT_EQ(it, it);
425 EXPECT_NE(it, end);
426 EXPECT_STATUS_OK(*it);
427 EXPECT_EQ(std::make_tuple(2, "bar", true), **it);
428
429 ++it;
430 EXPECT_EQ(it, it);
431 EXPECT_NE(it, end);
432 EXPECT_STATUS_OK(*it);
433 EXPECT_EQ(std::make_tuple(3, "baz", true), **it);
434
435 ++it;
436 EXPECT_EQ(it, it);
437 EXPECT_EQ(it, end);
438 }
439
TEST(TupleStream,RangeForLoop)440 TEST(TupleStream, RangeForLoop) {
441 std::vector<Row> rows;
442 rows.emplace_back(MakeTestRow({{"num", Value(2)}}));
443 rows.emplace_back(MakeTestRow({{"num", Value(3)}}));
444 rows.emplace_back(MakeTestRow({{"num", Value(5)}}));
445 using RowType = std::tuple<std::int64_t>;
446
447 RowRange range(MakeRowStreamIteratorSource(rows));
448 std::int64_t product = 1;
449 for (auto const& row : StreamOf<RowType>(range)) {
450 EXPECT_STATUS_OK(row);
451 product *= std::get<0>(*row);
452 }
453 EXPECT_EQ(product, 30);
454 }
455
TEST(TupleStream,IterationError)456 TEST(TupleStream, IterationError) {
457 std::vector<StatusOr<Row>> rows;
458 rows.emplace_back(MakeTestRow(1, "foo", true));
459 rows.emplace_back(Status(StatusCode::kUnknown, "some error"));
460 rows.emplace_back(MakeTestRow(2, "bar", true));
461
462 RowRange range(MakeRowStreamIteratorSource(rows));
463
464 using RowType = std::tuple<std::int64_t, std::string, bool>;
465 auto stream = StreamOf<RowType>(range);
466
467 auto end = stream.end();
468 auto it = stream.begin();
469 EXPECT_NE(it, end);
470 EXPECT_STATUS_OK(*it);
471 EXPECT_EQ(std::make_tuple(1, "foo", true), **it);
472
473 ++it;
474 EXPECT_EQ(it, it);
475 EXPECT_NE(it, end);
476 EXPECT_FALSE(*it);
477 EXPECT_EQ(StatusCode::kUnknown, it->status().code());
478 EXPECT_EQ("some error", it->status().message());
479
480 ++it;
481 EXPECT_EQ(it, it);
482 EXPECT_EQ(it, end);
483 }
484
TEST(GetSingularRow,BasicEmpty)485 TEST(GetSingularRow, BasicEmpty) {
486 std::vector<Row> rows;
487 RowRange range(MakeRowStreamIteratorSource(rows));
488 auto row = GetSingularRow(range);
489 EXPECT_FALSE(row.ok());
490 EXPECT_EQ(row.status().code(), StatusCode::kInvalidArgument);
491 EXPECT_THAT(row.status().message(), HasSubstr("no rows"));
492 }
493
TEST(GetSingularRow,TupleStreamEmpty)494 TEST(GetSingularRow, TupleStreamEmpty) {
495 std::vector<Row> rows;
496 RowRange range(MakeRowStreamIteratorSource(rows));
497 auto row = GetSingularRow(StreamOf<std::tuple<std::int64_t>>(range));
498 EXPECT_FALSE(row.ok());
499 EXPECT_EQ(row.status().code(), StatusCode::kInvalidArgument);
500 EXPECT_THAT(row.status().message(), HasSubstr("no rows"));
501 }
502
TEST(GetSingularRow,BasicSingleRow)503 TEST(GetSingularRow, BasicSingleRow) {
504 std::vector<Row> rows;
505 rows.emplace_back(MakeTestRow({{"num", Value(1)}}));
506
507 RowRange range(MakeRowStreamIteratorSource(rows));
508 auto row = GetSingularRow(range);
509 EXPECT_STATUS_OK(row);
510 EXPECT_EQ(1, *row->get<std::int64_t>(0));
511 }
512
TEST(GetSingularRow,TupleStreamSingleRow)513 TEST(GetSingularRow, TupleStreamSingleRow) {
514 std::vector<Row> rows;
515 rows.emplace_back(MakeTestRow({{"num", Value(1)}}));
516
517 auto row_range = RowRange(MakeRowStreamIteratorSource(rows));
518 auto tup_range = StreamOf<std::tuple<std::int64_t>>(row_range);
519
520 auto row = GetSingularRow(tup_range);
521 EXPECT_STATUS_OK(row);
522 EXPECT_EQ(1, std::get<0>(*row));
523 }
524
TEST(GetSingularRow,BasicTooManyRows)525 TEST(GetSingularRow, BasicTooManyRows) {
526 std::vector<Row> rows;
527 rows.emplace_back(MakeTestRow({{"num", Value(1)}}));
528 rows.emplace_back(MakeTestRow({{"num", Value(2)}}));
529
530 RowRange range(MakeRowStreamIteratorSource(rows));
531 auto row = GetSingularRow(range);
532 EXPECT_FALSE(row.ok());
533 EXPECT_EQ(row.status().code(), StatusCode::kInvalidArgument);
534 EXPECT_THAT(row.status().message(), HasSubstr("too many rows"));
535 }
536
TEST(GetSingularRow,TupleStreamTooManyRows)537 TEST(GetSingularRow, TupleStreamTooManyRows) {
538 std::vector<Row> rows;
539 rows.emplace_back(MakeTestRow({{"num", Value(1)}}));
540 rows.emplace_back(MakeTestRow({{"num", Value(2)}}));
541
542 RowRange range(MakeRowStreamIteratorSource(rows));
543 auto row = GetSingularRow(StreamOf<std::tuple<std::int64_t>>(range));
544 EXPECT_FALSE(row.ok());
545 EXPECT_EQ(row.status().code(), StatusCode::kInvalidArgument);
546 EXPECT_THAT(row.status().message(), HasSubstr("too many rows"));
547 }
548
549 } // namespace
550 } // namespace SPANNER_CLIENT_NS
551 } // namespace spanner
552 } // namespace cloud
553 } // namespace google
554