Skip to content
This repository was archived by the owner on Dec 8, 2021. It is now read-only.

feat!: support for select-star queries #976

Merged
merged 16 commits into from
Oct 24, 2019
Merged

Conversation

devjgm
Copy link
Contributor

@devjgm devjgm commented Oct 24, 2019

Fixes #387

BREAKING CHANGE: This PR changes QueryResult and ProfileQueryResult to themselves be ranges with begin() and end() member functions. Users can now directly use these objects in range-for loops. This gives users access to each row in a dynamic way allow them to inspect each row's values by column name, index, or iterate each value in the row.

Users may also wrap these objects in a StreamOf<Tuple>, which will parse each row into the given Tuple.

This PR also removes RowParser<T>


This change is Reviewable

@devjgm devjgm requested review from coryan and mr-salty October 24, 2019 00:22
@googlebot googlebot added the cla: yes This human has signed the Contributor License Agreement. label Oct 24, 2019
@codecov
Copy link

codecov bot commented Oct 24, 2019

Codecov Report

Merging #976 into master will increase coverage by 0.01%.
The diff coverage is 98.31%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #976      +/-   ##
==========================================
+ Coverage   94.12%   94.14%   +0.01%     
==========================================
  Files          96      159      +63     
  Lines        4068    10640    +6572     
==========================================
+ Hits         3829    10017    +6188     
- Misses        239      623     +384
Impacted Files Coverage Δ
...cloud/spanner/internal/partial_result_set_source.h 100% <ø> (ø) ⬆️
google/cloud/spanner/client.h 100% <ø> (ø) ⬆️
...anner/integration_tests/client_integration_test.cc 99.46% <100%> (ø)
.../spanner/integration_tests/throughput_benchmark.cc 72.07% <100%> (ø)
google/cloud/spanner/results.h 90.9% <100%> (+0.9%) ⬆️
google/cloud/spanner/client_test.cc 95.25% <100%> (ø)
...ogle/cloud/spanner/mocks/mock_spanner_connection.h 60% <100%> (ø) ⬆️
google/cloud/spanner/results_test.cc 93.45% <100%> (ø)
google/cloud/spanner/row.h 89.04% <100%> (+0.98%) ⬆️
...gle/cloud/spanner/internal/connection_impl_test.cc 93.83% <100%> (ø)
... and 76 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 05ebaec...8819d3e. Read the comment docs.

Copy link
Contributor

@coryan coryan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few nits and suggestions in the comments.

I must confess that I cannot quite follow if move semantics are supported, so I will just ask: how do I write a query returning large strings or bytes such that those are not copied too many times?

Reviewed 24 of 24 files at r1.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @devjgm and @mr-salty)


google/cloud/spanner/results.h, line 56 at r1 (raw file):

 * A `QueryResult` object is itself a range defined by the [Input
 * Iterators][input-iterator] returned from `begin()` and `end(). Callers may
 * directly iterator a `QueryResult` instance, which will return a sequence of

nit: "directly iterator"? maybe "directly iterate"?


google/cloud/spanner/row.h, line 198 at r1 (raw file):

/**
 * Creates a `Row` with the specified column names and values that may be

Consider removing "that may be useful when testing" and adding something to the long description, such as " ... that goes in each column. This function in intended for application developers mocking the results of a ExecuteQuery call".


google/cloud/spanner/row.h, line 208 at r1 (raw file):

/**
 * Creates a `Row` with autogenerated column names that may be useful when
 * testing.

same suggestions as above regarding "may be useful".


google/cloud/spanner/row.h, line 405 at r1 (raw file):

   * must be a range defined by `RowStreamIterator` objects.
   *
   * Ownership of the @p range is not transferred, so it must outlive the

That deserves a @note or even @warning.

Copy link
Contributor Author

@devjgm devjgm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless there's a bug or an accidentally forgotten && somewhere, I think efficient moves are the normal behavior that users will naturally get. For example, I think all of our examples and samples do this correctly and have the least possible number of copies. Let me annotate an example with places where Values might be copied/moved:

QueryResult result = c.Read(...);  // [1]
for (auto tup : StreamOf<RowType>(result)) {  // [2], [3]
  if (!tup) {  // [4]
    ...
  }
  auto const& x = std::get<0>(*tup);  // [5]
  auto y = std::move(std::get<0>(*tup));  // [6]
  auto z = std::get<0>(*tup);  // [7]
}

Here's what I think happens in that example:

  1. The Read() starts. Some Values may trickle in at this point (whatever was returned in the first response). Those are moved into the PartialResultSetSource::buffer_ vector.
  2. As we iterate the result range via its RowStreamIterator the proto values in the buffer_(mentioned in the previous step) are moved into spanner::Valueobjects to fill a Row. That vector of spanner::Value is then moved into Row, one Row for each iteration. So far only moves, no copies.
  3. Then StreamOfconsumes and parses each Row (from the previous step) into the specified tuple. It calls the &&-qualified overload of Row::get<T>() to make sure the values are moved as efficiently as possible. Oops! Wait, no it doesn't. It was accidentally copying here. Fix included in this PR. Fixed. Now, the caller is catching the returned tuple by-value in this case (auto tup), but that's a caller choice. This would be good if they then want to move out of the tuple.
  4. Actually, the rest of the numbered lines here are all just normal tuple stuff that I'm sure you know, so I'll stop here.

Reviewable status: 22 of 24 files reviewed, 1 unresolved discussion (waiting on @coryan and @mr-salty)


google/cloud/spanner/row.h, line 198 at r1 (raw file):

Previously, coryan (Carlos O'Ryan) wrote…

Consider removing "that may be useful when testing" and adding something to the long description, such as " ... that goes in each column. This function in intended for application developers mocking the results of a ExecuteQuery call".

Good suggestion. Done here and for the next function too.


google/cloud/spanner/row.h, line 405 at r1 (raw file):

Previously, coryan (Carlos O'Ryan) wrote…

That deserves a @note or even @warning.

I added this is as a @note. I don't think this is a particularly sharp edge. Callers would have to go pretty far out of their way to do this wrong. The "easy" mistake might be to pass a temporary range argument, but there's a static_assert in the c'tor body to catch that and break the build.

Let me know if you think this still may warrant a @warning.

Copy link
Contributor

@coryan coryan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking the time to explain this. I would not have been able to catch that missing move. :lgtm:

Reviewed 2 of 2 files at r2.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on @mr-salty)


google/cloud/spanner/row.h, line 405 at r1 (raw file):

Previously, devjgm (Greg Miller) wrote…

I added this is as a @note. I don't think this is a particularly sharp edge. Callers would have to go pretty far out of their way to do this wrong. The "easy" mistake might be to pass a temporary range argument, but there's a static_assert in the c'tor body to catch that and break the build.

Let me know if you think this still may warrant a @warning.

Looks good, thanks.

@devjgm devjgm merged commit fc80623 into googleapis:master Oct 24, 2019
@devjgm devjgm deleted the select-star branch October 24, 2019 15:23
devjgm added a commit to devjgm/google-cloud-cpp that referenced this pull request May 7, 2020
…panner#976)

Fixes googleapis/google-cloud-cpp-spanner#387

BREAKING CHANGE: This PR changes QueryResult and ProfileQueryResult to themselves be ranges with begin() and end() member functions. Users can now directly use these objects in range-for loops. This gives users access to each row in a dynamic way allow them to inspect each row's values by column name, index, or iterate each value in the row.

Users may also wrap these objects in a StreamOf<Tuple>, which will parse each row into the given Tuple.

This PR also removes RowParser<T>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
cla: yes This human has signed the Contributor License Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Design a good solution for SELECT *
3 participants