Skip to content

Commit 6f55915

Browse files
committed
fix invalid type
1 parent 762705d commit 6f55915

File tree

2 files changed

+109
-1
lines changed

2 files changed

+109
-1
lines changed

google/cloud/bigtable/internal/data_connection_impl.cc

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,13 @@ StatusOr<bigtable::PreparedQuery> DataConnectionImpl::PrepareQuery(
757757
if (!response) {
758758
return std::move(response).status();
759759
}
760+
for (auto const& column : response->metadata().proto_schema().columns()) {
761+
if (!column.has_type() ||
762+
column.type().kind_case() == google::bigtable::v2::Type::KIND_NOT_SET) {
763+
return internal::InternalError("Column type cannot be empty",
764+
GCP_ERROR_INFO());
765+
}
766+
}
760767
auto const* func = __func__;
761768
auto refresh_fn = [this, request, func]() mutable {
762769
auto current = google::cloud::internal::SaveCurrentOptions();
@@ -840,7 +847,15 @@ future<StatusOr<bigtable::PreparedQuery>> DataConnectionImpl::AsyncPrepareQuery(
840847
if (!response) {
841848
return std::move(response).status();
842849
}
843-
850+
for (auto const& column :
851+
response->metadata().proto_schema().columns()) {
852+
if (!column.has_type() ||
853+
column.type().kind_case() ==
854+
google::bigtable::v2::Type::KIND_NOT_SET) {
855+
return StatusOr<bigtable::PreparedQuery>(internal::InternalError(
856+
"Column type cannot be empty", GCP_ERROR_INFO()));
857+
}
858+
}
844859
auto refresh_fn = [this, request, func]() mutable {
845860
auto current = google::cloud::internal::SaveCurrentOptions();
846861
auto retry = retry_policy(*current);
@@ -870,6 +885,9 @@ future<StatusOr<bigtable::PreparedQuery>> DataConnectionImpl::AsyncPrepareQuery(
870885
.then([operation_context](auto f) mutable {
871886
StatusOr<google::bigtable::v2::PrepareQueryResponse> response =
872887
f.get();
888+
if (!response.ok()) {
889+
return response;
890+
}
873891
operation_context->OnDone(response.status());
874892
return response;
875893
});

google/cloud/bigtable/internal/data_connection_impl_test.cc

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3757,6 +3757,96 @@ TEST_F(DataConnectionTest, ExecuteQueryFailureWithSchemaChange) {
37573757
fake_cq_impl->SimulateCompletion(false);
37583758
}
37593759

3760+
TEST_F(DataConnectionTest, PrepareQueryFailsOnInvalidType) {
3761+
auto mock = std::make_shared<MockBigtableStub>();
3762+
auto fake_cq_impl = std::make_shared<FakeCompletionQueueImpl>();
3763+
auto mock_bg = std::make_unique<MockBackgroundThreads>();
3764+
EXPECT_CALL(*mock_bg, cq).WillRepeatedly([&]() {
3765+
return CompletionQueue{fake_cq_impl};
3766+
});
3767+
3768+
v2::PrepareQueryResponse pq_response;
3769+
pq_response.set_prepared_query("test-pq-id-54321");
3770+
auto constexpr kResultMetadataText = R"pb(
3771+
proto_schema {
3772+
columns {
3773+
name: "test"
3774+
type { string_type {} }
3775+
}
3776+
columns {
3777+
name: "invalid"
3778+
type {}
3779+
}
3780+
}
3781+
)pb";
3782+
ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString(
3783+
kResultMetadataText, pq_response.mutable_metadata()));
3784+
*pq_response.mutable_valid_until() = internal::ToProtoTimestamp(
3785+
std::chrono::system_clock::now() + std::chrono::seconds(3600));
3786+
3787+
EXPECT_CALL(*mock, PrepareQuery)
3788+
.WillOnce([&](grpc::ClientContext&, Options const&,
3789+
v2::PrepareQueryRequest const&) { return pq_response; });
3790+
3791+
auto conn = TestConnection(std::move(mock));
3792+
internal::OptionsSpan span(CallOptions());
3793+
auto params = bigtable::PrepareQueryParams{
3794+
bigtable::InstanceResource(google::cloud::Project("the-project"),
3795+
"the-instance"),
3796+
bigtable::SqlStatement("SELECT * FROM the-table")};
3797+
auto prepared_query = conn->PrepareQuery(params);
3798+
EXPECT_THAT(prepared_query,
3799+
StatusIs(StatusCode::kInternal, "Column type cannot be empty"));
3800+
3801+
fake_cq_impl->SimulateCompletion(false);
3802+
}
3803+
3804+
TEST_F(DataConnectionTest, AsyncPrepareQueryFailsOnInvalidType) {
3805+
auto mock = std::make_shared<MockBigtableStub>();
3806+
auto fake_cq_impl = std::make_shared<FakeCompletionQueueImpl>();
3807+
auto mock_bg = std::make_unique<MockBackgroundThreads>();
3808+
EXPECT_CALL(*mock_bg, cq).WillRepeatedly([&]() {
3809+
return CompletionQueue{fake_cq_impl};
3810+
});
3811+
3812+
v2::PrepareQueryResponse pq_response;
3813+
pq_response.set_prepared_query("test-pq-id-54321");
3814+
auto constexpr kResultMetadataText = R"pb(
3815+
proto_schema {
3816+
columns {
3817+
name: "test"
3818+
type { string_type {} }
3819+
}
3820+
columns {
3821+
name: "invalid"
3822+
type {}
3823+
}
3824+
}
3825+
)pb";
3826+
ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString(
3827+
kResultMetadataText, pq_response.mutable_metadata()));
3828+
*pq_response.mutable_valid_until() = internal::ToProtoTimestamp(
3829+
std::chrono::system_clock::now() + std::chrono::seconds(3600));
3830+
3831+
EXPECT_CALL(*mock, AsyncPrepareQuery)
3832+
.WillOnce([&](CompletionQueue const&, auto, auto,
3833+
v2::PrepareQueryRequest const&) {
3834+
return make_ready_future(make_status_or(pq_response));
3835+
});
3836+
3837+
auto conn = TestConnection(std::move(mock));
3838+
internal::OptionsSpan span(CallOptions());
3839+
auto params = bigtable::PrepareQueryParams{
3840+
bigtable::InstanceResource(google::cloud::Project("the-project"),
3841+
"the-instance"),
3842+
bigtable::SqlStatement("SELECT * FROM the-table")};
3843+
auto prepared_query = conn->AsyncPrepareQuery(params).get();
3844+
EXPECT_THAT(prepared_query,
3845+
StatusIs(StatusCode::kInternal, "Column type cannot be empty"));
3846+
3847+
fake_cq_impl->SimulateCompletion(false);
3848+
}
3849+
37603850
} // namespace
37613851
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
37623852
} // namespace bigtable_internal

0 commit comments

Comments
 (0)