Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for JSON data type in Spanner #6390

Merged
merged 3 commits into from
Aug 23, 2021

Conversation

olavloite
Copy link
Contributor

@olavloite olavloite commented Apr 28, 2021

Introduces support for the new JSON data type to Spanner. JSON is represented as plain strings in the client library, and no parsing or checking of the JSON is done by the client. As strings are also used to represent the STRING data type in Spanner, there is no default mapping from one Clr type to the JSON data type. That means that a client application must set SpannerDbType.Json as the type of a parameter that should be interpreted and sent as JSON to Spanner. (This is equal to the behavior of the DATE data type that also does not have a corresponding Clr type, as DateTime is already used for TIMESTAMP.)

@olavloite olavloite added the do not merge Indicates a pull request not ready for merge, due to either quality or timing. label Apr 28, 2021
@olavloite olavloite requested a review from zoercai April 28, 2021 19:08
@olavloite olavloite requested a review from a team as a code owner April 28, 2021 19:08
@google-cla google-cla bot added the cla: yes This human has signed the Contributor License Agreement. label Apr 28, 2021
@jskeet
Copy link
Collaborator

jskeet commented Apr 29, 2021

I will have a look at this when I get the chance, but it may not be before Tuesday (due to vacation and a public holiday).

Copy link
Contributor

@skuruppu skuruppu left a comment

Choose a reason for hiding this comment

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

Looks good from my perspective but I will let @jskeet review first before approving.

Copy link
Collaborator

@jskeet jskeet left a comment

Choose a reason for hiding this comment

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

Mostly fine - I'd just like to see valid values in the tests.

@@ -45,11 +44,15 @@ public async Task GetSchemaTable_WithFlagEnabled_ReturnsNull()
{
using (var connection = new SpannerConnection($"{_fixture.ConnectionString};EnableGetSchemaTable=true"))
{
var command = connection.CreateSelectCommand($"SELECT Int64Value, BytesArrayValue FROM {_fixture.TableName}");
var sql = _fixture.RunningOnEmulator
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it would be cleaner to have a separate to for JSON schema values. Most of what's tested is here doesn't really correspond with "GetSchemaTable with the flag enabled returns null".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think that this test case more in general could need some work:

  1. The _ReturnsNull suffix indicates that the method should return null with the flag enabled, but it actually does the opposite: Enabling the flag will ensure that the method does not return null.
  2. The current method only checks the return values of Int64 and BytesArray columns. I think it would be valuable to cover all the data types in this test case. It already uses a table that contains columns with all supported data types, so it would only be a matter of adding assertions for the other columns as well. (This is the reason I chose to add the assertions for JSON here)

WDYT?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Agreed about the suffix being odd. (I can't remember the history of this test.)

I think if we want to handle all types, we probably want a complete rewrite of the test, ideally separately from this PR. I could probably do that in the next week or so, if this PR can wait for that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, that shouldn't be a problem, it will probably take a little longer before this PR can be merged.

(I'm also happy to take it on, if that would be easier for you)

Copy link
Collaborator

Choose a reason for hiding this comment

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

If you've got the time, that would be great, thanks. Feel free to change your mind and push it back to me :)

Copy link
Collaborator

@jskeet jskeet left a comment

Choose a reason for hiding this comment

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

Out of interest, do we expect the emulator to support JSON at the same time as the production service? If so, I think I'd prefer to see the PR with unconditional tests that fail on the emulator... the code will be so much simpler.

@@ -45,11 +44,15 @@ public async Task GetSchemaTable_WithFlagEnabled_ReturnsNull()
{
using (var connection = new SpannerConnection($"{_fixture.ConnectionString};EnableGetSchemaTable=true"))
{
var command = connection.CreateSelectCommand($"SELECT Int64Value, BytesArrayValue FROM {_fixture.TableName}");
var sql = _fixture.RunningOnEmulator
Copy link
Collaborator

Choose a reason for hiding this comment

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

Agreed about the suffix being odd. (I can't remember the history of this test.)

I think if we want to handle all types, we probably want a complete rewrite of the test, ideally separately from this PR. I could probably do that in the next week or so, if this PR can wait for that?

@olavloite
Copy link
Contributor Author

Out of interest, do we expect the emulator to support JSON at the same time as the production service? If so, I think I'd prefer to see the PR with unconditional tests that fail on the emulator... the code will be so much simpler.

No, unfortunately the emulator will normally implement new features of Cloud Spanner with a delay of 2-3 months (but could be more, could be less). For the NUMERIC data type, which was the previous similar addition, it took a little more than 3 months between the official release and before it was available on the emulator.

Copy link
Contributor

@amanda-tarafa amanda-tarafa left a comment

Choose a reason for hiding this comment

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

I think you might be missing an update to BindingTests

@snippet-bot
Copy link

snippet-bot bot commented May 12, 2021

No region tags are edited in this PR.

This comment is generated by snippet-bot.
If you find problems with this result, please file an issue at:
https://github.com/googleapis/repo-automation-bots/issues.
To update this comment, add snippet-bot:force-run label or use the checkbox below:

  • Refresh this comment

@olavloite
Copy link
Contributor Author

I think you might be missing an update to BindingTests

Good point, thanks. I've added tests for JSON to the BindingTests as well.

I've also removed the special handling of NUMERIC from the tests here: #6456

@skuruppu
Copy link
Contributor

skuruppu commented Jun 9, 2021

@olavloite if you could handle the conflicts on this PR, that would be awesome.

@jskeet and @amanda-tarafa if you could please take another look and approve, that would be great. We're getting close to being able to merge this PR.

Copy link
Collaborator

@jskeet jskeet left a comment

Choose a reason for hiding this comment

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

Just re-reviewed - looks fine to me, thanks. Will merge after collisions have been resolved.

@jskeet
Copy link
Collaborator

jskeet commented Jun 9, 2021

Sorry, just re-read - I won't merge until given the green light explicitly :)

@jskeet
Copy link
Collaborator

jskeet commented Jun 24, 2021

#6659 now includes the JSON type - does that mean this can be rebased and merged?

@skuruppu
Copy link
Contributor

Since the tests are passing, yes absolutely :)

@olavloite olavloite removed the do not merge Indicates a pull request not ready for merge, due to either quality or timing. label Jun 24, 2021
@olavloite
Copy link
Contributor Author

#6659 now includes the JSON type - does that mean this can be rebased and merged?

It's now been rebased and cleaned up. As far as I'm concerned, it is ready to be merged.

@jskeet
Copy link
Collaborator

jskeet commented Jun 24, 2021

Hmm... it's showing conflicts at the moment. Could you rebase against master and force push again? I'll then review (which may well be tomorrow rather than today) and merge if I have no further comments.

@olavloite
Copy link
Contributor Author

Hmm... it's showing conflicts at the moment. Could you rebase against master and force push again? I'll then review (which may well be tomorrow rather than today) and merge if I have no further comments.

Huh, I'm not seeing any conflicts at the moment... Could it be that your browser is loading the PR from cache?

@jskeet
Copy link
Collaborator

jskeet commented Jun 24, 2021

Could it be that your browser is loading the PR from cache?

Nope, force reloaded. This is what I'm seeing at the bottom of the PR - which may be because I've got the "Rebase and merge" option selects (and that's what I'd want to use):

Rebase failure

@olavloite
Copy link
Contributor Author

Ah, I see. (The Squash and merge which is the default I'm seeing does not indicate any merge problems). I'll have a look.

test: use valid JSON values in tests

test: add binding tests for JSON

fix: remove unused sample tags

fix: fix and add back tests losts in rebase
@olavloite
Copy link
Contributor Author

I've rebased and squashed it down to one commit. PTAL when you have time.

@jskeet
Copy link
Collaborator

jskeet commented Jun 24, 2021

Great, thanks - have been advised to hold off actually merging temporarily anyway, but I'll review when I can just to remind myself of it, and be ready to merge when given the go-ahead.

Copy link
Collaborator

@jskeet jskeet left a comment

Choose a reason for hiding this comment

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

Basically still fine - a few comments that could be cleaned up. I'm going to hold off merging as advised even after that though.

case TypeCode.Json:
if (value is string jsonString)
{
return new Value { StringValue = jsonString };
Copy link
Collaborator

Choose a reason for hiding this comment

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

Note to self: after this is merged, I'll rewrite all of these "new Value" to "Value.FromString" etc.

@skuruppu
Copy link
Contributor

If everyone is ok with it, and since the tests are passing, let's merge this PR :)

@skuruppu skuruppu merged commit 7c6a6f1 into googleapis:master Aug 23, 2021
amanda-tarafa added a commit to amanda-tarafa/google-cloud-dotnet that referenced this pull request Aug 24, 2021
Changes in Google.Cloud.Spanner.Data version 3.12.0:

- [Commit 7c6a6f1](googleapis@7c6a6f1): feat: add support for JSON data type in Spanner ([issue 6390](googleapis#6390))
- [Commit ac367e2](googleapis@ac367e2): feat: Regenerate all APIs to support self-signed JWTs
- [Commit 61938b6](googleapis@61938b6):
  - feat(Spanner): Support comments and statement hints in untyped commands.
  - Alternative to [issue 6848](googleapis#6848)
  - Closes [issue 6847](googleapis#6847)
- [Commit d26b04c](googleapis@d26b04c): fix: address review comments
- [Commit d2025be](googleapis@d2025be): fix: use logger from SpannerSettings
- [Commit b34f6f4](googleapis@b34f6f4): cleanup: fix comment + remove unnecessary import
- [Commit fc7a41b](googleapis@fc7a41b): test: remove connectionstring tests and add settings test
- [Commit 6016ef0](googleapis@6016ef0):
  - feat: support custom SpannerSettings in SessionPoolManager
  - Support setting custom SpannerSettings when creating a SessionPoolManager.
- [Commit 0ab6b8b](googleapis@0ab6b8b):
  - feat: allow adding an additional version header
  - Allows adding an additional version header to the connection string. This will be
  - added to the `x-goog-api-client` header that is used by the underlying Spanner client.
  - Only a fixed set of values may be set for the header (currently only 'efcore' is
  - allowed), and the property is not intended for public use.
- [Commit 250124f](googleapis@250124f):
  - fix: synchronize access to the underlying transaction for ambient transactions ([issue 6616](googleapis#6616))
  - * fix: synchronize access to the underlying transaction for ambient transactions
  - Synchronizes access to the underlying Spanner transaction to prevent
  - multiple transactions from being created if parallel commands are
  - executed on the ambient transaction.
  - * test: add integration test
  - * fix: use Lazy for initialization
  - * chore: address review comments
  - * fix: remove unnecessary read call

Packages in this release:
- Release Google.Cloud.Spanner.Admin.Database.V1 version 3.12.0
- Release Google.Cloud.Spanner.Admin.Instance.V1 version 3.12.0
- Release Google.Cloud.Spanner.Common.V1 version 3.12.0
- Release Google.Cloud.Spanner.Data version 3.12.0
- Release Google.Cloud.Spanner.V1 version 3.12.0
gcf-merge-on-green bot pushed a commit that referenced this pull request Aug 24, 2021
Changes in Google.Cloud.Spanner.Data version 3.12.0:

- [Commit 7c6a6f1](7c6a6f1): feat: add support for JSON data type in Spanner ([issue 6390](#6390))
- [Commit ac367e2](ac367e2): feat: Regenerate all APIs to support self-signed JWTs
- [Commit 61938b6](61938b6):
  - feat(Spanner): Support comments and statement hints in untyped commands.
  - Alternative to [issue 6848](#6848)
  - Closes [issue 6847](#6847)
- [Commit d26b04c](d26b04c): fix: address review comments
- [Commit d2025be](d2025be): fix: use logger from SpannerSettings
- [Commit b34f6f4](b34f6f4): cleanup: fix comment + remove unnecessary import
- [Commit fc7a41b](fc7a41b): test: remove connectionstring tests and add settings test
- [Commit 6016ef0](6016ef0):
  - feat: support custom SpannerSettings in SessionPoolManager
  - Support setting custom SpannerSettings when creating a SessionPoolManager.
- [Commit 0ab6b8b](0ab6b8b):
  - feat: allow adding an additional version header
  - Allows adding an additional version header to the connection string. This will be
  - added to the `x-goog-api-client` header that is used by the underlying Spanner client.
  - Only a fixed set of values may be set for the header (currently only 'efcore' is
  - allowed), and the property is not intended for public use.
- [Commit 250124f](250124f):
  - fix: synchronize access to the underlying transaction for ambient transactions ([issue 6616](#6616))
  - * fix: synchronize access to the underlying transaction for ambient transactions
  - Synchronizes access to the underlying Spanner transaction to prevent
  - multiple transactions from being created if parallel commands are
  - executed on the ambient transaction.
  - * test: add integration test
  - * fix: use Lazy for initialization
  - * chore: address review comments
  - * fix: remove unnecessary read call

Packages in this release:
- Release Google.Cloud.Spanner.Admin.Database.V1 version 3.12.0
- Release Google.Cloud.Spanner.Admin.Instance.V1 version 3.12.0
- Release Google.Cloud.Spanner.Common.V1 version 3.12.0
- Release Google.Cloud.Spanner.Data version 3.12.0
- Release Google.Cloud.Spanner.V1 version 3.12.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes This human has signed the Contributor License Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants