Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions google/cloud/bigtable/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ add_library(
app_profile_config.cc
app_profile_config.h
async_row_reader.h
bound_query.cc
bound_query.h
bytes.cc
bytes.h
cell.h
Expand Down Expand Up @@ -236,6 +238,8 @@ add_library(
options.h
polling_policy.cc
polling_policy.h
prepared_query.cc
prepared_query.h
query_row.cc
query_row.h
read_modify_write_rule.h
Expand Down Expand Up @@ -437,6 +441,7 @@ if (BUILD_TESTING)
app_profile_config_test.cc
async_read_stream_test.cc
bigtable_version_test.cc
bound_query_test.cc
bytes_test.cc
cell_test.cc
client_options_test.cc
Expand Down Expand Up @@ -494,6 +499,7 @@ if (BUILD_TESTING)
mutation_batcher_test.cc
mutations_test.cc
polling_policy_test.cc
prepared_query_test.cc
query_row_test.cc
read_modify_write_rule_test.cc
row_range_test.cc
Expand Down
2 changes: 2 additions & 0 deletions google/cloud/bigtable/bigtable_client_unit_tests.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ bigtable_client_unit_tests = [
"app_profile_config_test.cc",
"async_read_stream_test.cc",
"bigtable_version_test.cc",
"bound_query_test.cc",
"bytes_test.cc",
"cell_test.cc",
"client_options_test.cc",
Expand Down Expand Up @@ -78,6 +79,7 @@ bigtable_client_unit_tests = [
"mutation_batcher_test.cc",
"mutations_test.cc",
"polling_policy_test.cc",
"prepared_query_test.cc",
"query_row_test.cc",
"read_modify_write_rule_test.cc",
"row_range_test.cc",
Expand Down
56 changes: 56 additions & 0 deletions google/cloud/bigtable/bound_query.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "google/cloud/bigtable/bound_query.h"

namespace google {
namespace cloud {
namespace bigtable {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN

StatusOr<std::string> BoundQuery::prepared_query() const {
return query_plan_->prepared_query();
}

StatusOr<google::bigtable::v2::ResultSetMetadata> BoundQuery::metadata() const {
return query_plan_->metadata();
}

std::unordered_map<std::string, Value> const& BoundQuery::parameters() const {
return parameters_;
}

InstanceResource const& BoundQuery::instance() const { return instance_; }

google::bigtable::v2::ExecuteQueryRequest BoundQuery::ToRequestProto() {
google::bigtable::v2::ExecuteQueryRequest result;
*result.mutable_instance_name() = instance_.FullName();
auto prepared_query = query_plan_->prepared_query();
if (prepared_query.ok()) {
*result.mutable_prepared_query() = query_plan_->prepared_query().value();
}

google::protobuf::Map<std::string, google::bigtable::v2::Value> parameters;
for (auto const& kv : parameters_) {
parameters[kv.first] =
bigtable_internal::ValueInternals::ToProto(kv.second).second;
}
*result.mutable_params() = parameters;
return result;
}

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
} // namespace bigtable
} // namespace cloud
} // namespace google
72 changes: 72 additions & 0 deletions google/cloud/bigtable/bound_query.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_BIGTABLE_BOUND_QUERY_H
#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_BIGTABLE_BOUND_QUERY_H

#include "google/cloud/bigtable/instance_resource.h"
#include "google/cloud/bigtable/internal/query_plan.h"
#include "google/cloud/bigtable/value.h"
#include "google/cloud/bigtable/version.h"
#include "google/cloud/completion_queue.h"
#include <google/bigtable/v2/bigtable.pb.h>
#include <string>
#include <unordered_map>

namespace google {
namespace cloud {
namespace bigtable {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN

/**
* Move only type representing a PreparedQuery with parameter values.
* Created by calling PreparedQuery::BindParameters.
*/
class BoundQuery {
public:
// Copy and move.
BoundQuery(BoundQuery const&) = delete;
BoundQuery(BoundQuery&&) = default;
BoundQuery& operator=(BoundQuery const&) = delete;
BoundQuery& operator=(BoundQuery&&) = default;

// Accessors
StatusOr<std::string> prepared_query() const;
StatusOr<google::bigtable::v2::ResultSetMetadata> metadata() const;
std::unordered_map<std::string, Value> const& parameters() const;
InstanceResource const& instance() const;

google::bigtable::v2::ExecuteQueryRequest ToRequestProto();

private:
friend class PreparedQuery;
BoundQuery(InstanceResource instance,
std::shared_ptr<bigtable_internal::QueryPlan> query_plan,
std::unordered_map<std::string, Value> parameters)
: instance_(std::move(instance)),
query_plan_(std::move(query_plan)),
parameters_(std::move(parameters)) {}

InstanceResource instance_;
// Copy of the query_plan_ contained by the PreparedQuery that created
// this BoundQuery.
std::shared_ptr<bigtable_internal::QueryPlan> query_plan_;
std::unordered_map<std::string, Value> parameters_;
};

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
} // namespace bigtable
} // namespace cloud
} // namespace google
#endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_BIGTABLE_BOUND_QUERY_H
98 changes: 98 additions & 0 deletions google/cloud/bigtable/bound_query_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "google/cloud/bigtable/bound_query.h"
#include "google/cloud/bigtable/prepared_query.h"
#include "google/cloud/bigtable/sql_statement.h"
#include "google/cloud/bigtable/value.h"
#include "google/cloud/testing_util/status_matchers.h"
#include <algorithm>

namespace google {
namespace cloud {
namespace bigtable {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
namespace {
using ::google::bigtable::v2::PrepareQueryResponse;

TEST(BoundQuery, FromPreparedQuery) {
CompletionQueue cq;
Project p("dummy-project");
InstanceResource instance(p, "dummy-instance");
std::string statement_contents(
"SELECT * FROM my_table WHERE col1 = @val1 and col2 = @val2;");
SqlStatement sql_statement(statement_contents);
PrepareQueryResponse response;
std::unordered_map<std::string, Value> parameters = {{"val1", Value(true)},
{"val2", Value(2.0)}};

// The following variables are only meant to confirm the metadata is correctly
// passed down to the BoundQuery.
auto metadata = std::make_unique<google::bigtable::v2::ResultSetMetadata>();
auto schema = std::make_unique<google::bigtable::v2::ProtoSchema>();
auto column = google::bigtable::v2::ColumnMetadata();
*column.mutable_name() = "col1";
schema->mutable_columns()->Add(std::move(column));
metadata->set_allocated_proto_schema(schema.release());
response.set_allocated_metadata(metadata.release());

PreparedQuery pq(cq, instance, sql_statement, response);
auto bq = pq.BindParameters(parameters);
EXPECT_EQ(instance.FullName(), bq.instance().FullName());
EXPECT_STATUS_OK(bq.prepared_query());
EXPECT_EQ(statement_contents, bq.prepared_query().value());
EXPECT_EQ(parameters, bq.parameters());
EXPECT_STATUS_OK(bq.metadata());
EXPECT_TRUE(bq.metadata().value().has_proto_schema());
EXPECT_EQ(1, bq.metadata().value().proto_schema().columns_size());
EXPECT_EQ("col1", bq.metadata().value().proto_schema().columns()[0].name());
}

TEST(BoundQuery, ToRequestProto) {
CompletionQueue cq;
Project p("dummy-project");
InstanceResource instance(p, "dummy-instance");
std::string statement_contents(
"SELECT * FROM my_table WHERE col1 = @val1 and col2 = @val2;");
SqlStatement sql_statement(statement_contents);
PrepareQueryResponse response;
std::unordered_map<std::string, Value> parameters = {{"val1", Value(true)},
{"val2", Value(2.0)}};

PreparedQuery pq(cq, instance, sql_statement, response);
auto bq = pq.BindParameters(parameters);
google::bigtable::v2::ExecuteQueryRequest proto = bq.ToRequestProto();
EXPECT_EQ(instance.FullName(), proto.instance_name());
EXPECT_EQ(statement_contents, proto.prepared_query());

// Test param contents.
EXPECT_EQ(parameters.size(), proto.mutable_params()->size());

// The first parameter is a boolean.
EXPECT_TRUE(proto.params().contains("val1"));
auto val1 = proto.params().find("val1")->second;
EXPECT_TRUE(val1.has_bool_value());
EXPECT_EQ(true, val1.bool_value());

// The second parameter is a double.
EXPECT_TRUE(proto.params().contains("val2"));
auto val2 = proto.params().find("val2")->second;
EXPECT_TRUE(val2.has_float_value());
EXPECT_EQ(2.0, val2.float_value());
}
} // namespace
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
} // namespace bigtable
} // namespace cloud
} // namespace google
4 changes: 4 additions & 0 deletions google/cloud/bigtable/google_cloud_cpp_bigtable.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ google_cloud_cpp_bigtable_hdrs = [
"admin_client.h",
"app_profile_config.h",
"async_row_reader.h",
"bound_query.h",
"bytes.h",
"cell.h",
"client_options.h",
Expand Down Expand Up @@ -121,6 +122,7 @@ google_cloud_cpp_bigtable_hdrs = [
"mutations.h",
"options.h",
"polling_policy.h",
"prepared_query.h",
"query_row.h",
"read_modify_write_rule.h",
"resource_names.h",
Expand Down Expand Up @@ -173,6 +175,7 @@ google_cloud_cpp_bigtable_srcs = [
"admin/internal/bigtable_table_admin_tracing_stub.cc",
"admin_client.cc",
"app_profile_config.cc",
"bound_query.cc",
"bytes.cc",
"client_options.cc",
"cluster_config.cc",
Expand Down Expand Up @@ -227,6 +230,7 @@ google_cloud_cpp_bigtable_srcs = [
"mutation_batcher.cc",
"mutations.cc",
"polling_policy.cc",
"prepared_query.cc",
"query_row.cc",
"resource_names.cc",
"row_range.cc",
Expand Down
36 changes: 36 additions & 0 deletions google/cloud/bigtable/prepared_query.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "google/cloud/bigtable/prepared_query.h"
#include "google/cloud/bigtable/sql_statement.h"

namespace google {
namespace cloud {
namespace bigtable {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN

BoundQuery PreparedQuery::BindParameters(
std::unordered_map<std::string, Value> params) const {
return BoundQuery(instance_, query_plan_, std::move(params));
}

InstanceResource const& PreparedQuery::instance() const { return instance_; }
SqlStatement const& PreparedQuery::sql_statement() const {
return sql_statement_;
}

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
} // namespace bigtable
} // namespace cloud
} // namespace google
Loading