Skip to content

Commit 2ba1571

Browse files
authored
feat(spanner): convert ReadOptions/PartitionOptions to Options (#8448)
Add an `Options opts = {}` argument to `Read()`, `PartitionRead()`, and `PartitionQuery()`, and relegate their `ReadOptions` and `PartitionOptions` overloads to the "backwards compatibility" section. The new `Options` overloads also begin an `OptionsSpan`. Add `ReadOptions`/`PartitionOptions`-to/from-`Options` conversion functions to facilitate those compatibility interfaces, and add round-trip tests. This required adding new Spanner-specific options `ReadIndexNameOption`, `ReadRowLimitOption`, `PartitionSizeOption`, and `PartitionsMaximumOption`. Update the samples to use the preferred `Options` overloads. Part of #7690.
1 parent 6445a74 commit 2ba1571

File tree

13 files changed

+298
-44
lines changed

13 files changed

+298
-44
lines changed

google/cloud/spanner/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ add_library(
167167
query_options.h
168168
query_partition.cc
169169
query_partition.h
170+
read_options.cc
170171
read_options.h
171172
read_partition.cc
172173
read_partition.h

google/cloud/spanner/client.cc

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,56 +45,57 @@ absl::optional<typename OptionType::Type> OptOpt(Options const& opts) {
4545
} // namespace
4646

4747
RowStream Client::Read(std::string table, KeySet keys,
48-
std::vector<std::string> columns,
49-
ReadOptions read_options) {
48+
std::vector<std::string> columns, Options opts) {
49+
internal::OptionsSpan span(internal::MergeOptions(std::move(opts), opts_));
5050
return conn_->Read({spanner_internal::MakeSingleUseTransaction(
5151
Transaction::ReadOnlyOptions()),
5252
std::move(table),
5353
std::move(keys),
5454
std::move(columns),
55-
std::move(read_options),
55+
ToReadOptions(internal::CurrentOptions()),
5656
{}});
5757
}
5858

5959
RowStream Client::Read(Transaction::SingleUseOptions transaction_options,
6060
std::string table, KeySet keys,
61-
std::vector<std::string> columns,
62-
ReadOptions read_options) {
61+
std::vector<std::string> columns, Options opts) {
62+
internal::OptionsSpan span(internal::MergeOptions(std::move(opts), opts_));
6363
return conn_->Read({spanner_internal::MakeSingleUseTransaction(
6464
std::move(transaction_options)),
6565
std::move(table),
6666
std::move(keys),
6767
std::move(columns),
68-
std::move(read_options),
68+
ToReadOptions(internal::CurrentOptions()),
6969
{}});
7070
}
7171

7272
RowStream Client::Read(Transaction transaction, std::string table, KeySet keys,
73-
std::vector<std::string> columns,
74-
ReadOptions read_options) {
73+
std::vector<std::string> columns, Options opts) {
74+
internal::OptionsSpan span(internal::MergeOptions(std::move(opts), opts_));
7575
return conn_->Read({std::move(transaction),
7676
std::move(table),
7777
std::move(keys),
7878
std::move(columns),
79-
std::move(read_options),
79+
ToReadOptions(internal::CurrentOptions()),
8080
{}});
8181
}
8282

83-
RowStream Client::Read(ReadPartition const& read_partition) {
83+
RowStream Client::Read(ReadPartition const& read_partition, Options opts) {
84+
internal::OptionsSpan span(internal::MergeOptions(std::move(opts), opts_));
8485
return conn_->Read(spanner_internal::MakeReadParams(read_partition));
8586
}
8687

8788
StatusOr<std::vector<ReadPartition>> Client::PartitionRead(
8889
Transaction transaction, std::string table, KeySet keys,
89-
std::vector<std::string> columns, ReadOptions read_options,
90-
PartitionOptions const& partition_options) {
90+
std::vector<std::string> columns, Options opts) {
91+
internal::OptionsSpan span(internal::MergeOptions(std::move(opts), opts_));
9192
return conn_->PartitionRead({{std::move(transaction),
9293
std::move(table),
9394
std::move(keys),
9495
std::move(columns),
95-
std::move(read_options),
96+
ToReadOptions(internal::CurrentOptions()),
9697
{}},
97-
partition_options});
98+
ToPartitionOptions(internal::CurrentOptions())});
9899
}
99100

100101
RowStream Client::ExecuteQuery(SqlStatement statement, Options opts) {
@@ -163,10 +164,11 @@ ProfileQueryResult Client::ProfileQuery(Transaction transaction,
163164
}
164165

165166
StatusOr<std::vector<QueryPartition>> Client::PartitionQuery(
166-
Transaction transaction, SqlStatement statement,
167-
PartitionOptions const& partition_options) {
167+
Transaction transaction, SqlStatement statement, Options opts) {
168+
internal::OptionsSpan span(internal::MergeOptions(std::move(opts), opts_));
168169
return conn_->PartitionQuery(
169-
{std::move(transaction), std::move(statement), partition_options});
170+
{std::move(transaction), std::move(statement),
171+
ToPartitionOptions(internal::CurrentOptions())});
170172
}
171173

172174
StatusOr<DmlResult> Client::ExecuteDml(Transaction transaction,

google/cloud/spanner/client.h

Lines changed: 86 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ class Client {
181181
* not exist in the database; `Read` yields nothing for nonexistent rows.
182182
* @param columns The columns of `table` to be returned for each row matching
183183
* this request.
184-
* @param read_options `ReadOptions` used for this request.
184+
* @param opts `Options` used for this request.
185185
*
186186
* @par Example
187187
* @snippet samples.cc read-data
@@ -190,8 +190,7 @@ class Client {
190190
* column value can exceed 10 MiB.
191191
*/
192192
RowStream Read(std::string table, KeySet keys,
193-
std::vector<std::string> columns,
194-
ReadOptions read_options = {});
193+
std::vector<std::string> columns, Options opts = {});
195194

196195
/**
197196
* @copydoc Read
@@ -201,33 +200,73 @@ class Client {
201200
*/
202201
RowStream Read(Transaction::SingleUseOptions transaction_options,
203202
std::string table, KeySet keys,
204-
std::vector<std::string> columns,
205-
ReadOptions read_options = {});
203+
std::vector<std::string> columns, Options opts = {});
206204

207205
/**
208206
* @copydoc Read
209207
*
210208
* @param transaction Execute this read as part of an existing transaction.
211209
*/
212210
RowStream Read(Transaction transaction, std::string table, KeySet keys,
213-
std::vector<std::string> columns,
214-
ReadOptions read_options = {});
211+
std::vector<std::string> columns, Options opts = {});
215212
//@}
216213

214+
/// @name Backwards compatibility for `ReadOptions`.
215+
///@{
216+
RowStream Read(std::string table, KeySet keys,
217+
std::vector<std::string> columns,
218+
ReadOptions const& read_options) {
219+
return Read(std::move(table), std::move(keys), std::move(columns),
220+
ToOptions(read_options));
221+
}
222+
RowStream Read(std::string table, KeySet keys,
223+
std::vector<std::string> columns,
224+
std::initializer_list<internal::NonConstructible>) {
225+
return Read(std::move(table), std::move(keys), std::move(columns));
226+
}
227+
RowStream Read(Transaction::SingleUseOptions transaction_options,
228+
std::string table, KeySet keys,
229+
std::vector<std::string> columns,
230+
ReadOptions const& read_options) {
231+
return Read(std::move(transaction_options), std::move(table),
232+
std::move(keys), std::move(columns), ToOptions(read_options));
233+
}
234+
RowStream Read(Transaction::SingleUseOptions transaction_options,
235+
std::string table, KeySet keys,
236+
std::vector<std::string> columns,
237+
std::initializer_list<internal::NonConstructible>) {
238+
return Read(std::move(transaction_options), std::move(table),
239+
std::move(keys), std::move(columns));
240+
}
241+
RowStream Read(Transaction transaction, std::string table, KeySet keys,
242+
std::vector<std::string> columns,
243+
ReadOptions const& read_options) {
244+
return Read(std::move(transaction), std::move(table), std::move(keys),
245+
std::move(columns), ToOptions(read_options));
246+
}
247+
RowStream Read(Transaction transaction, std::string table, KeySet keys,
248+
std::vector<std::string> columns,
249+
std::initializer_list<internal::NonConstructible>) {
250+
return Read(std::move(transaction), std::move(table), std::move(keys),
251+
std::move(columns));
252+
}
253+
///@}
254+
217255
/**
218256
* Reads rows from a subset of rows in a database. Requires a prior call
219257
* to `PartitionRead` to obtain the partition information; see the
220258
* documentation of that method for full details.
221259
*
222260
* @param partition A `ReadPartition`, obtained by calling `PartitionRead`.
261+
* @param opts `Options` used for this request.
223262
*
224263
* @note No individual row in the `ReadResult` can exceed 100 MiB, and no
225264
* column value can exceed 10 MiB.
226265
*
227266
* @par Example
228267
* @snippet samples.cc read-read-partition
229268
*/
230-
RowStream Read(ReadPartition const& partition);
269+
RowStream Read(ReadPartition const& partition, Options opts = {});
231270

232271
/**
233272
* Creates a set of partitions that can be used to execute a read
@@ -252,8 +291,7 @@ class Client {
252291
* not exist in the database; `Read` yields nothing for nonexistent rows.
253292
* @param columns The columns of `table` to be returned for each row matching
254293
* this request.
255-
* @param read_options `ReadOptions` used for this request.
256-
* @param partition_options `PartitionOptions` used for this request.
294+
* @param opts `Options` used for this request.
257295
*
258296
* @return A `StatusOr` containing a vector of `ReadPartition` or error
259297
* status on failure.
@@ -263,8 +301,27 @@ class Client {
263301
*/
264302
StatusOr<std::vector<ReadPartition>> PartitionRead(
265303
Transaction transaction, std::string table, KeySet keys,
266-
std::vector<std::string> columns, ReadOptions read_options = {},
267-
PartitionOptions const& partition_options = PartitionOptions{});
304+
std::vector<std::string> columns, Options opts = {});
305+
306+
/// @name Backwards compatibility for `ReadOptions` and `PartitionOptions`.
307+
///@{
308+
StatusOr<std::vector<ReadPartition>> PartitionRead(
309+
Transaction transaction, std::string table, KeySet keys,
310+
std::vector<std::string> columns, ReadOptions const& read_options,
311+
PartitionOptions const& partition_options) {
312+
return PartitionRead(std::move(transaction), std::move(table),
313+
std::move(keys), std::move(columns),
314+
internal::MergeOptions(ToOptions(read_options),
315+
ToOptions(partition_options)));
316+
}
317+
StatusOr<std::vector<ReadPartition>> PartitionRead(
318+
Transaction transaction, std::string table, KeySet keys,
319+
std::vector<std::string> columns,
320+
std::initializer_list<internal::NonConstructible>) {
321+
return PartitionRead(std::move(transaction), std::move(table),
322+
std::move(keys), std::move(columns));
323+
}
324+
///@}
268325

269326
//@{
270327
/**
@@ -474,7 +531,7 @@ class Client {
474531
* @param transaction The transaction to execute the operation in.
475532
* **Must** be a read-only snapshot transaction.
476533
* @param statement The SQL statement to execute.
477-
* @param partition_options `PartitionOptions` used for this request.
534+
* @param opts `Options` used for this request.
478535
*
479536
* @return A `StatusOr` containing a vector of `QueryPartition`s or error
480537
* status on failure.
@@ -484,7 +541,22 @@ class Client {
484541
*/
485542
StatusOr<std::vector<QueryPartition>> PartitionQuery(
486543
Transaction transaction, SqlStatement statement,
487-
PartitionOptions const& partition_options = PartitionOptions{});
544+
Options opts = Options{});
545+
546+
/// @name Backwards compatibility for `PartitionOptions`.
547+
///@{
548+
StatusOr<std::vector<QueryPartition>> PartitionQuery(
549+
Transaction transaction, SqlStatement statement,
550+
PartitionOptions const& partition_options) {
551+
return PartitionQuery(std::move(transaction), std::move(statement),
552+
ToOptions(partition_options));
553+
}
554+
StatusOr<std::vector<QueryPartition>> PartitionQuery(
555+
Transaction transaction, SqlStatement statement,
556+
std::initializer_list<internal::NonConstructible>) {
557+
return PartitionQuery(std::move(transaction), std::move(statement));
558+
}
559+
///@}
488560

489561
/**
490562
* Executes a SQL DML statement.

google/cloud/spanner/google_cloud_cpp_spanner.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ google_cloud_cpp_spanner_srcs = [
172172
"partition_options.cc",
173173
"query_options.cc",
174174
"query_partition.cc",
175+
"read_options.cc",
175176
"read_partition.cc",
176177
"results.cc",
177178
"row.cc",

google/cloud/spanner/internal/connection_impl.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,13 +325,13 @@ class StreamingPartitionedDmlResult {
325325

326326
std::shared_ptr<spanner::RetryPolicy> const&
327327
ConnectionImpl::RetryPolicyPrototype() const {
328-
// TODO(#7690): Base this on internal::CurrentOptions().
328+
// TODO(#4528) TODO(#7690): Base this on internal::CurrentOptions().
329329
return opts_.get<spanner::SpannerRetryPolicyOption>();
330330
}
331331

332332
std::shared_ptr<spanner::BackoffPolicy> const&
333333
ConnectionImpl::BackoffPolicyPrototype() const {
334-
// TODO(#7690): Base this on internal::CurrentOptions().
334+
// TODO(#4528) TODO(#7690): Base this on internal::CurrentOptions().
335335
return opts_.get<spanner::SpannerBackoffPolicyOption>();
336336
}
337337

google/cloud/spanner/options.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,48 @@ struct RequestTagOption {
186186
using Type = std::string;
187187
};
188188

189+
/**
190+
* Option for `google::cloud::Options` to set the name of an index on a
191+
* database table. This index is used instead of the table primary key when
192+
* interpreting the `KeySet` and sorting result rows.
193+
*/
194+
struct ReadIndexNameOption {
195+
using Type = std::string;
196+
};
197+
198+
/**
199+
* Option for `google::cloud::Options` to set a limit on the number of rows
200+
* to yield from `Client::Read()`. There is no limit when the option is unset,
201+
* or when it is set to 0.
202+
*/
203+
struct ReadRowLimitOption {
204+
using Type = std::int64_t;
205+
};
206+
207+
/**
208+
* Option for `google::cloud::Options` to set the desired partition size to
209+
* be generated by `Client::PartitionRead()` or `PartitionQuery()`.
210+
*
211+
* The default for this option is currently 1 GiB. This is only a hint. The
212+
* actual size of each partition may be smaller or larger than this request.
213+
*/
214+
struct PartitionSizeOption {
215+
using Type = std::int64_t;
216+
};
217+
218+
/**
219+
* Option for `google::cloud::Options` to set the desired maximum number of
220+
* partitions to return from `Client::PartitionRead()` or `PartitionQuery()`.
221+
*
222+
* For example, this may be set to the number of workers available. The
223+
* default for this option is currently 10,000. The maximum value is
224+
* currently 200,000. This is only a hint. The actual number of partitions
225+
* returned may be smaller or larger than this request.
226+
*/
227+
struct PartitionsMaximumOption {
228+
using Type = std::int64_t;
229+
};
230+
189231
/**
190232
* Option for `google::cloud::Options` to set a per-transaction tag.
191233
*/

google/cloud/spanner/partition_options.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,38 @@
1313
// limitations under the License.
1414

1515
#include "google/cloud/spanner/partition_options.h"
16+
#include "google/cloud/spanner/options.h"
1617

1718
namespace google {
1819
namespace cloud {
20+
namespace spanner {
21+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
22+
23+
Options ToOptions(PartitionOptions const& po) {
24+
Options opts;
25+
if (po.partition_size_bytes) {
26+
opts.set<PartitionSizeOption>(*po.partition_size_bytes);
27+
}
28+
if (po.max_partitions) {
29+
opts.set<PartitionsMaximumOption>(*po.max_partitions);
30+
}
31+
return opts;
32+
}
33+
34+
PartitionOptions ToPartitionOptions(Options const& opts) {
35+
PartitionOptions po;
36+
if (opts.has<PartitionSizeOption>()) {
37+
po.partition_size_bytes = opts.get<PartitionSizeOption>();
38+
}
39+
if (opts.has<PartitionsMaximumOption>()) {
40+
po.max_partitions = opts.get<PartitionsMaximumOption>();
41+
}
42+
return po;
43+
}
44+
45+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
46+
} // namespace spanner
47+
1948
namespace spanner_internal {
2049
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
2150

0 commit comments

Comments
 (0)