Skip to content

Commit f894bf7

Browse files
feat(bigtable): add support for SqlStatement (#15631)
* feat(bigtable): add support for SqlStatement * chore: clang-tidy * chore: remove samples reference * chore: address comments * chore: remove get(), make Parameter friend of Value * build: register sql_statement_tests in CMakeLists.txt
1 parent 6dd962f commit f894bf7

File tree

7 files changed

+440
-0
lines changed

7 files changed

+440
-0
lines changed

google/cloud/bigtable/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ add_library(
252252
rpc_backoff_policy.h
253253
rpc_retry_policy.cc
254254
rpc_retry_policy.h
255+
sql_statement.cc
256+
sql_statement.h
255257
table.cc
256258
table.h
257259
table_admin.cc
@@ -494,6 +496,7 @@ if (BUILD_TESTING)
494496
row_test.cc
495497
rpc_backoff_policy_test.cc
496498
rpc_retry_policy_test.cc
499+
sql_statement_test.cc
497500
table_admin_test.cc
498501
table_apply_test.cc
499502
table_bulk_apply_test.cc

google/cloud/bigtable/bigtable_client_unit_tests.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ bigtable_client_unit_tests = [
8484
"row_test.cc",
8585
"rpc_backoff_policy_test.cc",
8686
"rpc_retry_policy_test.cc",
87+
"sql_statement_test.cc",
8788
"table_admin_test.cc",
8889
"table_apply_test.cc",
8990
"table_bulk_apply_test.cc",

google/cloud/bigtable/google_cloud_cpp_bigtable.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ google_cloud_cpp_bigtable_hdrs = [
132132
"row_set.h",
133133
"rpc_backoff_policy.h",
134134
"rpc_retry_policy.h",
135+
"sql_statement.h",
135136
"table.h",
136137
"table_admin.h",
137138
"table_config.h",
@@ -229,6 +230,7 @@ google_cloud_cpp_bigtable_srcs = [
229230
"row_set.cc",
230231
"rpc_backoff_policy.cc",
231232
"rpc_retry_policy.cc",
233+
"sql_statement.cc",
232234
"table.cc",
233235
"table_admin.cc",
234236
"table_config.cc",
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// Copyright 2025 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+
// https://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/bigtable/sql_statement.h"
16+
#include "google/cloud/internal/make_status.h"
17+
#include <algorithm>
18+
19+
namespace google {
20+
namespace cloud {
21+
namespace bigtable_internal {
22+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
23+
PrepareQueryProto SqlStatementInternals::ToProto(
24+
bigtable::SqlStatement s, bigtable::InstanceResource const& r) {
25+
::google::bigtable::v2::PrepareQueryRequest statement_proto;
26+
statement_proto.set_query(std::move(s.statement_));
27+
statement_proto.set_instance_name(r.FullName());
28+
if (!s.params_.empty()) {
29+
auto& types = *statement_proto.mutable_param_types();
30+
for (auto& param : s.params_) {
31+
types[param.first] = std::move(param.second.type());
32+
}
33+
}
34+
return statement_proto;
35+
}
36+
37+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
38+
} // namespace bigtable_internal
39+
40+
namespace bigtable {
41+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
42+
43+
std::vector<std::string> SqlStatement::ParameterNames() const {
44+
std::vector<std::string> keys;
45+
keys.reserve(params_.size());
46+
for (auto const& p : params_) {
47+
keys.push_back(p.first);
48+
}
49+
return keys;
50+
}
51+
52+
google::cloud::StatusOr<Parameter> SqlStatement::GetParameter(
53+
std::string const& parameter_name) const {
54+
auto iter = params_.find(parameter_name);
55+
if (iter != params_.end()) {
56+
// This method does not return a const value, so we copy it.
57+
return iter->second;
58+
}
59+
return internal::NotFoundError("No such parameter: " + parameter_name,
60+
GCP_ERROR_INFO());
61+
}
62+
63+
bool operator==(Parameter const& a, Parameter const& b) {
64+
return a.value_ == b.value_;
65+
}
66+
67+
std::ostream& operator<<(std::ostream& os, Parameter const& p) {
68+
return os << p.value_;
69+
}
70+
71+
std::ostream& operator<<(std::ostream& os, SqlStatement const& stmt) {
72+
os << stmt.statement_;
73+
for (auto const& param : stmt.params_) {
74+
os << "\n[param]: {" << param.first << "=" << param.second << "}";
75+
}
76+
return os;
77+
}
78+
79+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
80+
} // namespace bigtable
81+
} // namespace cloud
82+
} // namespace google
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
2+
// Copyright 2025 Google LLC
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// https://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
#ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_BIGTABLE_SQL_STATEMENT_H
17+
#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_BIGTABLE_SQL_STATEMENT_H
18+
19+
#include "google/cloud/bigtable/instance_resource.h"
20+
#include "google/cloud/bigtable/value.h"
21+
#include "google/cloud/bigtable/version.h"
22+
#include "google/cloud/internal/make_status.h"
23+
#include "google/cloud/status_or.h"
24+
#include <google/bigtable/v2/bigtable.pb.h>
25+
#include <string>
26+
#include <unordered_map>
27+
#include <vector>
28+
29+
namespace google {
30+
namespace cloud {
31+
namespace bigtable_internal {
32+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
33+
struct SqlStatementInternals;
34+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
35+
} // namespace bigtable_internal
36+
37+
namespace bigtable {
38+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
39+
/**
40+
* Represents parameter of an SQL statement
41+
*
42+
* Parameter placeholders are specified by `@<param name>` in the SQL string.
43+
* Values for parameters are a collection of `std::pair<std::string const,
44+
* google::cloud:bigtable::Value>`.
45+
*/
46+
class Parameter {
47+
public:
48+
explicit Parameter(bool v) : Parameter(PrivateConstructor{}, v) {}
49+
explicit Parameter(std::int64_t v) : Parameter(PrivateConstructor{}, v) {}
50+
explicit Parameter(float v) : Parameter(PrivateConstructor{}, v) {}
51+
explicit Parameter(double v) : Parameter(PrivateConstructor{}, v) {}
52+
explicit Parameter(std::string v)
53+
: Parameter(PrivateConstructor{}, std::move(v)) {}
54+
explicit Parameter(char const* v)
55+
: Parameter(PrivateConstructor{}, std::move(v)) {}
56+
explicit Parameter(Bytes const& v)
57+
: Parameter(PrivateConstructor{}, std::move(v)) {}
58+
explicit Parameter(Timestamp const& v)
59+
: Parameter(PrivateConstructor{}, std::move(v)) {}
60+
explicit Parameter(absl::CivilDay const& v)
61+
: Parameter(PrivateConstructor{}, std::move(v)) {}
62+
63+
// Copy and move.
64+
Parameter(Parameter const&) = default;
65+
Parameter(Parameter&&) = default;
66+
Parameter& operator=(Parameter const&) = default;
67+
Parameter& operator=(Parameter&&) = default;
68+
69+
google::bigtable::v2::Type const& type() const { return value_.type_; }
70+
71+
friend bool operator==(Parameter const& a, Parameter const& b);
72+
friend bool operator!=(Parameter const& a, Parameter const& b) {
73+
return !(a == b);
74+
}
75+
76+
friend std::ostream& operator<<(std::ostream& os, Parameter const& p);
77+
78+
private:
79+
struct PrivateConstructor {};
80+
81+
template <typename T>
82+
Parameter(PrivateConstructor, T&& val) : value_(std::forward<T>(val)) {}
83+
84+
Value value_;
85+
};
86+
87+
/**
88+
* Represents a potentially parameterized SQL statement.
89+
*
90+
* @note `SqlStatement` equality comparisons are case-sensitive.
91+
*
92+
* Parameter placeholders are specified by `@<param name>` in the SQL string.
93+
* Values for parameters are a collection of `std::pair<std::string const,
94+
* google::cloud:bigtable::Value>`.
95+
*/
96+
class SqlStatement {
97+
public:
98+
/// Type alias for parameter collection.
99+
/// The key represents the name of the parameter.
100+
using ParamType = std::unordered_map<std::string, Parameter>;
101+
102+
SqlStatement() = default;
103+
/// Constructs a SqlStatement without parameters.
104+
explicit SqlStatement(std::string statement)
105+
: statement_(std::move(statement)) {}
106+
/// Constructs a SqlStatement with specified parameters.
107+
SqlStatement(std::string statement, ParamType params)
108+
: statement_(std::move(statement)), params_(std::move(params)) {}
109+
110+
/// Copy and move.
111+
SqlStatement(SqlStatement const&) = default;
112+
SqlStatement(SqlStatement&&) = default;
113+
SqlStatement& operator=(SqlStatement const&) = default;
114+
SqlStatement& operator=(SqlStatement&&) = default;
115+
116+
/**
117+
* Returns the SQL statement.
118+
* No parameter substitution is performed in the statement string.
119+
*/
120+
std::string const& sql() const { return statement_; }
121+
122+
/**
123+
* Returns the collection of parameters.
124+
* @return If no parameters were specified, the container will be empty.
125+
*/
126+
ParamType const& params() const { return params_; }
127+
128+
/**
129+
* Returns the names of all the parameters.
130+
*/
131+
std::vector<std::string> ParameterNames() const;
132+
133+
/**
134+
* Returns the requested parameter.
135+
* @param parameter_name name of requested parameter.
136+
* @return `StatusCode::kNotFound` returned for invalid names.
137+
*/
138+
google::cloud::StatusOr<Parameter> GetParameter(
139+
std::string const& parameter_name) const;
140+
141+
friend bool operator==(SqlStatement const& a, SqlStatement const& b) {
142+
return a.statement_ == b.statement_ && a.params_ == b.params_;
143+
}
144+
friend bool operator!=(SqlStatement const& a, SqlStatement const& b) {
145+
return !(a == b);
146+
}
147+
148+
/**
149+
* Outputs a string representation of the given @p stmt to the given @p os.
150+
*
151+
* @warning This is intended for debugging and human consumption only, not
152+
* machine consumption, as the output format may change without notice.
153+
*/
154+
friend std::ostream& operator<<(std::ostream& os, SqlStatement const& stmt);
155+
156+
private:
157+
friend struct bigtable_internal::SqlStatementInternals;
158+
159+
std::string statement_;
160+
ParamType params_;
161+
};
162+
163+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
164+
} // namespace bigtable
165+
166+
// Internal implementation details that callers should not use.
167+
namespace bigtable_internal {
168+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
169+
using PrepareQueryProto = ::google::bigtable::v2::PrepareQueryRequest;
170+
struct SqlStatementInternals {
171+
static PrepareQueryProto ToProto(bigtable::SqlStatement s,
172+
bigtable::InstanceResource const& r);
173+
};
174+
175+
inline PrepareQueryProto ToProto(bigtable::SqlStatement s,
176+
bigtable::InstanceResource const& r) {
177+
return SqlStatementInternals::ToProto(std::move(s), r);
178+
}
179+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
180+
} // namespace bigtable_internal
181+
} // namespace cloud
182+
} // namespace google
183+
184+
#endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_BIGTABLE_SQL_STATEMENT_H

0 commit comments

Comments
 (0)