Skip to content

Commit ec4f063

Browse files
committed
chore: move to value.cc, add tests
1 parent eefa27b commit ec4f063

File tree

4 files changed

+383
-105
lines changed

4 files changed

+383
-105
lines changed

google/cloud/bigtable/internal/partial_result_set_source.cc

Lines changed: 2 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -194,110 +194,6 @@ Status PartialResultSetSource::ProcessDataFromStream(
194194
return {}; // OK
195195
}
196196

197-
/**
198-
* Checks whether the declared type in column matches the value's contents.
199-
* Since the received values may or may not have type() set, we check against
200-
* the value contents themselves
201-
*/
202-
bool TypeAndValuesMatch(google::bigtable::v2::Type const& type,
203-
google::bigtable::v2::Value const& value) {
204-
using google::bigtable::v2::Type;
205-
bool has_matching_value;
206-
switch (type.kind_case()) {
207-
case Type::kArrayType: {
208-
if (!value.has_array_value()) {
209-
has_matching_value = value.has_array_value();
210-
break;
211-
}
212-
has_matching_value = true;
213-
for (auto const& val : value.array_value().values()) {
214-
if (!TypeAndValuesMatch(type.array_type().element_type(), val)) {
215-
has_matching_value = false;
216-
break;
217-
}
218-
}
219-
break;
220-
}
221-
case Type::kMapType: {
222-
if (!value.has_array_value()) {
223-
has_matching_value = value.has_array_value();
224-
break;
225-
}
226-
has_matching_value = true;
227-
auto key_type = type.map_type().key_type();
228-
;
229-
auto value_type = type.map_type().value_type();
230-
;
231-
for (auto const& val : value.array_value().values()) {
232-
if (!val.has_array_value() || val.array_value().values_size() != 2) {
233-
has_matching_value = false;
234-
break;
235-
}
236-
auto map_key = val.array_value().values(0);
237-
auto map_value = val.array_value().values(1);
238-
if (!TypeAndValuesMatch(key_type, map_key) ||
239-
!TypeAndValuesMatch(value_type, map_value)) {
240-
has_matching_value = false;
241-
break;
242-
}
243-
}
244-
break;
245-
}
246-
case Type::kStructType: {
247-
if (!value.has_array_value()) {
248-
has_matching_value = value.has_array_value();
249-
break;
250-
}
251-
has_matching_value = true;
252-
auto fields = type.struct_type().fields();
253-
auto values = value.array_value().values();
254-
if (fields.size() != values.size()) {
255-
has_matching_value = value.has_array_value();
256-
break;
257-
}
258-
for (int i = 0; i < fields.size(); ++i) {
259-
auto const& f1 = fields.Get(i);
260-
auto const& v = values[i];
261-
if (!TypeAndValuesMatch(f1.type(), v)) {
262-
has_matching_value = false;
263-
break;
264-
}
265-
}
266-
break;
267-
}
268-
case Type::kBoolType:
269-
has_matching_value = value.has_bool_value();
270-
break;
271-
case Type::kBytesType:
272-
has_matching_value = value.has_bytes_value();
273-
break;
274-
case Type::kDateType:
275-
has_matching_value = value.has_date_value();
276-
break;
277-
case Type::kEnumType:
278-
has_matching_value = value.has_int_value();
279-
break;
280-
case Type::kFloat32Type:
281-
case Type::kFloat64Type:
282-
has_matching_value = value.has_float_value();
283-
break;
284-
case Type::kInt64Type:
285-
has_matching_value = value.has_int_value();
286-
break;
287-
case Type::kStringType:
288-
has_matching_value = value.has_string_value();
289-
break;
290-
case Type::kTimestampType:
291-
has_matching_value = value.has_timestamp_value();
292-
break;
293-
default:
294-
has_matching_value = false;
295-
break;
296-
}
297-
// Nulls are allowed;
298-
return has_matching_value || bigtable::Value::IsNullValue(value);
299-
}
300-
301197
Status PartialResultSetSource::BufferProtoRows() {
302198
if (metadata_.has_value()) {
303199
auto const& proto_schema = metadata_->proto_schema();
@@ -322,7 +218,8 @@ Status PartialResultSetSource::BufferProtoRows() {
322218

323219
while (parsed_value != proto_values.end()) {
324220
for (auto const& column : proto_schema.columns()) {
325-
if (!TypeAndValuesMatch(column.type(), *parsed_value)) {
221+
if (!bigtable::Value::TypeAndValuesMatch(column.type(),
222+
*parsed_value)) {
326223
return internal::InternalError("Metadata and Value not matching.",
327224
GCP_ERROR_INFO());
328225
}

google/cloud/bigtable/value.cc

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,113 @@ std::ostream& operator<<(std::ostream& os, Value const& v) {
338338
return StreamHelper(os, v.value_, v.type_, StreamMode::kScalar);
339339
}
340340

341+
// NOLINTNEXTLINE(misc-no-recursion)
342+
bool Value::TypeAndArrayValuesMatch(google::bigtable::v2::Type const& type,
343+
google::bigtable::v2::Value const& value) {
344+
if (!value.has_array_value()) {
345+
return false;
346+
}
347+
for (auto const& val : value.array_value().values()) {
348+
if (!TypeAndValuesMatch(type.array_type().element_type(), val)) {
349+
return false;
350+
}
351+
}
352+
return true;
353+
}
354+
355+
// NOLINTNEXTLINE(misc-no-recursion)
356+
bool Value::TypeAndMapValuesMatch(google::bigtable::v2::Type const& type,
357+
google::bigtable::v2::Value const& value) {
358+
if (!value.has_array_value()) {
359+
return false;
360+
}
361+
auto key_type = type.map_type().key_type();
362+
auto value_type = type.map_type().value_type();
363+
for (auto const& val : value.array_value().values()) {
364+
if (!val.has_array_value() || val.array_value().values_size() != 2) {
365+
return false;
366+
}
367+
auto map_key = val.array_value().values(0);
368+
auto map_value = val.array_value().values(1);
369+
if (!TypeAndValuesMatch(key_type, map_key) ||
370+
!TypeAndValuesMatch(value_type, map_value)) {
371+
return false;
372+
}
373+
}
374+
return true;
375+
}
376+
377+
// NOLINTNEXTLINE(misc-no-recursion)
378+
bool Value::TypeAndStructValuesMatch(google::bigtable::v2::Type const& type,
379+
google::bigtable::v2::Value const& value) {
380+
if (!value.has_array_value()) {
381+
return false;
382+
}
383+
auto fields = type.struct_type().fields();
384+
auto values = value.array_value().values();
385+
if (fields.size() != values.size()) {
386+
return false;
387+
}
388+
for (int i = 0; i < fields.size(); ++i) {
389+
auto const& f1 = fields.Get(i);
390+
auto const& v = values[i];
391+
if (!TypeAndValuesMatch(f1.type(), v)) {
392+
return false;
393+
}
394+
}
395+
return true;
396+
}
397+
398+
/**
399+
* Checks whether the declared type in column matches the value's contents.
400+
* Since the received values may or may not have type() set, we check against
401+
* the value contents themselves
402+
*/
403+
// NOLINTNEXTLINE(misc-no-recursion)
404+
bool Value::TypeAndValuesMatch(google::bigtable::v2::Type const& type,
405+
google::bigtable::v2::Value const& value) {
406+
using google::bigtable::v2::Type;
407+
bool has_matching_value;
408+
switch (type.kind_case()) {
409+
case Type::kArrayType:
410+
return TypeAndArrayValuesMatch(type, value);
411+
case Type::kMapType:
412+
return TypeAndMapValuesMatch(type, value);
413+
case Type::kStructType:
414+
return TypeAndStructValuesMatch(type, value);
415+
case Type::kBoolType:
416+
has_matching_value = value.has_bool_value();
417+
break;
418+
case Type::kBytesType:
419+
has_matching_value = value.has_bytes_value();
420+
break;
421+
case Type::kDateType:
422+
has_matching_value = value.has_date_value();
423+
break;
424+
case Type::kEnumType:
425+
has_matching_value = value.has_int_value();
426+
break;
427+
case Type::kFloat32Type:
428+
case Type::kFloat64Type:
429+
has_matching_value = value.has_float_value();
430+
break;
431+
case Type::kInt64Type:
432+
has_matching_value = value.has_int_value();
433+
break;
434+
case Type::kStringType:
435+
has_matching_value = value.has_string_value();
436+
break;
437+
case Type::kTimestampType:
438+
has_matching_value = value.has_timestamp_value();
439+
break;
440+
default:
441+
has_matching_value = false;
442+
break;
443+
}
444+
// Nulls are allowed;
445+
return has_matching_value || bigtable::Value::IsNullValue(value);
446+
}
447+
341448
//
342449
// Value::TypeProtoIs
343450
//

google/cloud/bigtable/value.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,18 @@ class Value {
315315
return value.kind_case() == google::bigtable::v2::Value::KIND_NOT_SET;
316316
}
317317

318+
static bool TypeAndValuesMatch(google::bigtable::v2::Type const& type,
319+
google::bigtable::v2::Value const& value);
320+
318321
private:
322+
static bool TypeAndArrayValuesMatch(google::bigtable::v2::Type const& type,
323+
google::bigtable::v2::Value const& value);
324+
static bool TypeAndMapValuesMatch(google::bigtable::v2::Type const& type,
325+
google::bigtable::v2::Value const& value);
326+
static bool TypeAndStructValuesMatch(
327+
google::bigtable::v2::Type const& type,
328+
google::bigtable::v2::Value const& value);
329+
319330
// Metafunction that returns true if `T` is an `absl::optional<U>`
320331
template <typename T>
321332
struct IsOptional : std::false_type {};

0 commit comments

Comments
 (0)