From 10d7b247b6866b08fa848b02a53ecd68be365e85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Wed, 28 Apr 2021 11:30:38 +0200 Subject: [PATCH 1/3] feat: support JSON data type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: NPE was thrown when getting an array of structs from a ResultSet (#445) A NullPointerException was thrown if a ResultSet contained an array of Structs and the getArray() method was called on the column. Fixes #444 fix: cleanup and add documentation chore(deps): update dependency com.google.cloud:google-cloud-spanner-jdbc to v2.0.2 (#443) chore: regenerate README (#450) chore(deps): update dependency com.google.cloud:libraries-bom to v20.2.0 (#448) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:libraries-bom](https://togithub.com/GoogleCloudPlatform/cloud-opensource-java) | `20.1.0` -> `20.2.0` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.2.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.2.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.2.0/compatibility-slim/20.1.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.2.0/confidence-slim/20.1.0)](https://docs.renovatebot.com/merge-confidence/) | --- :date: **Schedule**: At any time (no schedule defined). :vertical_traffic_light: **Automerge**: Disabled by config. Please merge this manually once you are satisfied. :recycle: **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. :no_bell: **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). chore: add SECURITY.md (#446) chore: add SECURITY.md feat: allow get/set Spanner Value instances (#454) Adds support for getting a value from a `java.sql.ResultSet` as a `com.google.cloud.spanner.Value` instance, and for setting a parameter on a `java.sql.PreparedStatement` using a `com.google.cloud.spanner.Value` instance. Fixes #452 build(deps): update dependency org.apache.maven.plugins:maven-project-info-reports-plugin to v3.1.2 (#451) deps: update dependency com.google.cloud:google-cloud-spanner-bom to v6.4.0 (#453) chore: remove unused statements file (#458) The ClientSideStatements.json file has been moved to the Connection API in the client library and is not needed in the JDBC driver. chore: release 2.0.3-SNAPSHOT (#442) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> chore: adding cloud-rad java xrefs (#461) Source-Author: Emily Ball Source-Date: Thu May 6 11:48:47 2021 -0700 Source-Repo: googleapis/synthtool Source-Sha: 046994f491c02806aea60118e214a9edd67f5ab7 Source-Link: https://github.com/googleapis/synthtool/commit/046994f491c02806aea60118e214a9edd67f5ab7 deps: update dependency com.google.cloud:google-cloud-shared-dependencies to v1.1.0 (#463) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:google-cloud-shared-dependencies](https://togithub.com/googleapis/java-shared-dependencies) | `1.0.0` -> `1.1.0` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/1.1.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/1.1.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/1.1.0/compatibility-slim/1.0.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/1.1.0/confidence-slim/1.0.0)](https://docs.renovatebot.com/merge-confidence/) | ---
googleapis/java-shared-dependencies [Compare Source](https://togithub.com/googleapis/java-shared-dependencies/compare/v1.0.0...v1.1.0) - update dependency com.google.protobuf:protobuf-bom to v3.16.0 ([#​348](https://www.github.com/googleapis/java-shared-dependencies/issues/348)) ([0aacfde](https://www.github.com/googleapis/java-shared-dependencies/commit/0aacfdeec70e30803734db8287c47e4fad5481ef)) - update gax.version to v1.64.0 ([#​345](https://www.github.com/googleapis/java-shared-dependencies/issues/345)) ([478bd35](https://www.github.com/googleapis/java-shared-dependencies/commit/478bd35296293e81c7e70157f50bfbebdc1bb54d)) - update iam.version to v1.0.13 ([#​343](https://www.github.com/googleapis/java-shared-dependencies/issues/343)) ([3637923](https://www.github.com/googleapis/java-shared-dependencies/commit/363792392b71deff5cc5731104b631122fba5e61))
--- 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻️ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). chore(deps): update dependency com.google.cloud:libraries-bom to v20.3.0 (#462) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:libraries-bom](https://togithub.com/GoogleCloudPlatform/cloud-opensource-java) | `20.2.0` -> `20.3.0` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.3.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.3.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.3.0/compatibility-slim/20.2.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.3.0/confidence-slim/20.2.0)](https://docs.renovatebot.com/merge-confidence/) | --- 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻️ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). build(java): remove codecov action (#465) This PR was generated using Autosynth. :rainbow: Synth log will be available here: https://source.cloud.google.com/results/invocations/8e8c0070-26ea-4d86-b07a-e4dcc9e5b8b1/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) Source-Link: https://github.com/googleapis/synthtool/commit/4f4b1b9b8d8b52f1e9e4a76165896debce5ab7f1 chore(deps): update dependency com.google.cloud:libraries-bom to v20.4.0 (#466) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:libraries-bom](https://togithub.com/GoogleCloudPlatform/cloud-opensource-java) | `20.3.0` -> `20.4.0` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.4.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.4.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.4.0/compatibility-slim/20.3.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.4.0/confidence-slim/20.3.0)](https://docs.renovatebot.com/merge-confidence/) | --- 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻️ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). chore: add changelog to cloud-rad (#467) This PR was generated using Autosynth. :rainbow: Synth log will be available here: https://source.cloud.google.com/results/invocations/41862329-45d0-4225-9ed2-ad5a75997ae8/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) Source-Link: https://github.com/googleapis/synthtool/commit/c86c7a60985644eab557949363a38301d40d78d2 tests: fixes jdbc query options test (#468) * tests: fixes jdbc query options test This test was failing, because we were no longer recreating the jdbc connection from scratch. One of the tests, set an environment variable specifying the optimizer version, which was permanently applied, since the connection was not re-created. Here we make sure to start / stop the static server before each test. * chore: fixes linting errors tests: fixes sql script test (#469) In version 6.4.4 of spanner we have change the verifyStatementsInFile method to wrap any SQLExceptions into SpannerExceptions. In the failing tests we were catching SQLExceptions and ignoring them, since they were expected. We have changed the tests to also ignore the respective SpannerExceptions. deps: update dependency com.google.cloud:google-cloud-spanner-bom to v6.4.4 (#464) chore: release 2.1.0 (#460) :robot: I have created a release \*beep\* \*boop\* --- * allow get/set Spanner Value instances ([#454](https://www.github.com/googleapis/java-spanner-jdbc/issues/454)) ([d6935b8](https://www.github.com/googleapis/java-spanner-jdbc/commit/d6935b863349c58cfdd44d6ce20dba6f5dbc1472)), closes [#452](https://www.github.com/googleapis/java-spanner-jdbc/issues/452) * NPE was thrown when getting an array of structs from a ResultSet ([#445](https://www.github.com/googleapis/java-spanner-jdbc/issues/445)) ([1dfb37b](https://www.github.com/googleapis/java-spanner-jdbc/commit/1dfb37b27ee661718fe80be0bf260c40f4b15582)), closes [#444](https://www.github.com/googleapis/java-spanner-jdbc/issues/444) * update dependency com.google.cloud:google-cloud-shared-dependencies to v1.1.0 ([#463](https://www.github.com/googleapis/java-spanner-jdbc/issues/463)) ([f148c71](https://www.github.com/googleapis/java-spanner-jdbc/commit/f148c71bef2b762d7b4475ba7f28443c7938c394)) * update dependency com.google.cloud:google-cloud-spanner-bom to v6.4.0 ([#453](https://www.github.com/googleapis/java-spanner-jdbc/issues/453)) ([7dac8b3](https://www.github.com/googleapis/java-spanner-jdbc/commit/7dac8b3e43625aa28be214bd735fc3386770de04)) * update dependency com.google.cloud:google-cloud-spanner-bom to v6.4.4 ([#464](https://www.github.com/googleapis/java-spanner-jdbc/issues/464)) ([eeb31c0](https://www.github.com/googleapis/java-spanner-jdbc/commit/eeb31c050fda116203d9da5c4a80c7f1c6a6cac4)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). chore: release 2.1.1-SNAPSHOT (#470) :robot: I have created a release \*beep\* \*boop\* --- --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). chore(deps): update dependency com.google.cloud:google-cloud-spanner-jdbc to v2.1.0 (#471) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:google-cloud-spanner-jdbc](https://togithub.com/googleapis/java-spanner-jdbc) | `2.0.2` -> `2.1.0` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-jdbc/2.1.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-jdbc/2.1.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-jdbc/2.1.0/compatibility-slim/2.0.2)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-jdbc/2.1.0/confidence-slim/2.0.2)](https://docs.renovatebot.com/merge-confidence/) | ---
googleapis/java-spanner-jdbc [Compare Source](https://togithub.com/googleapis/java-spanner-jdbc/compare/v2.0.2...v2.1.0) - allow get/set Spanner Value instances ([#​454](https://www.github.com/googleapis/java-spanner-jdbc/issues/454)) ([d6935b8](https://www.github.com/googleapis/java-spanner-jdbc/commit/d6935b863349c58cfdd44d6ce20dba6f5dbc1472)), closes [#​452](https://www.github.com/googleapis/java-spanner-jdbc/issues/452) - NPE was thrown when getting an array of structs from a ResultSet ([#​445](https://www.github.com/googleapis/java-spanner-jdbc/issues/445)) ([1dfb37b](https://www.github.com/googleapis/java-spanner-jdbc/commit/1dfb37b27ee661718fe80be0bf260c40f4b15582)), closes [#​444](https://www.github.com/googleapis/java-spanner-jdbc/issues/444) - update dependency com.google.cloud:google-cloud-shared-dependencies to v1.1.0 ([#​463](https://www.github.com/googleapis/java-spanner-jdbc/issues/463)) ([f148c71](https://www.github.com/googleapis/java-spanner-jdbc/commit/f148c71bef2b762d7b4475ba7f28443c7938c394)) - update dependency com.google.cloud:google-cloud-spanner-bom to v6.4.0 ([#​453](https://www.github.com/googleapis/java-spanner-jdbc/issues/453)) ([7dac8b3](https://www.github.com/googleapis/java-spanner-jdbc/commit/7dac8b3e43625aa28be214bd735fc3386770de04)) - update dependency com.google.cloud:google-cloud-spanner-bom to v6.4.4 ([#​464](https://www.github.com/googleapis/java-spanner-jdbc/issues/464)) ([eeb31c0](https://www.github.com/googleapis/java-spanner-jdbc/commit/eeb31c050fda116203d9da5c4a80c7f1c6a6cac4)) - release scripts from issuing overlapping phases ([#​434](https://www.github.com/googleapis/java-spanner-jdbc/issues/434)) ([b2eec0f](https://www.github.com/googleapis/java-spanner-jdbc/commit/b2eec0f079e64f5c21b89bbc0b02e3e981d6469a)) - typo ([#​431](https://www.github.com/googleapis/java-spanner-jdbc/issues/431)) ([a0b158b](https://www.github.com/googleapis/java-spanner-jdbc/commit/a0b158bf9931d610779dec51ca61107078e9398e)) - update dependency com.google.cloud:google-cloud-shared-dependencies to v0.21.1 ([#​438](https://www.github.com/googleapis/java-spanner-jdbc/issues/438)) ([aa56b5c](https://www.github.com/googleapis/java-spanner-jdbc/commit/aa56b5c1d5e3b1ccdaa0d5b877deccbda5aa0061)) - update dependency com.google.cloud:google-cloud-shared-dependencies to v1 ([#​441](https://www.github.com/googleapis/java-spanner-jdbc/issues/441)) ([df7f0e7](https://www.github.com/googleapis/java-spanner-jdbc/commit/df7f0e796c03f9607e57b4b6ba999c92ea14c58d)) - update dependency com.google.cloud:google-cloud-spanner-bom to v6.2.1 ([#​430](https://www.github.com/googleapis/java-spanner-jdbc/issues/430)) ([212d9d0](https://www.github.com/googleapis/java-spanner-jdbc/commit/212d9d05c4f28ade71ab5484792188b11a5bcd8b)) - update dependency com.google.cloud:google-cloud-spanner-bom to v6.3.3 ([#​439](https://www.github.com/googleapis/java-spanner-jdbc/issues/439)) ([a128c4c](https://www.github.com/googleapis/java-spanner-jdbc/commit/a128c4cbe0e6b66f9276b71f7733a46645186e88)) - update dependency com.google.cloud:google-cloud-shared-dependencies to v0.21.0 ([#​423](https://www.github.com/googleapis/java-spanner-jdbc/issues/423)) ([e0cf14a](https://www.github.com/googleapis/java-spanner-jdbc/commit/e0cf14a4dd087532924f49bb8e0431e1d681c7e8)) - update dependency com.google.cloud:google-cloud-spanner-bom to v6.2.0 ([#​420](https://www.github.com/googleapis/java-spanner-jdbc/issues/420)) ([fdd8809](https://www.github.com/googleapis/java-spanner-jdbc/commit/fdd880943394e4760c26eadc3a87d5a298591eb1))
--- 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻️ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). feat: add `gcf-owl-bot[bot]` to `ignoreAuthors` (#474) This PR was generated using Autosynth. :rainbow: Synth log will be available here: https://source.cloud.google.com/results/invocations/35db7954-f063-42f8-9ff3-5d189e94e5d3/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) Source-Link: https://github.com/googleapis/synthtool/commit/7332178a11ddddc91188dc0f25bca1ccadcaa6c6 deps: update dependency com.google.cloud:google-cloud-shared-dependencies to v1.2.0 (#473) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:google-cloud-shared-dependencies](https://togithub.com/googleapis/java-shared-dependencies) | `1.1.0` -> `1.2.0` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/1.2.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/1.2.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/1.2.0/compatibility-slim/1.1.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/1.2.0/confidence-slim/1.1.0)](https://docs.renovatebot.com/merge-confidence/) | ---
googleapis/java-shared-dependencies [Compare Source](https://togithub.com/googleapis/java-shared-dependencies/compare/v1.1.0...v1.2.0) - update dependency com.google.api-client:google-api-client-bom to v1.31.5 ([#​353](https://www.github.com/googleapis/java-shared-dependencies/issues/353)) ([8d72ab0](https://www.github.com/googleapis/java-shared-dependencies/commit/8d72ab003e08c864aedc17fc190ba26f393bf0c7)) - update dependency com.google.errorprone:error_prone_annotations to v2.7.1 ([#​360](https://www.github.com/googleapis/java-shared-dependencies/issues/360)) ([8f952d0](https://www.github.com/googleapis/java-shared-dependencies/commit/8f952d05745358fc426a1a2dcb688da5d5010239)) - update dependency com.google.protobuf:protobuf-bom to v3.17.0 ([#​355](https://www.github.com/googleapis/java-shared-dependencies/issues/355)) ([09858fb](https://www.github.com/googleapis/java-shared-dependencies/commit/09858fb4f1b78a77e828501597d20df4db0ebfcf)) - update dependency io.grpc:grpc-bom to v1.37.1 ([#​359](https://www.github.com/googleapis/java-shared-dependencies/issues/359)) ([bc9869e](https://www.github.com/googleapis/java-shared-dependencies/commit/bc9869e914314f951afd69f2acae95c414398f43)) - update google.common-protos.version to v2.2.1 ([#​358](https://www.github.com/googleapis/java-shared-dependencies/issues/358)) ([a3ed764](https://www.github.com/googleapis/java-shared-dependencies/commit/a3ed764a0e5143ee323d4b69c9747b8265d349e2)) - update iam.version to v1.0.14 ([#​352](https://www.github.com/googleapis/java-shared-dependencies/issues/352)) ([bea9a01](https://www.github.com/googleapis/java-shared-dependencies/commit/bea9a01788ac1332a4bc7e06574ef5701700fe90))
--- 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻️ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). chore: regenerate README (#472) This PR was generated using Autosynth. :rainbow:
Log from Synthtool ``` 2021-05-18 19:34:16,960 synthtool [DEBUG] > Executing /root/.cache/synthtool/java-spanner-jdbc/.github/readme/synth.py. On branch autosynth-readme nothing to commit, working tree clean 2021-05-18 19:34:18,292 synthtool [DEBUG] > Wrote metadata to .github/readme/synth.metadata/synth.metadata. ```
Full log will be available here: https://source.cloud.google.com/results/invocations/572b047a-da68-49ed-98fa-b98e7f88514a/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) build(deps): update dependency com.google.cloud:google-cloud-shared-config to v0.12.0 (#476) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:google-cloud-shared-config](https://togithub.com/googleapis/java-shared-config) | `0.11.2` -> `0.12.0` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-config/0.12.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-config/0.12.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-config/0.12.0/compatibility-slim/0.11.2)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-config/0.12.0/confidence-slim/0.11.2)](https://docs.renovatebot.com/merge-confidence/) | --- 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻️ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). chore: dump maven version along with java (#477) This PR was generated using Autosynth. :rainbow: Synth log will be available here: https://source.cloud.google.com/results/invocations/9ea9dfcf-fef7-472c-9ebc-755e62e086c4/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) Source-Link: https://github.com/googleapis/synthtool/commit/8eae0234a16b26c2ff616d305dbd9786c8b10a47 docs: document connection properties in README (#478) Adds documentation for the supported connection properties to the README file. Fixes #456 chore: regenerate README (#481) This PR was generated using Autosynth. :rainbow:
Log from Synthtool ``` 2021-05-24 05:37:24,863 synthtool [DEBUG] > Executing /root/.cache/synthtool/java-spanner-jdbc/.github/readme/synth.py. On branch autosynth-readme nothing to commit, working tree clean 2021-05-24 05:37:26,075 synthtool [DEBUG] > Wrote metadata to .github/readme/synth.metadata/synth.metadata. ```
Full log will be available here: https://source.cloud.google.com/results/invocations/5da15a47-718f-4374-b505-dead2c234c76/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) build(deps): update dependency org.apache.maven.plugins:maven-javadoc-plugin to v3.3.0 (#480) chore(deps): update dependency com.google.cloud:libraries-bom to v20.5.0 (#482) deps: update dependency com.google.cloud:google-cloud-spanner-bom to v6.5.0 (#483) test(deps): update dependency com.google.truth:truth to v1.1.3 (#484) test(deps): update dependency com.google.truth:truth to v1.1.3 (#485) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | com.google.truth:truth | `1.1.2` -> `1.1.3` | [![age](https://badges.renovateapi.com/packages/maven/com.google.truth:truth/1.1.3/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.truth:truth/1.1.3/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.truth:truth/1.1.3/compatibility-slim/1.1.2)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.truth:truth/1.1.3/confidence-slim/1.1.2)](https://docs.renovatebot.com/merge-confidence/) | --- 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻️ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). chore: release 2.2.0 (#475) :robot: I have created a release \*beep\* \*boop\* --- * add `gcf-owl-bot[bot]` to `ignoreAuthors` ([#474](https://www.github.com/googleapis/java-spanner-jdbc/issues/474)) ([c14f17b](https://www.github.com/googleapis/java-spanner-jdbc/commit/c14f17b411b15e778a68ce998de04732b159d7ac)) * document connection properties in README ([#478](https://www.github.com/googleapis/java-spanner-jdbc/issues/478)) ([3ccc543](https://www.github.com/googleapis/java-spanner-jdbc/commit/3ccc5433bec261b18d2536b04590e7645e47ed9b)), closes [#456](https://www.github.com/googleapis/java-spanner-jdbc/issues/456) * update dependency com.google.cloud:google-cloud-shared-dependencies to v1.2.0 ([#473](https://www.github.com/googleapis/java-spanner-jdbc/issues/473)) ([a6cc069](https://www.github.com/googleapis/java-spanner-jdbc/commit/a6cc0697ed5916c665f007a1bf16660b8b91f9f9)) * update dependency com.google.cloud:google-cloud-spanner-bom to v6.5.0 ([#483](https://www.github.com/googleapis/java-spanner-jdbc/issues/483)) ([e7fec30](https://www.github.com/googleapis/java-spanner-jdbc/commit/e7fec30f2f2c5518821d5348d448f102301d65c3)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). chore: release 2.2.1-SNAPSHOT (#487) :robot: I have created a release \*beep\* \*boop\* --- --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). chore(deps): update dependency com.google.cloud:google-cloud-spanner-jdbc to v2.2.0 (#488) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:google-cloud-spanner-jdbc](https://togithub.com/googleapis/java-spanner-jdbc) | `2.1.0` -> `2.2.0` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-jdbc/2.2.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-jdbc/2.2.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-jdbc/2.2.0/compatibility-slim/2.1.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-jdbc/2.2.0/confidence-slim/2.1.0)](https://docs.renovatebot.com/merge-confidence/) | ---
googleapis/java-spanner-jdbc [Compare Source](https://togithub.com/googleapis/java-spanner-jdbc/compare/v2.1.0...v2.2.0) - add `gcf-owl-bot[bot]` to `ignoreAuthors` ([#​474](https://www.github.com/googleapis/java-spanner-jdbc/issues/474)) ([c14f17b](https://www.github.com/googleapis/java-spanner-jdbc/commit/c14f17b411b15e778a68ce998de04732b159d7ac)) - document connection properties in README ([#​478](https://www.github.com/googleapis/java-spanner-jdbc/issues/478)) ([3ccc543](https://www.github.com/googleapis/java-spanner-jdbc/commit/3ccc5433bec261b18d2536b04590e7645e47ed9b)), closes [#​456](https://www.github.com/googleapis/java-spanner-jdbc/issues/456) - update dependency com.google.cloud:google-cloud-shared-dependencies to v1.2.0 ([#​473](https://www.github.com/googleapis/java-spanner-jdbc/issues/473)) ([a6cc069](https://www.github.com/googleapis/java-spanner-jdbc/commit/a6cc0697ed5916c665f007a1bf16660b8b91f9f9)) - update dependency com.google.cloud:google-cloud-spanner-bom to v6.5.0 ([#​483](https://www.github.com/googleapis/java-spanner-jdbc/issues/483)) ([e7fec30](https://www.github.com/googleapis/java-spanner-jdbc/commit/e7fec30f2f2c5518821d5348d448f102301d65c3))
--- 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻️ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). chore: regenerate README (#489) This PR was generated using Autosynth. :rainbow:
Log from Synthtool ``` 2021-06-02 20:28:22,584 synthtool [DEBUG] > Executing /root/.cache/synthtool/java-spanner-jdbc/.github/readme/synth.py. On branch autosynth-readme nothing to commit, working tree clean 2021-06-02 20:28:23,968 synthtool [DEBUG] > Wrote metadata to .github/readme/synth.metadata/synth.metadata. ```
Full log will be available here: https://source.cloud.google.com/results/invocations/f9c652de-b905-42d2-8dff-d97f0e0d5476/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) deps: update dependency com.google.cloud:google-cloud-shared-dependencies to v1.3.0 (#490) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:google-cloud-shared-dependencies](https://togithub.com/googleapis/java-shared-dependencies) | `1.2.0` -> `1.3.0` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/1.3.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/1.3.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/1.3.0/compatibility-slim/1.2.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/1.3.0/confidence-slim/1.2.0)](https://docs.renovatebot.com/merge-confidence/) | ---
googleapis/java-shared-dependencies [Compare Source](https://togithub.com/googleapis/java-shared-dependencies/compare/v1.2.0...v1.3.0) - add `gcf-owl-bot[bot]` to `ignoreAuthors` ([#​365](https://www.github.com/googleapis/java-shared-dependencies/issues/365)) ([7e8309b](https://www.github.com/googleapis/java-shared-dependencies/commit/7e8309bf67ade0fe2b09f792848136cd88b4d2e4)) - update dependency com.google.auth:google-auth-library-bom to v0.26.0 ([#​368](https://www.github.com/googleapis/java-shared-dependencies/issues/368)) ([38256a8](https://www.github.com/googleapis/java-shared-dependencies/commit/38256a82cb6896c3f5e5ea6ca5d8d671c412bf84)) - update dependency com.google.cloud:google-cloud-core-bom to v1.95.0 ([#​377](https://www.github.com/googleapis/java-shared-dependencies/issues/377)) ([297ea62](https://www.github.com/googleapis/java-shared-dependencies/commit/297ea621e02f8c0679c8b07ed399d11eaacecc14)) - update dependency com.google.code.gson:gson to v2.8.7 ([#​370](https://www.github.com/googleapis/java-shared-dependencies/issues/370)) ([cdc1b8e](https://www.github.com/googleapis/java-shared-dependencies/commit/cdc1b8ea1c93f97b712081ca8dc8ea57f342b69e)) - update dependency com.google.protobuf:protobuf-bom to v3.17.1 ([#​369](https://www.github.com/googleapis/java-shared-dependencies/issues/369)) ([5a19574](https://www.github.com/googleapis/java-shared-dependencies/commit/5a19574bc626bb3c6b573ed1d177e8907188dec1)) - update dependency com.google.protobuf:protobuf-bom to v3.17.2 ([#​374](https://www.github.com/googleapis/java-shared-dependencies/issues/374)) ([83516e6](https://www.github.com/googleapis/java-shared-dependencies/commit/83516e691b99e5e5d22d27e561781a5ade5fb514)) - update dependency io.grpc:grpc-bom to v1.38.0 ([#​364](https://www.github.com/googleapis/java-shared-dependencies/issues/364)) ([00db570](https://www.github.com/googleapis/java-shared-dependencies/commit/00db5701c3b0aa609f3778c06911a9a0248ca342)) - update gax.version to v1.65.0 ([#​376](https://www.github.com/googleapis/java-shared-dependencies/issues/376)) ([b793a0d](https://www.github.com/googleapis/java-shared-dependencies/commit/b793a0d7744ff1b0f8ae5d3d13ec4776ae8d3089)) - update google.common-protos.version to v2.3.1 ([#​366](https://www.github.com/googleapis/java-shared-dependencies/issues/366)) ([7d6a7fa](https://www.github.com/googleapis/java-shared-dependencies/commit/7d6a7fa7a2cad2b3f2ecf45e42d2ed5db0b60a43)) - update google.common-protos.version to v2.3.2 ([#​375](https://www.github.com/googleapis/java-shared-dependencies/issues/375)) ([68a47ad](https://www.github.com/googleapis/java-shared-dependencies/commit/68a47ad3243f3e980db74c9c8505a1b3063c131b))
--- 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). chore: release 2.2.1 (#491) :robot: I have created a release \*beep\* \*boop\* --- * update dependency com.google.cloud:google-cloud-shared-dependencies to v1.3.0 ([#490](https://www.github.com/googleapis/java-spanner-jdbc/issues/490)) ([bf0c9d6](https://www.github.com/googleapis/java-spanner-jdbc/commit/bf0c9d6bf612b50a59ea2d530430ccace79aaf35)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). chore: release 2.2.2-SNAPSHOT (#492) :robot: I have created a release \*beep\* \*boop\* --- --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). chore(deps): update dependency com.google.cloud:google-cloud-spanner-jdbc to v2.2.1 (#493) chore(deps): update dependency com.google.cloud.samples:shared-configuration to v1.0.23 (#494) chore: regenerate README (#495) This PR was generated using Autosynth. :rainbow:
Log from Synthtool ``` 2021-06-05 09:53:24,030 synthtool [DEBUG] > Executing /root/.cache/synthtool/java-spanner-jdbc/.github/readme/synth.py. On branch autosynth-readme nothing to commit, working tree clean 2021-06-05 09:53:25,229 synthtool [DEBUG] > Wrote metadata to .github/readme/synth.metadata/synth.metadata. ```
Full log will be available here: https://source.cloud.google.com/results/invocations/2c57a5bd-142d-430b-9931-a1a1a7e59a30/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) chore(deps): update dependency com.google.cloud:libraries-bom to v20.6.0 (#496) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:libraries-bom](https://togithub.com/GoogleCloudPlatform/cloud-opensource-java) | `20.5.0` -> `20.6.0` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.6.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.6.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.6.0/compatibility-slim/20.5.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.6.0/confidence-slim/20.5.0)](https://docs.renovatebot.com/merge-confidence/) | --- 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). deps: update dependency com.google.cloud:google-cloud-spanner-bom to v6.6.0 (#498) * deps: update dependency com.google.cloud:google-cloud-spanner-bom to v6.6.0 Updates to Spanner client 6.6.0 and adds tests for optimizer stats package. Replaces #497 * test: implement missing method for integration test chore: release 2.2.2 (#499) :robot: I have created a release \*beep\* \*boop\* --- * update dependency com.google.cloud:google-cloud-spanner-bom to v6.6.0 ([#498](https://www.github.com/googleapis/java-spanner-jdbc/issues/498)) ([5849a97](https://www.github.com/googleapis/java-spanner-jdbc/commit/5849a970087d3fa1d1b42092b4568602563a1dbd)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). chore: release 2.2.3-SNAPSHOT (#500) :robot: I have created a release \*beep\* \*boop\* --- --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). deps: update dependency com.google.cloud:google-cloud-spanner-bom to v6.6.1 (#502) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:google-cloud-spanner-bom](https://togithub.com/googleapis/java-spanner) | `6.6.0` -> `6.6.1` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-bom/6.6.1/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-bom/6.6.1/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-bom/6.6.1/compatibility-slim/6.6.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-bom/6.6.1/confidence-slim/6.6.0)](https://docs.renovatebot.com/merge-confidence/) | ---
googleapis/java-spanner [Compare Source](https://togithub.com/googleapis/java-spanner/compare/v6.6.0...v6.6.1)
--- 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). chore: release 2.2.3 (#504) :robot: I have created a release \*beep\* \*boop\* --- * update dependency com.google.cloud:google-cloud-spanner-bom to v6.6.1 ([#502](https://www.github.com/googleapis/java-spanner-jdbc/issues/502)) ([41a9cd4](https://www.github.com/googleapis/java-spanner-jdbc/commit/41a9cd49fed468f410ad226555f7b9ba46d857b3)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). chore: regenerate README (#505) This PR was generated using Autosynth. :rainbow:
Log from Synthtool ``` 2021-06-15 21:17:11,110 synthtool [DEBUG] > Executing /root/.cache/synthtool/java-spanner-jdbc/.github/readme/synth.py. On branch autosynth-readme nothing to commit, working tree clean 2021-06-15 21:17:12,273 synthtool [DEBUG] > Wrote metadata to .github/readme/synth.metadata/synth.metadata. ```
Full log will be available here: https://source.cloud.google.com/results/invocations/0bc6fb82-3b4e-44b2-978c-65fa57b88268/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) chore: release 2.2.4-SNAPSHOT (#507) :robot: I have created a release \*beep\* \*boop\* --- --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). fix: Update dependencies.sh to not break on mac (#506) This PR was generated using Autosynth. :rainbow: Synth log will be available here: https://source.cloud.google.com/results/invocations/f853e0b6-9a6b-4346-9a07-ff7c7ec6f858/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) Source-Link: https://github.com/googleapis/synthtool/commit/8f76a885deaaf2fe234daeba4a8cc4d1b3de8086 chore(deps): update dependency com.google.cloud:google-cloud-spanner-jdbc to v2.2.2 (#501) chore: regenerate README (#510) This PR was generated using Autosynth. :rainbow:
Log from Synthtool ``` 2021-06-15 23:11:37,759 synthtool [DEBUG] > Executing /root/.cache/synthtool/java-spanner-jdbc/.github/readme/synth.py. On branch autosynth-readme nothing to commit, working tree clean 2021-06-15 23:11:38,999 synthtool [DEBUG] > Wrote metadata to .github/readme/synth.metadata/synth.metadata. ```
Full log will be available here: https://source.cloud.google.com/results/invocations/61cfb5e0-68cd-47b3-89b4-af4a25c2c4b6/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) fix: prevent relocating urls that start with com like /computeMetadata/ (#511) Fixes #503 In addition to original problem I have added an exception for all the Netty libraries since I have got errors on service provider which claims that netty libraries are not a subtype. chore(deps): update dependency com.google.cloud:google-cloud-spanner-jdbc to v2.2.3 (#509) chore: minimize noise from build scripts (#512) This PR was generated using Autosynth. :rainbow: Synth log will be available here: https://source.cloud.google.com/results/invocations/88f2626c-4d2d-42a7-9d16-aaa685eaa74a/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) Source-Link: https://github.com/googleapis/synthtool/commit/1c0c698705e668ccb3d68556ae7260f16ce63a6e fix: Add `shopt -s nullglob` to dependencies script (#514) This PR was generated using Autosynth. :rainbow: Synth log will be available here: https://source.cloud.google.com/results/invocations/bc91c2d7-c025-42b9-ab03-f02a01c15622/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) Source-Link: https://github.com/googleapis/synthtool/commit/87254ac89a9559864c0a245d6b150406439ce3d8 chore(deps): update dependency com.google.cloud:libraries-bom to v20.7.0 (#515) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:libraries-bom](https://togithub.com/GoogleCloudPlatform/cloud-opensource-java) | `20.6.0` -> `20.7.0` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.7.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.7.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.7.0/compatibility-slim/20.6.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.7.0/confidence-slim/20.6.0)](https://docs.renovatebot.com/merge-confidence/) | --- 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). deps: update dependency com.google.cloud:google-cloud-spanner-bom to v6.7.0 (#513) deps: update dependency com.google.cloud:google-cloud-shared-dependencies to v1.4.0 (#518) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:google-cloud-shared-dependencies](https://togithub.com/googleapis/java-shared-dependencies) | `1.3.0` -> `1.4.0` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/1.4.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/1.4.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/1.4.0/compatibility-slim/1.3.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/1.4.0/confidence-slim/1.3.0)](https://docs.renovatebot.com/merge-confidence/) | ---
googleapis/java-shared-dependencies [Compare Source](https://togithub.com/googleapis/java-shared-dependencies/compare/v1.3.0...v1.4.0) - add grpc-gcp to dependencyManagement ([#​389](https://www.github.com/googleapis/java-shared-dependencies/issues/389)) ([57fd2e6](https://www.github.com/googleapis/java-shared-dependencies/commit/57fd2e646e28e37e0b5e4e1b37425d4897a8776f)) - Add `shopt -s nullglob` to dependencies script ([#​392](https://www.github.com/googleapis/java-shared-dependencies/issues/392)) ([f8f29df](https://www.github.com/googleapis/java-shared-dependencies/commit/f8f29df1c9cc6eca517c99113fb9509fd611ac92)) - Add common httpclient and oauth dependencies ([#​391](https://www.github.com/googleapis/java-shared-dependencies/issues/391)) ([09660e1](https://www.github.com/googleapis/java-shared-dependencies/commit/09660e1e50c96dcd7df4e80d8ad357f8256eda6c)) - Update dependencies.sh to not break on mac ([#​384](https://www.github.com/googleapis/java-shared-dependencies/issues/384)) ([0ae2841](https://www.github.com/googleapis/java-shared-dependencies/commit/0ae2841d7ce2885d041795c58a38d2d3973c2e5a)) - update dependency com.google.api-client:google-api-client-bom to v1.32.1 ([#​390](https://www.github.com/googleapis/java-shared-dependencies/issues/390)) ([00288c1](https://www.github.com/googleapis/java-shared-dependencies/commit/00288c18d09616582c8bec961ecc5c00ef1d4288)) - update dependency com.google.api:api-common to v1.10.4 ([#​385](https://www.github.com/googleapis/java-shared-dependencies/issues/385)) ([5f2b39b](https://www.github.com/googleapis/java-shared-dependencies/commit/5f2b39b5bdc4cec9d5ab2f050e11000ed372d057)) - update dependency com.google.api:gax-grpc to v1.65.1 ([#​382](https://www.github.com/googleapis/java-shared-dependencies/issues/382)) ([a2a1547](https://www.github.com/googleapis/java-shared-dependencies/commit/a2a15471dee21207a0b97b3bc8f6f59d6a4a2d13)) - update dependency com.google.protobuf:protobuf-bom to v3.17.3 ([#​379](https://www.github.com/googleapis/java-shared-dependencies/issues/379)) ([6f43eb5](https://www.github.com/googleapis/java-shared-dependencies/commit/6f43eb553dca98140d343bee3f1003096d79ee6c)) - update dependency io.grpc:grpc-bom to v1.38.1 ([#​386](https://www.github.com/googleapis/java-shared-dependencies/issues/386)) ([7b1d4cf](https://www.github.com/googleapis/java-shared-dependencies/commit/7b1d4cf317fbd75b91d6a63f82b5fc2f46eaf3ca)) - update dependency io.grpc:grpc-bom to v1.39.0 ([#​394](https://www.github.com/googleapis/java-shared-dependencies/issues/394)) ([ebc8af6](https://www.github.com/googleapis/java-shared-dependencies/commit/ebc8af6b3f850b58b35d9720a7a0b1545d4616bd)) - update gax.version to v1.66.0 ([#​395](https://www.github.com/googleapis/java-shared-dependencies/issues/395)) ([c73f73e](https://www.github.com/googleapis/java-shared-dependencies/commit/c73f73e84740a8117be342a66e179eaf3e29c6fd)) - update google.core.version to v1.95.1 ([#​381](https://www.github.com/googleapis/java-shared-dependencies/issues/381)) ([4496153](https://www.github.com/googleapis/java-shared-dependencies/commit/44961532f621b0ab19e9e7feebb7d588aef5d423)) - update google.core.version to v1.95.2 ([#​383](https://www.github.com/googleapis/java-shared-dependencies/issues/383)) ([7216859](https://www.github.com/googleapis/java-shared-dependencies/commit/7216859bcd67fa1ce1119831c33c50a2d5b79324)) - update google.core.version to v1.95.3 ([#​388](https://www.github.com/googleapis/java-shared-dependencies/issues/388)) ([354e4e8](https://www.github.com/googleapis/java-shared-dependencies/commit/354e4e811f4ba886406681a4261ac0455a9eb2d2)) - update google.core.version to v1.95.4 ([#​393](https://www.github.com/googleapis/java-shared-dependencies/issues/393)) ([be78ad8](https://www.github.com/googleapis/java-shared-dependencies/commit/be78ad85e31d8876eabafee7aa8242712573cb46))
--- 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). deps: update dependency com.google.cloud:google-cloud-spanner-bom to v6.8.0 (#517) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:google-cloud-spanner-bom](https://togithub.com/googleapis/java-spanner) | `6.7.0` -> `6.8.0` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-bom/6.8.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-bom/6.8.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-bom/6.8.0/compatibility-slim/6.7.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-bom/6.8.0/confidence-slim/6.7.0)](https://docs.renovatebot.com/merge-confidence/) | ---
googleapis/java-spanner [Compare Source](https://togithub.com/googleapis/java-spanner/compare/v6.7.0...v6.8.0) - add gRPC-GCP channel pool as an option ([#​1227](https://www.github.com/googleapis/java-spanner/issues/1227)) ([1fa95a9](https://www.github.com/googleapis/java-spanner/commit/1fa95a9993ea8c7a5f943ab39eced4ced4cb87e7)) - spanner JSON type ([#​1260](https://www.github.com/googleapis/java-spanner/issues/1260)) ([b2a56c6](https://www.github.com/googleapis/java-spanner/commit/b2a56c68695b6209e20f9f86d83d7c5a0f39c7a8)) - Add `shopt -s nullglob` to dependencies script ([#​1256](https://www.github.com/googleapis/java-spanner/issues/1256)) ([d1712f7](https://www.github.com/googleapis/java-spanner/commit/d1712f7c51752c2359045e5eabac8fc0530a2421))
--- 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). chore: release 2.2.4 (#508) :robot: I have created a release \*beep\* \*boop\* --- * Add `shopt -s nullglob` to dependencies script ([#514](https://www.github.com/googleapis/java-spanner-jdbc/issues/514)) ([ae51b24](https://www.github.com/googleapis/java-spanner-jdbc/commit/ae51b241148606ffddeb0a703b853de67710e48b)) * prevent relocating urls that start with com like /computeMetadata/ ([#511](https://www.github.com/googleapis/java-spanner-jdbc/issues/511)) ([1178a1d](https://www.github.com/googleapis/java-spanner-jdbc/commit/1178a1d35b4b0032acf71b3dbf862d4f9fb9399c)) * Update dependencies.sh to not break on mac ([#506](https://www.github.com/googleapis/java-spanner-jdbc/issues/506)) ([e205c0c](https://www.github.com/googleapis/java-spanner-jdbc/commit/e205c0c8eba6ac23d747c433b42d8e2365528bd8)) * update dependency com.google.cloud:google-cloud-shared-dependencies to v1.4.0 ([#518](https://www.github.com/googleapis/java-spanner-jdbc/issues/518)) ([045b858](https://www.github.com/googleapis/java-spanner-jdbc/commit/045b8586a7ca7b0e2bd341b27ca3e8a3530c992a)) * update dependency com.google.cloud:google-cloud-spanner-bom to v6.7.0 ([#513](https://www.github.com/googleapis/java-spanner-jdbc/issues/513)) ([e1affe3](https://www.github.com/googleapis/java-spanner-jdbc/commit/e1affe358a812a45b9d2c0c9ccd0b00e3aa3791e)) * update dependency com.google.cloud:google-cloud-spanner-bom to v6.8.0 ([#517](https://www.github.com/googleapis/java-spanner-jdbc/issues/517)) ([c9013ff](https://www.github.com/googleapis/java-spanner-jdbc/commit/c9013ff48269b158121e4c65c545be30752c31fb)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). chore: release 2.2.5-SNAPSHOT (#519) :robot: I have created a release \*beep\* \*boop\* --- --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). deps: update dependency com.google.cloud:google-cloud-spanner-bom to v6.9.0 (#521) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:google-cloud-spanner-bom](https://togithub.com/googleapis/java-spanner) | `6.8.0` -> `6.9.0` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-bom/6.9.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-bom/6.9.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-bom/6.9.0/compatibility-slim/6.8.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-bom/6.9.0/confidence-slim/6.8.0)](https://docs.renovatebot.com/merge-confidence/) | ---
googleapis/java-spanner [Compare Source](https://togithub.com/googleapis/java-spanner/compare/v6.8.0...v6.9.0) - add support for tagging to Connection API ([#​623](https://www.github.com/googleapis/java-spanner/issues/623)) ([5722372](https://www.github.com/googleapis/java-spanner/commit/5722372b7869828e372dec06e80e5b0e7280af61)) - **spanner:** add leader_options to InstanceConfig and default_leader to Database ([#​1271](https://www.github.com/googleapis/java-spanner/issues/1271)) ([f257671](https://www.github.com/googleapis/java-spanner/commit/f25767144344f0df67662f1b3ef662902384599a)) - support setting an async executor provider ([#​1263](https://www.github.com/googleapis/java-spanner/issues/1263)) ([369c8a7](https://www.github.com/googleapis/java-spanner/commit/369c8a771ec48fa1476236f800b0e8eb5982a33c)) - update dependency com.google.cloud:google-cloud-shared-dependencies to v1.4.0 ([#​1269](https://www.github.com/googleapis/java-spanner/issues/1269)) ([025e162](https://www.github.com/googleapis/java-spanner/commit/025e162813d6321dabe49e32f00934f9ae334e24))
--- 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). chore: release 2.2.5 (#522) :robot: I have created a release \*beep\* \*boop\* --- * update dependency com.google.cloud:google-cloud-spanner-bom to v6.9.0 ([#521](https://www.github.com/googleapis/java-spanner-jdbc/issues/521)) ([8d840ac](https://www.github.com/googleapis/java-spanner-jdbc/commit/8d840ac855f4466c1d53a3b38d964e213708e5e5)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). chore: regenerate README (#523) This PR was generated using Autosynth. :rainbow:
Log from Synthtool ``` 2021-07-06 00:20:39,365 synthtool [DEBUG] > Executing /root/.cache/synthtool/java-spanner-jdbc/.github/readme/synth.py. On branch autosynth-readme nothing to commit, working tree clean 2021-07-06 00:20:40,571 synthtool [DEBUG] > Wrote metadata to .github/readme/synth.metadata/synth.metadata. ```
Full log will be available here: https://source.cloud.google.com/results/invocations/c1ec5162-f264-4d89-804f-4f695017e997/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) chore: release 2.2.6-SNAPSHOT (#524) :robot: I have created a release \*beep\* \*boop\* --- --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). chore(deps): update dependency com.google.cloud:google-cloud-spanner-jdbc to v2.2.4 (#520) deps: update dependency com.google.cloud:google-cloud-spanner-bom to v6.9.1 (#525) chore: regenerate README (#528) This PR was generated using Autosynth. :rainbow:
Log from Synthtool ``` 2021-07-06 01:48:33,450 synthtool [DEBUG] > Executing /root/.cache/synthtool/java-spanner-jdbc/.github/readme/synth.py. On branch autosynth-readme nothing to commit, working tree clean 2021-07-06 01:48:34,668 synthtool [DEBUG] > Wrote metadata to .github/readme/synth.metadata/synth.metadata. ```
Full log will be available here: https://source.cloud.google.com/results/invocations/ca49248a-3908-48df-b9b2-6223c4d77cca/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) chore: release 2.2.6 (#527) :robot: I have created a release \*beep\* \*boop\* --- * update dependency com.google.cloud:google-cloud-spanner-bom to v6.9.1 ([#525](https://www.github.com/googleapis/java-spanner-jdbc/issues/525)) ([37023b8](https://www.github.com/googleapis/java-spanner-jdbc/commit/37023b8295c97304aa0a55a28f71905fcbf5b93f)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). chore: release 2.2.7-SNAPSHOT (#529) :robot: I have created a release \*beep\* \*boop\* --- --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). chore: remove distributionManagement section (#530) All java client libraries inherit the distributionManagement section form shared-config. To prevent individual pom files from overriding the shared-config version of distributionManagement, it is being removed. chore: regenerate README (#531) This PR was generated using Autosynth. :rainbow:
Log from Synthtool ``` 2021-07-07 14:59:54,920 synthtool [DEBUG] > Executing /root/.cache/synthtool/java-spanner-jdbc/.github/readme/synth.py. On branch autosynth-readme nothing to commit, working tree clean 2021-07-07 14:59:56,130 synthtool [DEBUG] > Wrote metadata to .github/readme/synth.metadata/synth.metadata. ```
Full log will be available here: https://source.cloud.google.com/results/invocations/ba544d15-79a9-4161-b4d1-03f316693e40/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) chore(deps): update dependency com.google.cloud:google-cloud-spanner-jdbc to v2.2.6 (#526) chore(deps): update dependency com.google.cloud:libraries-bom to v20.8.0 (#532) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:libraries-bom](https://togithub.com/GoogleCloudPlatform/cloud-opensource-java) | `20.7.0` -> `20.8.0` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.8.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.8.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.8.0/compatibility-slim/20.7.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.8.0/confidence-slim/20.7.0)](https://docs.renovatebot.com/merge-confidence/) | --- 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). chore: remove All rights reserved clause from java.header (#533) This PR was generated using Autosynth. :rainbow: Synth log will be available here: https://source.cloud.google.com/results/invocations/76b59ea3-9589-4be2-a86f-50cc3a39422e/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) Source-Link: https://github.com/googleapis/synthtool/commit/09c59c20a4bf0daed1665af59035ff240fe356df feat: add support for tagging to JDBC connection (#270) * feat: add support for tagging to JDBC connection * fix: add ignored differences + default implementations chore: regenerate README (#535) This PR was generated using Autosynth. :rainbow:
Log from Synthtool ``` 2021-07-14 08:46:45,315 synthtool [DEBUG] > Executing /root/.cache/synthtool/java-spanner-jdbc/.github/readme/synth.py. On branch autosynth-readme nothing to commit, working tree clean 2021-07-14 08:46:46,598 synthtool [DEBUG] > Wrote metadata to .github/readme/synth.metadata/synth.metadata. ```
Full log will be available here: https://source.cloud.google.com/results/invocations/ae6a79f2-326e-4d4f-ad8d-bf6a5da0ba25/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) chore: add dependencyDashboardLabels to renovate.json (#536) This PR was generated using Autosynth. :rainbow: Synth log will be available here: https://source.cloud.google.com/results/invocations/d9079f8e-3fa1-44e6-b6d8-65a7341e9be2/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) Source-Link: https://github.com/googleapis/synthtool/commit/5d3c52f5db664eee9026db76b5bcb466f3a09ca9 deps: update dependency com.google.cloud:google-cloud-spanner-bom to v6.10.0 (#537) build(deps): update dependency com.google.cloud:google-cloud-shared-config to v0.13.1 (#541) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:google-cloud-shared-config](https://togithub.com/googleapis/java-shared-config) | `0.12.0` -> `0.13.1` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-config/0.13.1/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-config/0.13.1/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-config/0.13.1/compatibility-slim/0.12.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-config/0.13.1/confidence-slim/0.12.0)](https://docs.renovatebot.com/merge-confidence/) | ---
googleapis/java-shared-config [Compare Source](https://togithub.com/googleapis/java-shared-config/compare/v0.13.0...v0.13.1) - add `gcf-owl-bot[bot]` to `ignoreAuthors` ([#​264](https://www.github.com/googleapis/java-shared-config/issues/264)) ([d274af8](https://www.github.com/googleapis/java-shared-config/commit/d274af836ac9b3e98be84e551b7e9e552397ecc1)) - Add shopt -s nullglob to dependencies script ([865ca3c](https://www.github.com/googleapis/java-shared-config/commit/865ca3cbf106a7aaae1a989320a1ad5a47b6ffaf)) - Update dependencies.sh to not break on mac ([#​276](https://www.github.com/googleapis/java-shared-config/issues/276)) ([865ca3c](https://www.github.com/googleapis/java-shared-config/commit/865ca3cbf106a7aaae1a989320a1ad5a47b6ffaf)) - update auto-value-annotation.version to v1.8.2 ([#​275](https://www.github.com/googleapis/java-shared-config/issues/275)) ([4d15246](https://www.github.com/googleapis/java-shared-config/commit/4d152461a5592940a8be762c7a8698a02dbe26cf)) - update dependency com.puppycrawl.tools:checkstyle to v8.43 ([#​266](https://www.github.com/googleapis/java-shared-config/issues/266)) ([fae7961](https://www.github.com/googleapis/java-shared-config/commit/fae7961412b33e34e8fcfec78d1451894d4e61d9)) - update dependency com.puppycrawl.tools:checkstyle to v8.44 ([#​274](https://www.github.com/googleapis/java-shared-config/issues/274)) ([d53d0e0](https://www.github.com/googleapis/java-shared-config/commit/d53d0e0935e908d16f4e7cf763577cf3fd8128d3)) ***
--- 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). chore: regenerate README (#542) This PR was generated using Autosynth. :rainbow:
Log from Synthtool ``` 2021-07-27 20:52:25,206 synthtool [DEBUG] > Executing /root/.cache/synthtool/java-spanner-jdbc/.github/readme/synth.py. On branch autosynth-readme nothing to commit, working tree clean 2021-07-27 20:52:26,466 synthtool [DEBUG] > Wrote metadata to .github/readme/synth.metadata/synth.metadata. ```
Full log will be available here: https://source.cloud.google.com/results/invocations/7ded6de6-d25f-40c9-81f2-ea9cb5641798/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) chore(deps): update dependency com.google.cloud:libraries-bom to v20.9.0 (#539) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:libraries-bom](https://togithub.com/GoogleCloudPlatform/cloud-opensource-java) | `20.8.0` -> `20.9.0` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.9.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.9.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.9.0/compatibility-slim/20.8.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/20.9.0/confidence-slim/20.8.0)](https://docs.renovatebot.com/merge-confidence/) | --- 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). build(deps): update dependency com.google.cloud:google-cloud-shared-config to v1 (#543) deps: update dependency com.google.cloud:google-cloud-shared-dependencies to v2 (#544) * deps: update dependency com.google.cloud:google-cloud-shared-dependencies to v2 * Update pom.xml Co-authored-by: Neenu Shaji chore: release 2.3.0 (#534) :robot: I have created a release \*beep\* \*boop\* --- * add support for tagging to JDBC connection ([#270](https://www.github.com/googleapis/java-spanner-jdbc/issues/270)) ([a4bd82c](https://www.github.com/googleapis/java-spanner-jdbc/commit/a4bd82c8e4ce8b7179b943ac06b049598276f1b4)) * update dependency com.google.cloud:google-cloud-shared-dependencies to v2 ([#544](https://www.github.com/googleapis/java-spanner-jdbc/issues/544)) ([366430d](https://www.github.com/googleapis/java-spanner-jdbc/commit/366430dc270edd09de1a0749ba360f312897b1aa)) * update dependency com.google.cloud:google-cloud-spanner-bom to v6.10.0 ([#537](https://www.github.com/googleapis/java-spanner-jdbc/issues/537)) ([8655ae5](https://www.github.com/googleapis/java-spanner-jdbc/commit/8655ae5955f5385a9d6445e13264427d73c4d37e)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). chore: release 2.3.1-SNAPSHOT (#545) :robot: I have created a release \*beep\* \*boop\* --- --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). deps: update dependency com.google.cloud:google-cloud-spanner-bom to v6.10.1 (#538) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:google-cloud-spanner-bom](https://togithub.com/googleapis/java-spanner) | `6.10.0` -> `6.10.1` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-bom/6.10.1/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-bom/6.10.1/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-bom/6.10.1/compatibility-slim/6.10.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-bom/6.10.1/confidence-slim/6.10.0)](https://docs.renovatebot.com/merge-confidence/) | ---
googleapis/java-spanner [Compare Source](https://togithub.com/googleapis/java-spanner/compare/v6.10.0...v6.10.1)
--- 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). chore: release 2.3.1 (#546) :robot: I have created a release \*beep\* \*boop\* --- * update dependency com.google.cloud:google-cloud-spanner-bom to v6.10.1 ([#538](https://www.github.com/googleapis/java-spanner-jdbc/issues/538)) ([75507c4](https://www.github.com/googleapis/java-spanner-jdbc/commit/75507c4a42c3b051e8a14c1233b3b2526c0d3ccc)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). chore: release 2.3.2-SNAPSHOT (#547) :robot: I have created a release \*beep\* \*boop\* --- --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). deps: update dependency com.google.cloud:google-cloud-spanner-bom to v6.11.0 (#549) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:google-cloud-spanner-bom](https://togithub.com/googleapis/java-spanner) | `6.10.1` -> `6.11.0` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-bom/6.11.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-bom/6.11.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-bom/6.11.0/compatibility-slim/6.10.1)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-spanner-bom/6.11.0/confidence-slim/6.10.1)](https://docs.renovatebot.com/merge-confidence/) | ---
googleapis/java-spanner [Compare Source](https://togithub.com/googleapis/java-spanner/compare/v6.10.1...v6.11.0) - release gapic-generator-java v2.0.0 ([#​1334](https://www.github.com/googleapis/java-spanner/issues/1334)) ([368fb80](https://www.github.com/googleapis/java-spanner/commit/368fb80e8ae9fd9bee7af81c13bef32b26361877)) - use 'latest' stats package in samples to prevent build failures ([#​1313](https://www.github.com/googleapis/java-spanner/issues/1313)) ([6a8351c](https://www.github.com/googleapis/java-spanner/commit/6a8351c9d2cf0fe805b87a611ff1d94d4dba3f87)), closes [#​1273](https://www.github.com/googleapis/java-spanner/issues/1273) - update dependency com.google.cloud:google-cloud-monitoring to v3 ([#​1341](https://www.github.com/googleapis/java-spanner/issues/1341)) ([de7b540](https://www.github.com/googleapis/java-spanner/commit/de7b54094b6bb2928616e2e04215f4ba5b8bc750)) - update dependency com.google.cloud:google-cloud-shared-dependencies to v2 ([#​1331](https://www.github.com/googleapis/java-spanner/issues/1331)) ([cd1ad7b](https://www.github.com/googleapis/java-spanner/commit/cd1ad7b4cd1716b60f3f96ee953f76c126742788)) - update dependency com.google.cloud:google-cloud-shared-dependencies to v2.0.1 ([#​1344](https://www.github.com/googleapis/java-spanner/issues/1344)) ([300837f](https://www.github.com/googleapis/java-spanner/commit/300837f0a27dab89285895f753aececb8d641da9)) - update dependency com.google.cloud:google-cloud-trace to v2 ([#​1342](https://www.github.com/googleapis/java-spanner/issues/1342)) ([d24886b](https://www.github.com/googleapis/java-spanner/commit/d24886b058fd87ea744a4f375fb6affd8f9398d9)) - update dependency com.google.cloud:grpc-gcp to v1.1.0 ([#​1306](https://www.github.com/googleapis/java-spanner/issues/1306)) ([fa0c65d](https://www.github.com/googleapis/java-spanner/commit/fa0c65dc31236e05e6b10508281cf58e82ee87ef))
--- 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). chore: release 2.3.2 (#550) :robot: I have created a release \*beep\* \*boop\* --- * update dependency com.google.cloud:google-cloud-spanner-bom to v6.11.0 ([#549](https://www.github.com/googleapis/java-spanner-jdbc/issues/549)) ([2639e40](https://www.github.com/googleapis/java-spanner-jdbc/commit/2639e40ebbde19966653f06f8b664106568f6bac)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). chore: regenerate README (#551) This PR was generated using Autosynth. :rainbow:
Log from Synthtool ``` 2021-08-12 20:14:23,342 synthtool [DEBUG] > Executing /root/.cache/synthtool/java-spanner-jdbc/.github/readme/synth.py. On branch autosynth-readme nothing to commit, working tree clean 2021-08-12 20:14:24,558 synthtool [DEBUG] > Wrote metadata to .github/readme/synth.metadata/synth.metadata. ```
Full log will be available here: https://source.cloud.google.com/results/invocations/16f91a02-9987-4387-964e-2ee273dbe88d/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) chore: release 2.3.3-SNAPSHOT (#552) :robot: I have created a release \*beep\* \*boop\* --- --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). build(java): use ENABLE_FLAKYBOT env variable (#553) Kokoro job config now supports both environment variables during this migration period. Source-Author: Jeff Ching Source-Date: Thu Aug 12 10:10:27 2021 -0700 Source-Repo: googleapis/synthtool Source-Sha: ff01716e16d2c6e87eaf87197b753ac9fcbbed5d Source-Link: https://github.com/googleapis/synthtool/commit/ff01716e16d2c6e87eaf87197b753ac9fcbbed5d chore(deps): update dependency com.google.cloud:google-cloud-spanner-jdbc to v2.3.2 (#548) chore: regenerate README (#554) This PR was generated using Autosynth. :rainbow:
Log from Synthtool ``` 2021-08-16 01:01:15,979 synthtool [DEBUG] > Executing /root/.cache/synthtool/java-spanner-jdbc/.github/readme/synth.py. On branch autosynth-readme nothing to commit, working tree clean 2021-08-16 01:01:17,256 synthtool [DEBUG] > Wrote metadata to .github/readme/synth.metadata/synth.metadata. ```
Full log will be available here: https://source.cloud.google.com/results/invocations/89da9f1b-f590-497f-968b-a6f0fc752b78/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) chore(deps): update dependency com.google.cloud:libraries-bom to v21 (#555) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:libraries-bom](https://togithub.com/GoogleCloudPlatform/cloud-opensource-java) | `20.9.0` -> `21.0.0` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/21.0.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/21.0.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/21.0.0/compatibility-slim/20.9.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:libraries-bom/21.0.0/confidence-slim/20.9.0)](https://docs.renovatebot.com/merge-confidence/) | --- 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). deps: update dependency com.google.cloud:google-cloud-spanner-bom to v6.11.1 (#556) chore: release 2.3.3 (#559) :robot: I have created a release \*beep\* \*boop\* --- * update dependency com.google.cloud:google-cloud-spanner-bom to v6.11.1 ([#556](https://www.github.com/googleapis/java-spanner-jdbc/issues/556)) ([36f0d32](https://www.github.com/googleapis/java-spanner-jdbc/commit/36f0d32aec65f098f7091d44a0e4acc98104aeb9)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). chore: release 2.3.4-SNAPSHOT (#560) :robot: I have created a release \*beep\* \*boop\* --- --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). chore(deps): update dependency com.google.cloud:google-cloud-spanner-jdbc to v2.3.3 (#561) chore: regenerate README (#562) This PR was generated using Autosynth. :rainbow:
Log from Synthtool ``` 2021-08-19 16:14:05,660 synthtool [DEBUG] > Executing /root/.cache/synthtool/java-spanner-jdbc/.github/readme/synth.py. On branch autosynth-readme nothing to commit, working tree clean 2021-08-19 16:14:06,662 synthtool [DEBUG] > Wrote metadata to .github/readme/synth.metadata/synth.metadata. ```
Full log will be available here: https://source.cloud.google.com/results/invocations/42ee00f6-6a53-49f5-89dd-60be3f7682e4/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) build(deps): update dependency com.google.cloud:google-cloud-shared-config to v1.0.1 (#557) deps: update dependency com.google.cloud:google-cloud-shared-dependencies to v2.1.0 (#563) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:google-cloud-shared-dependencies](https://togithub.com/googleapis/java-shared-dependencies) | `2.0.1` -> `2.1.0` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/2.1.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/2.1.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/2.1.0/compatibility-slim/2.0.1)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/2.1.0/confidence-slim/2.0.1)](https://docs.renovatebot.com/merge-confidence/) | ---
googleapis/java-shared-dependencies [Compare Source](https://togithub.com/googleapis/java-shared-dependencies/compare/v2.0.1...v2.1.0) - update dependency com.google.auth:google-auth-library-bom to v1.1.0 ([#​439](https://www.togithub.com/googleapis/java-shared-dependencies/issues/439)) ([ca52bd9](https://www.github.com/googleapis/java-shared-dependencies/commit/ca52bd9c099c96bf7b5a57aa85d39b58a610c875)) - update dependency com.google.cloud:google-cloud-core-bom to v2.1.0 ([#​444](https://www.togithub.com/googleapis/java-shared-dependencies/issues/444)) ([ff914c6](https://www.github.com/googleapis/java-shared-dependencies/commit/ff914c6de9e3e7fa6ba75591d3d5077c5421827d)) - update dependency com.google.code.gson:gson to v2.8.8 ([#​442](https://www.togithub.com/googleapis/java-shared-dependencies/issues/442)) ([79a093f](https://www.github.com/googleapis/java-shared-dependencies/commit/79a093f9ccea4d47cf8b678570a1c9699029a8b2)) - update dependency com.google.errorprone:error_prone_annotations to v2.9.0 ([#​441](https://www.togithub.com/googleapis/java-shared-dependencies/issues/441)) ([e644a4b](https://www.github.com/googleapis/java-shared-dependencies/commit/e644a4b504ab8aa5771f9be36861d1730ea9bcc9)) - update dependency io.grpc:grpc-bom to v1.40.0 ([#​438](https://www.togithub.com/googleapis/java-shared-dependencies/issues/438)) ([c3f8fb4](https://www.github.com/googleapis/java-shared-dependencies/commit/c3f8fb4408f5dc6c7f7dc0e14f0c24fa755433a5)) - update gax.version to v2.3.0 ([#​437](https://www.togithub.com/googleapis/java-shared-dependencies/issues/437)) ([e59aaad](https://www.github.com/googleapis/java-shared-dependencies/commit/e59aaadd76e40ab5ea31c3e812686a4ba0471a49)) - update dependency com.google.api:api-common to v2.0.1 ([#​431](https://www.togithub.com/googleapis/java-shared-dependencies/issues/431)) ([b1a52c8](https://www.github.com/googleapis/java-shared-dependencies/commit/b1a52c83e19be7be80086f2010e928171b046f62)) - update gax.version to v2.1.0 ([#​432](https://www.togithub.com/googleapis/java-shared-dependencies/issues/432)) ([7f53006](https://www.github.com/googleapis/java-shared-dependencies/commit/7f53006d021e839f52325a87d7c4715eff88818d)) - update google.core.version to v2.0.4 ([#​430](https://www.togithub.com/googleapis/java-shared-dependencies/issues/430)) ([d0465ad](https://www.github.com/googleapis/java-shared-dependencies/commit/d0465ad3a79993d4e854078ea992e53ab9add07f)) - update google.core.version to v2.0.5 ([#​434](https://www.togithub.com/googleapis/java-shared-dependencies/issues/434)) ([af00753](https://www.github.com/googleapis/java-shared-dependencies/commit/af0075390034cba5cefede8260ab03f728d525a8))
--- 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner-jdbc). chore: release 2.3.4 (#564) :robot: I have created a release \*beep\* \*boop\* --- * update dependency com.google.cloud:google-cloud-shared-dependencies to v2.1.0 ([#563](https://www.github.com/googleapis/java-spanner-jdbc/issues/563)) ([b0959a4](https://www.github.com/googleapis/java-spanner-jdbc/commit/b0959a412bae1a8024de92d5f9699d49863fb088)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). chore: release 2.3.5-SNAPSHOT (#565) :robot: I have created a release \*beep\* \*boop\* --- --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). fix: skip JSON tests on emulator deps: update dependency com.google.cloud:google-cloud-spanner-bom to v6.12.0 (#568) fix: remove unintentional change fix: add value for JSON in new test chore(deps): update dependency com.google.cloud:google-cloud-spanner-jdbc to v2.3.4 (#566) chore: release 2.3.5 (#569) :robot: I have created a release \*beep\* \*boop\* --- * update dependency com.google.cloud:google-cloud-spanner-bom to v6.12.0 ([#568](https://www.github.com/googleapis/java-spanner-jdbc/issues/568)) ([c032204](https://www.github.com/googleapis/java-spanner-jdbc/commit/c032204445d61c60385232216cdb52c217a85725)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). chore: release 2.3.6-SNAPSHOT (#571) :robot: I have created a release \*beep\* \*boop\* --- --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --- .github/generated-files-bot.yml | 1 + .github/readme/synth.metadata/synth.metadata | 4 +- .github/workflows/ci.yaml | 6 +- .kokoro/build.sh | 6 +- .kokoro/coerce_logs.sh | 1 - .kokoro/dependencies.sh | 5 +- .kokoro/nightly/integration.cfg | 2 +- .kokoro/nightly/samples.cfg | 2 +- .kokoro/release/publish_javadoc11.sh | 9 + .readme-partials.yaml | 22 ++ CHANGELOG.md | 136 +++++++++ README.md | 89 +++++- SECURITY.md | 7 + clirr-ignored-differences.xml | 22 ++ java.header | 2 +- pom.xml | 47 ++- renovate.json | 5 +- samples/install-without-bom/pom.xml | 6 +- samples/pom.xml | 2 +- samples/snapshot/pom.xml | 6 +- samples/snippets/pom.xml | 6 +- .../jdbc/AbstractJdbcPreparedStatement.java | 2 +- .../spanner/jdbc/AbstractJdbcWrapper.java | 3 + .../jdbc/CloudSpannerJdbcConnection.java | 41 +++ .../google/cloud/spanner/jdbc/JdbcArray.java | 4 + .../cloud/spanner/jdbc/JdbcConnection.java | 32 +++ .../cloud/spanner/jdbc/JdbcDataType.java | 53 ++++ .../google/cloud/spanner/jdbc/JdbcDriver.java | 28 +- .../spanner/jdbc/JdbcParameterStore.java | 152 +++++++--- .../spanner/jdbc/JdbcPreparedStatement.java | 4 +- .../cloud/spanner/jdbc/JdbcResultSet.java | 17 ++ .../cloud/spanner/jdbc/JdbcTypeConverter.java | 64 ++++- .../google/cloud/spanner/jdbc/JsonType.java | 55 ++++ .../spanner/jdbc/ClientSideStatements.json | 268 ------------------ .../jdbc/DatabaseMetaData_GetColumns.sql | 3 + .../spanner/jdbc/ITAbstractJdbcTest.java | 10 +- .../cloud/spanner/jdbc/JdbcArrayTest.java | 47 ++- .../spanner/jdbc/JdbcParameterStoreTest.java | 128 +++++++-- .../jdbc/JdbcPreparedStatementTest.java | 39 +++ .../spanner/jdbc/JdbcQueryOptionsTest.java | 111 ++++++-- .../jdbc/JdbcResultSetMetaDataTest.java | 22 +- .../cloud/spanner/jdbc/JdbcResultSetTest.java | 146 +++++++++- .../spanner/jdbc/JdbcTypeConverterTest.java | 18 ++ .../jdbc/it/ITJdbcDatabaseMetaDataTest.java | 3 + .../jdbc/it/ITJdbcPreparedStatementTest.java | 268 ++++++++++++++---- .../jdbc/it/ITJdbcQueryOptionsTest.java | 40 ++- .../jdbc/it/ITJdbcSimpleStatementsTest.java | 42 +++ .../spanner/jdbc/it/ITJdbcSqlScriptTest.java | 11 + .../spanner/jdbc/it/CreateMusicTables.sql | 2 + .../jdbc/it/CreateMusicTables_Emulator.sql | 104 +++++++ synth.metadata | 8 +- versions.txt | 2 +- 52 files changed, 1617 insertions(+), 496 deletions(-) create mode 100644 SECURITY.md create mode 100644 src/main/java/com/google/cloud/spanner/jdbc/JsonType.java delete mode 100644 src/main/resources/com/google/cloud/spanner/jdbc/ClientSideStatements.json create mode 100644 src/test/resources/com/google/cloud/spanner/jdbc/it/CreateMusicTables_Emulator.sql diff --git a/.github/generated-files-bot.yml b/.github/generated-files-bot.yml index 47c2ba132..c644a24e1 100644 --- a/.github/generated-files-bot.yml +++ b/.github/generated-files-bot.yml @@ -9,3 +9,4 @@ ignoreAuthors: - 'renovate-bot' - 'yoshi-automation' - 'release-please[bot]' +- 'gcf-owl-bot[bot]' diff --git a/.github/readme/synth.metadata/synth.metadata b/.github/readme/synth.metadata/synth.metadata index 36432895f..05a0f5ca1 100644 --- a/.github/readme/synth.metadata/synth.metadata +++ b/.github/readme/synth.metadata/synth.metadata @@ -4,14 +4,14 @@ "git": { "name": ".", "remote": "https://github.com/googleapis/java-spanner-jdbc.git", - "sha": "da5084160a5c89552b57cf32e6af1e70e0d6b807" + "sha": "a09b94bd75d3db728e187478a30a5589ac037aa7" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "082e1ca0863b13ada8594fe91845380765da5b70" + "sha": "484b7ec7bdef3909589a83e3d763e7588cb8c37c" } } ] diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 29d933b04..65ae6ecdd 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -19,10 +19,6 @@ jobs: - run: .kokoro/build.sh env: JOB_TYPE: test - - name: coverage - uses: codecov/codecov-action@v1 - with: - name: actions ${{matrix.java}} windows: runs-on: windows-latest steps: @@ -80,4 +76,4 @@ jobs: - run: java -version - run: .kokoro/build.sh env: - JOB_TYPE: clirr \ No newline at end of file + JOB_TYPE: clirr diff --git a/.kokoro/build.sh b/.kokoro/build.sh index 9eaeef4f2..a4c46cfca 100755 --- a/.kokoro/build.sh +++ b/.kokoro/build.sh @@ -23,8 +23,8 @@ cd ${scriptDir}/.. # include common functions source ${scriptDir}/common.sh -# Print out Java version -java -version +# Print out Maven & Java version +mvn -version echo ${JOB_TYPE} # attempt to install 3 times with exponential backoff (starting with 10 seconds) @@ -115,7 +115,7 @@ fi # fix output location of logs bash .kokoro/coerce_logs.sh -if [[ "${ENABLE_BUILD_COP}" == "true" ]] +if [[ "${ENABLE_FLAKYBOT}" == "true" ]] then chmod +x ${KOKORO_GFILE_DIR}/linux_amd64/flakybot ${KOKORO_GFILE_DIR}/linux_amd64/flakybot -repo=googleapis/java-spanner-jdbc diff --git a/.kokoro/coerce_logs.sh b/.kokoro/coerce_logs.sh index 5cf7ba49e..46edbf7f2 100755 --- a/.kokoro/coerce_logs.sh +++ b/.kokoro/coerce_logs.sh @@ -28,7 +28,6 @@ job=$(basename ${KOKORO_JOB_NAME}) echo "coercing sponge logs..." for xml in `find . -name *-sponge_log.xml` do - echo "processing ${xml}" class=$(basename ${xml} | cut -d- -f2) dir=$(dirname ${xml})/${job}/${class} text=$(dirname ${xml})/${class}-sponge_log.txt diff --git a/.kokoro/dependencies.sh b/.kokoro/dependencies.sh index 59d2aafc7..9030ba8f9 100755 --- a/.kokoro/dependencies.sh +++ b/.kokoro/dependencies.sh @@ -14,6 +14,7 @@ # limitations under the License. set -eo pipefail +shopt -s nullglob ## Get the directory of the build script scriptDir=$(realpath $(dirname "${BASH_SOURCE[0]}")) @@ -46,7 +47,7 @@ function completenessCheck() { # This is stripped from the output as it is not present in the flattened pom. # Only dependencies with 'compile' or 'runtime' scope are included from original dependency list. msg "Generating dependency list using original pom..." - mvn dependency:list -f pom.xml -DincludeScope=runtime -Dsort=true | grep '\[INFO] .*:.*:.*:.*:.*' | sed -e s/\\s--\\smodule.*// >.org-list.txt + mvn dependency:list -f pom.xml -DincludeScope=runtime -Dsort=true | grep '\[INFO] .*:.*:.*:.*:.*' | sed -e 's/ --.*//' >.org-list.txt # Output dep list generated using the flattened pom (only 'compile' and 'runtime' scopes) msg "Generating dependency list using flattened pom..." @@ -70,7 +71,7 @@ function completenessCheck() { set +e error_count=0 -for path in $(find -name ".flattened-pom.xml") +for path in **/.flattened-pom.xml do # Check flattened pom in each dir that contains it for completeness dir=$(dirname "$path") diff --git a/.kokoro/nightly/integration.cfg b/.kokoro/nightly/integration.cfg index 0048c8ece..e51c7b4c6 100644 --- a/.kokoro/nightly/integration.cfg +++ b/.kokoro/nightly/integration.cfg @@ -22,7 +22,7 @@ env_vars: { } env_vars: { - key: "ENABLE_BUILD_COP" + key: "ENABLE_FLAKYBOT" value: "true" } diff --git a/.kokoro/nightly/samples.cfg b/.kokoro/nightly/samples.cfg index f25429314..9761fd864 100644 --- a/.kokoro/nightly/samples.cfg +++ b/.kokoro/nightly/samples.cfg @@ -33,6 +33,6 @@ env_vars: { } env_vars: { - key: "ENABLE_BUILD_COP" + key: "ENABLE_FLAKYBOT" value: "true" } diff --git a/.kokoro/release/publish_javadoc11.sh b/.kokoro/release/publish_javadoc11.sh index 164c47361..38ee2e5c8 100755 --- a/.kokoro/release/publish_javadoc11.sh +++ b/.kokoro/release/publish_javadoc11.sh @@ -42,6 +42,8 @@ mvn clean site -B -q -P docFX # copy README to docfx-yml dir and rename index.md cp README.md target/docfx-yml/index.md +# copy CHANGELOG to docfx-yml dir and rename history.md +cp CHANGELOG.md target/docfx-yml/history.md pushd target/docfx-yml @@ -49,6 +51,13 @@ pushd target/docfx-yml python3 -m docuploader create-metadata \ --name ${NAME} \ --version ${VERSION} \ + --xrefs devsite://java/gax \ + --xrefs devsite://java/google-cloud-core \ + --xrefs devsite://java/api-common \ + --xrefs devsite://java/proto-google-common-protos \ + --xrefs devsite://java/google-api-client \ + --xrefs devsite://java/google-http-client \ + --xrefs devsite://java/protobuf \ --language java # upload yml to production bucket diff --git a/.readme-partials.yaml b/.readme-partials.yaml index 3407400d2..6fcc2f61a 100644 --- a/.readme-partials.yaml +++ b/.readme-partials.yaml @@ -24,6 +24,28 @@ custom_content: | } ``` + ### Connection URL Properties + + The Cloud Spanner JDBC driver supports the following connection URL properties. Note that all of + these can also be supplied in a Properties instance that is passed to the + `DriverManager#getConnection(String url, Properties properties)` method. + + #### Commonly Used Properties + - credentials (String): URL for the credentials file to use for the connection. If you do not specify any credentials at all, the default credentials of the environment as returned by `GoogleCredentials#getApplicationDefault()` is used. Example: `jdbc:cloudspanner:/projects/my-project/instances/my-instance/databases/my-db;credentials=/path/to/credentials.json` + - autocommit (boolean): Sets the initial autocommit mode for the connection. Default is true. + - readonly (boolean): Sets the initial readonly mode for the connection. Default is false. + - autoConfigEmulator (boolean): Automatically configure the connection to try to connect to the Cloud Spanner emulator. You do not need to specify any host or port in the connection string as long as the emulator is running on the default host/port (localhost:9010). The instance and database in the connection string will automatically be created if these do not yet exist on the emulator. This means that you do not need to execute any `gcloud` commands on the emulator to create the instance and database before you can connect to it. Example: `jdbc:cloudspanner:/projects/test-project/instances/test-instance/databases/test-db;autoConfigEmulator=true` + - usePlainText (boolean): Sets whether the JDBC connection should establish an unencrypted connection to a (local) server. This option can only be used when connecting to a local emulator that does not require an encrypted connection, and that does not require authentication. Example: `jdbc:cloudspanner://localhost:9010/projects/test-project/instances/test-instance/databases/test-db;usePlainText=true` + - optimizerVersion (String): Sets the default query optimizer version to use for this connection. See also https://cloud.google.com/spanner/docs/query-optimizer/query-optimizer-versions. + + #### Advanced Properties + - minSessions (int): Sets the minimum number of sessions in the backing session pool. Defaults to 100. + - maxSessions (int): Sets the maximum number of sessions in the backing session pool. Defaults to 400. + - numChannels (int): Sets the number of gRPC channels to use. Defaults to 4. + - retryAbortsInternally (boolean): The JDBC driver will by default automatically retry aborted transactions internally. This is done by keeping track of all statements and the results of these during a transaction, and if the transaction is aborted by Cloud Spanner, it will replay the statements on a new transaction and compare the results with the initial attempt. Disable this option if you want to handle aborted transactions in your own application. + - oauthToken (string): A valid pre-existing OAuth token to use for authentication for this connection. Setting this property will take precedence over any value set for a credentials file. + - lenient (boolean): Enable this to force the JDBC driver to ignore unknown properties in the connection URL. Some applications automatically add additional properties to the URL that are not recognized by the JDBC driver. Normally, the JDBC driver will reject this, unless `lenient` mode is enabled. + ### Jar with Dependencies A single jar with all dependencies can be downloaded from https://repo1.maven.org/maven2/com/google/cloud/google-cloud-spanner-jdbc/latest or be built with the command `mvn package` (select the jar that is named `google-cloud-spanner-jdbc--single-jar-with-dependencies.jar`). diff --git a/CHANGELOG.md b/CHANGELOG.md index 1acc5b01e..315f5f2e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,141 @@ # Changelog +### [2.3.5](https://www.github.com/googleapis/java-spanner-jdbc/compare/v2.3.4...v2.3.5) (2021-08-24) + + +### Dependencies + +* update dependency com.google.cloud:google-cloud-spanner-bom to v6.12.0 ([#568](https://www.github.com/googleapis/java-spanner-jdbc/issues/568)) ([c032204](https://www.github.com/googleapis/java-spanner-jdbc/commit/c032204445d61c60385232216cdb52c217a85725)) + +### [2.3.4](https://www.github.com/googleapis/java-spanner-jdbc/compare/v2.3.3...v2.3.4) (2021-08-23) + + +### Dependencies + +* update dependency com.google.cloud:google-cloud-shared-dependencies to v2.1.0 ([#563](https://www.github.com/googleapis/java-spanner-jdbc/issues/563)) ([b0959a4](https://www.github.com/googleapis/java-spanner-jdbc/commit/b0959a412bae1a8024de92d5f9699d49863fb088)) + +### [2.3.3](https://www.github.com/googleapis/java-spanner-jdbc/compare/v2.3.2...v2.3.3) (2021-08-19) + + +### Dependencies + +* update dependency com.google.cloud:google-cloud-spanner-bom to v6.11.1 ([#556](https://www.github.com/googleapis/java-spanner-jdbc/issues/556)) ([36f0d32](https://www.github.com/googleapis/java-spanner-jdbc/commit/36f0d32aec65f098f7091d44a0e4acc98104aeb9)) + +### [2.3.2](https://www.github.com/googleapis/java-spanner-jdbc/compare/v2.3.1...v2.3.2) (2021-08-12) + + +### Dependencies + +* update dependency com.google.cloud:google-cloud-spanner-bom to v6.11.0 ([#549](https://www.github.com/googleapis/java-spanner-jdbc/issues/549)) ([2639e40](https://www.github.com/googleapis/java-spanner-jdbc/commit/2639e40ebbde19966653f06f8b664106568f6bac)) + +### [2.3.1](https://www.github.com/googleapis/java-spanner-jdbc/compare/v2.3.0...v2.3.1) (2021-08-12) + + +### Dependencies + +* update dependency com.google.cloud:google-cloud-spanner-bom to v6.10.1 ([#538](https://www.github.com/googleapis/java-spanner-jdbc/issues/538)) ([75507c4](https://www.github.com/googleapis/java-spanner-jdbc/commit/75507c4a42c3b051e8a14c1233b3b2526c0d3ccc)) + +## [2.3.0](https://www.github.com/googleapis/java-spanner-jdbc/compare/v2.2.6...v2.3.0) (2021-08-11) + + +### Features + +* add support for tagging to JDBC connection ([#270](https://www.github.com/googleapis/java-spanner-jdbc/issues/270)) ([a4bd82c](https://www.github.com/googleapis/java-spanner-jdbc/commit/a4bd82c8e4ce8b7179b943ac06b049598276f1b4)) + + +### Dependencies + +* update dependency com.google.cloud:google-cloud-shared-dependencies to v2 ([#544](https://www.github.com/googleapis/java-spanner-jdbc/issues/544)) ([366430d](https://www.github.com/googleapis/java-spanner-jdbc/commit/366430dc270edd09de1a0749ba360f312897b1aa)) +* update dependency com.google.cloud:google-cloud-spanner-bom to v6.10.0 ([#537](https://www.github.com/googleapis/java-spanner-jdbc/issues/537)) ([8655ae5](https://www.github.com/googleapis/java-spanner-jdbc/commit/8655ae5955f5385a9d6445e13264427d73c4d37e)) + +### [2.2.6](https://www.github.com/googleapis/java-spanner-jdbc/compare/v2.2.5...v2.2.6) (2021-07-06) + + +### Dependencies + +* update dependency com.google.cloud:google-cloud-spanner-bom to v6.9.1 ([#525](https://www.github.com/googleapis/java-spanner-jdbc/issues/525)) ([37023b8](https://www.github.com/googleapis/java-spanner-jdbc/commit/37023b8295c97304aa0a55a28f71905fcbf5b93f)) + +### [2.2.5](https://www.github.com/googleapis/java-spanner-jdbc/compare/v2.2.4...v2.2.5) (2021-07-06) + + +### Dependencies + +* update dependency com.google.cloud:google-cloud-spanner-bom to v6.9.0 ([#521](https://www.github.com/googleapis/java-spanner-jdbc/issues/521)) ([8d840ac](https://www.github.com/googleapis/java-spanner-jdbc/commit/8d840ac855f4466c1d53a3b38d964e213708e5e5)) + +### [2.2.4](https://www.github.com/googleapis/java-spanner-jdbc/compare/v2.2.3...v2.2.4) (2021-07-02) + + +### Bug Fixes + +* Add `shopt -s nullglob` to dependencies script ([#514](https://www.github.com/googleapis/java-spanner-jdbc/issues/514)) ([ae51b24](https://www.github.com/googleapis/java-spanner-jdbc/commit/ae51b241148606ffddeb0a703b853de67710e48b)) +* prevent relocating urls that start with com like /computeMetadata/ ([#511](https://www.github.com/googleapis/java-spanner-jdbc/issues/511)) ([1178a1d](https://www.github.com/googleapis/java-spanner-jdbc/commit/1178a1d35b4b0032acf71b3dbf862d4f9fb9399c)) +* Update dependencies.sh to not break on mac ([#506](https://www.github.com/googleapis/java-spanner-jdbc/issues/506)) ([e205c0c](https://www.github.com/googleapis/java-spanner-jdbc/commit/e205c0c8eba6ac23d747c433b42d8e2365528bd8)) + + +### Dependencies + +* update dependency com.google.cloud:google-cloud-shared-dependencies to v1.4.0 ([#518](https://www.github.com/googleapis/java-spanner-jdbc/issues/518)) ([045b858](https://www.github.com/googleapis/java-spanner-jdbc/commit/045b8586a7ca7b0e2bd341b27ca3e8a3530c992a)) +* update dependency com.google.cloud:google-cloud-spanner-bom to v6.7.0 ([#513](https://www.github.com/googleapis/java-spanner-jdbc/issues/513)) ([e1affe3](https://www.github.com/googleapis/java-spanner-jdbc/commit/e1affe358a812a45b9d2c0c9ccd0b00e3aa3791e)) +* update dependency com.google.cloud:google-cloud-spanner-bom to v6.8.0 ([#517](https://www.github.com/googleapis/java-spanner-jdbc/issues/517)) ([c9013ff](https://www.github.com/googleapis/java-spanner-jdbc/commit/c9013ff48269b158121e4c65c545be30752c31fb)) + +### [2.2.3](https://www.github.com/googleapis/java-spanner-jdbc/compare/v2.2.2...v2.2.3) (2021-06-15) + + +### Dependencies + +* update dependency com.google.cloud:google-cloud-spanner-bom to v6.6.1 ([#502](https://www.github.com/googleapis/java-spanner-jdbc/issues/502)) ([41a9cd4](https://www.github.com/googleapis/java-spanner-jdbc/commit/41a9cd49fed468f410ad226555f7b9ba46d857b3)) + +### [2.2.2](https://www.github.com/googleapis/java-spanner-jdbc/compare/v2.2.1...v2.2.2) (2021-06-10) + + +### Dependencies + +* update dependency com.google.cloud:google-cloud-spanner-bom to v6.6.0 ([#498](https://www.github.com/googleapis/java-spanner-jdbc/issues/498)) ([5849a97](https://www.github.com/googleapis/java-spanner-jdbc/commit/5849a970087d3fa1d1b42092b4568602563a1dbd)) + +### [2.2.1](https://www.github.com/googleapis/java-spanner-jdbc/compare/v2.2.0...v2.2.1) (2021-06-04) + + +### Dependencies + +* update dependency com.google.cloud:google-cloud-shared-dependencies to v1.3.0 ([#490](https://www.github.com/googleapis/java-spanner-jdbc/issues/490)) ([bf0c9d6](https://www.github.com/googleapis/java-spanner-jdbc/commit/bf0c9d6bf612b50a59ea2d530430ccace79aaf35)) + +## [2.2.0](https://www.github.com/googleapis/java-spanner-jdbc/compare/v2.1.0...v2.2.0) (2021-05-26) + + +### Features + +* add `gcf-owl-bot[bot]` to `ignoreAuthors` ([#474](https://www.github.com/googleapis/java-spanner-jdbc/issues/474)) ([c14f17b](https://www.github.com/googleapis/java-spanner-jdbc/commit/c14f17b411b15e778a68ce998de04732b159d7ac)) + + +### Documentation + +* document connection properties in README ([#478](https://www.github.com/googleapis/java-spanner-jdbc/issues/478)) ([3ccc543](https://www.github.com/googleapis/java-spanner-jdbc/commit/3ccc5433bec261b18d2536b04590e7645e47ed9b)), closes [#456](https://www.github.com/googleapis/java-spanner-jdbc/issues/456) + + +### Dependencies + +* update dependency com.google.cloud:google-cloud-shared-dependencies to v1.2.0 ([#473](https://www.github.com/googleapis/java-spanner-jdbc/issues/473)) ([a6cc069](https://www.github.com/googleapis/java-spanner-jdbc/commit/a6cc0697ed5916c665f007a1bf16660b8b91f9f9)) +* update dependency com.google.cloud:google-cloud-spanner-bom to v6.5.0 ([#483](https://www.github.com/googleapis/java-spanner-jdbc/issues/483)) ([e7fec30](https://www.github.com/googleapis/java-spanner-jdbc/commit/e7fec30f2f2c5518821d5348d448f102301d65c3)) + +## [2.1.0](https://www.github.com/googleapis/java-spanner-jdbc/compare/v2.0.2...v2.1.0) (2021-05-18) + + +### Features + +* allow get/set Spanner Value instances ([#454](https://www.github.com/googleapis/java-spanner-jdbc/issues/454)) ([d6935b8](https://www.github.com/googleapis/java-spanner-jdbc/commit/d6935b863349c58cfdd44d6ce20dba6f5dbc1472)), closes [#452](https://www.github.com/googleapis/java-spanner-jdbc/issues/452) + + +### Bug Fixes + +* NPE was thrown when getting an array of structs from a ResultSet ([#445](https://www.github.com/googleapis/java-spanner-jdbc/issues/445)) ([1dfb37b](https://www.github.com/googleapis/java-spanner-jdbc/commit/1dfb37b27ee661718fe80be0bf260c40f4b15582)), closes [#444](https://www.github.com/googleapis/java-spanner-jdbc/issues/444) + + +### Dependencies + +* update dependency com.google.cloud:google-cloud-shared-dependencies to v1.1.0 ([#463](https://www.github.com/googleapis/java-spanner-jdbc/issues/463)) ([f148c71](https://www.github.com/googleapis/java-spanner-jdbc/commit/f148c71bef2b762d7b4475ba7f28443c7938c394)) +* update dependency com.google.cloud:google-cloud-spanner-bom to v6.4.0 ([#453](https://www.github.com/googleapis/java-spanner-jdbc/issues/453)) ([7dac8b3](https://www.github.com/googleapis/java-spanner-jdbc/commit/7dac8b3e43625aa28be214bd735fc3386770de04)) +* update dependency com.google.cloud:google-cloud-spanner-bom to v6.4.4 ([#464](https://www.github.com/googleapis/java-spanner-jdbc/issues/464)) ([eeb31c0](https://www.github.com/googleapis/java-spanner-jdbc/commit/eeb31c050fda116203d9da5c4a80c7f1c6a6cac4)) + ### [2.0.2](https://www.github.com/googleapis/java-spanner-jdbc/compare/v2.0.1...v2.0.2) (2021-04-26) diff --git a/README.md b/README.md index 1fbd770a5..515d5dad1 100644 --- a/README.md +++ b/README.md @@ -8,33 +8,41 @@ Java idiomatic client for [Google Cloud Spanner JDBC][product-docs]. - [Product Documentation][product-docs] - [Client Library Documentation][javadocs] + ## Quickstart If you are using Maven, add this to your pom.xml file: + ```xml com.google.cloud google-cloud-spanner-jdbc - 2.0.1 + 2.3.3 ``` If you are using Gradle without BOM, add this to your dependencies + ```Groovy -compile 'com.google.cloud:google-cloud-spanner-jdbc:2.0.1' +compile 'com.google.cloud:google-cloud-spanner-jdbc:2.3.3' ``` If you are using SBT, add this to your dependencies + ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-spanner-jdbc" % "2.0.1" +libraryDependencies += "com.google.cloud" % "google-cloud-spanner-jdbc" % "2.3.3" ``` ## Authentication See the [Authentication][authentication] section in the base directory's README. +## Authorization + +The client application making API calls must be granted [authorization scopes][auth-scopes] required for the desired Google Cloud Spanner JDBC APIs, and the authenticated principal must have the [IAM role(s)][predefined-iam-roles] required to access GCP resources using the Google Cloud Spanner JDBC API calls. + ## Getting Started ### Prerequisites @@ -84,6 +92,28 @@ try (Connection connection = } ``` +### Connection URL Properties + +The Cloud Spanner JDBC driver supports the following connection URL properties. Note that all of +these can also be supplied in a Properties instance that is passed to the +`DriverManager#getConnection(String url, Properties properties)` method. + +#### Commonly Used Properties +- credentials (String): URL for the credentials file to use for the connection. If you do not specify any credentials at all, the default credentials of the environment as returned by `GoogleCredentials#getApplicationDefault()` is used. Example: `jdbc:cloudspanner:/projects/my-project/instances/my-instance/databases/my-db;credentials=/path/to/credentials.json` +- autocommit (boolean): Sets the initial autocommit mode for the connection. Default is true. +- readonly (boolean): Sets the initial readonly mode for the connection. Default is false. +- autoConfigEmulator (boolean): Automatically configure the connection to try to connect to the Cloud Spanner emulator. You do not need to specify any host or port in the connection string as long as the emulator is running on the default host/port (localhost:9010). The instance and database in the connection string will automatically be created if these do not yet exist on the emulator. This means that you do not need to execute any `gcloud` commands on the emulator to create the instance and database before you can connect to it. Example: `jdbc:cloudspanner:/projects/test-project/instances/test-instance/databases/test-db;autoConfigEmulator=true` +- usePlainText (boolean): Sets whether the JDBC connection should establish an unencrypted connection to a (local) server. This option can only be used when connecting to a local emulator that does not require an encrypted connection, and that does not require authentication. Example: `jdbc:cloudspanner://localhost:9010/projects/test-project/instances/test-instance/databases/test-db;usePlainText=true` +- optimizerVersion (String): Sets the default query optimizer version to use for this connection. See also https://cloud.google.com/spanner/docs/query-optimizer/query-optimizer-versions. + +#### Advanced Properties +- minSessions (int): Sets the minimum number of sessions in the backing session pool. Defaults to 100. +- maxSessions (int): Sets the maximum number of sessions in the backing session pool. Defaults to 400. +- numChannels (int): Sets the number of gRPC channels to use. Defaults to 4. +- retryAbortsInternally (boolean): The JDBC driver will by default automatically retry aborted transactions internally. This is done by keeping track of all statements and the results of these during a transaction, and if the transaction is aborted by Cloud Spanner, it will replay the statements on a new transaction and compare the results with the initial attempt. Disable this option if you want to handle aborted transactions in your own application. +- oauthToken (string): A valid pre-existing OAuth token to use for authentication for this connection. Setting this property will take precedence over any value set for a credentials file. +- lenient (boolean): Enable this to force the JDBC driver to ignore unknown properties in the connection URL. Some applications automatically add additional properties to the URL that are not recognized by the JDBC driver. Normally, the JDBC driver will reject this, unless `lenient` mode is enabled. + ### Jar with Dependencies A single jar with all dependencies can be downloaded from https://repo1.maven.org/maven2/com/google/cloud/google-cloud-spanner-jdbc/latest or be built with the command `mvn package` (select the jar that is named `google-cloud-spanner-jdbc--single-jar-with-dependencies.jar`). @@ -106,16 +136,57 @@ activate the `shade` profile like this: To get help, follow the instructions in the [shared Troubleshooting document][troubleshooting]. -## Java Versions +## Supported Java Versions Java 8 or above is required for using this client. +Google's Java client libraries, +[Google Cloud Client Libraries][cloudlibs] +and +[Google Cloud API Libraries][apilibs], +follow the +[Oracle Java SE support roadmap][oracle] +(see the Oracle Java SE Product Releases section). + +### For new development + +In general, new feature development occurs with support for the lowest Java +LTS version covered by Oracle's Premier Support (which typically lasts 5 years +from initial General Availability). If the minimum required JVM for a given +library is changed, it is accompanied by a [semver][semver] major release. + +Java 11 and (in September 2021) Java 17 are the best choices for new +development. + +### Keeping production systems current + +Google tests its client libraries with all current LTS versions covered by +Oracle's Extended Support (which typically lasts 8 years from initial +General Availability). + +#### Legacy support + +Google's client libraries support legacy versions of Java runtimes with long +term stable libraries that don't receive feature updates on a best efforts basis +as it may not be possible to backport all patches. + +Google provides updates on a best efforts basis to apps that continue to use +Java 7, though apps might need to upgrade to current versions of the library +that supports their JVM. + +#### Where to find specific information + +The latest versions and the supported Java versions are identified on +the individual GitHub repository `github.com/GoogleAPIs/java-SERVICENAME` +and on [google-cloud-java][g-c-j]. + ## Versioning This library follows [Semantic Versioning](http://semver.org/). + ## Contributing @@ -127,6 +198,7 @@ Please note that this project is released with a Contributor Code of Conduct. By this project you agree to abide by its terms. See [Code of Conduct][code-of-conduct] for more information. + ## License Apache 2.0 - See [LICENSE][license] for more information. @@ -158,6 +230,9 @@ Java is a registered trademark of Oracle and/or its affiliates. [maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-spanner-jdbc.svg [maven-version-link]: https://search.maven.org/search?q=g:com.google.cloud%20AND%20a:google-cloud-spanner-jdbc&core=gav [authentication]: https://github.com/googleapis/google-cloud-java#authentication +[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes +[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles +[iam-policy]: https://cloud.google.com/iam/docs/overview#cloud-iam-policy [developer-console]: https://console.developers.google.com/ [create-project]: https://cloud.google.com/resource-manager/docs/creating-managing-projects [cloud-sdk]: https://cloud.google.com/sdk/ @@ -169,3 +244,9 @@ Java is a registered trademark of Oracle and/or its affiliates. [libraries-bom]: https://github.com/GoogleCloudPlatform/cloud-opensource-java/wiki/The-Google-Cloud-Platform-Libraries-BOM [shell_img]: https://gstatic.com/cloudssh/images/open-btn.png + +[semver]: https://semver.org/ +[cloudlibs]: https://cloud.google.com/apis/docs/client-libraries-explained +[apilibs]: https://cloud.google.com/apis/docs/client-libraries-explained#google_api_client_libraries +[oracle]: https://www.oracle.com/java/technologies/java-se-support-roadmap.html +[g-c-j]: http://github.com/googleapis/google-cloud-java diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..8b58ae9c0 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,7 @@ +# Security Policy + +To report a security issue, please use [g.co/vulnz](https://g.co/vulnz). + +The Google Security Team will respond within 5 working days of your report on g.co/vulnz. + +We use g.co/vulnz for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue. diff --git a/clirr-ignored-differences.xml b/clirr-ignored-differences.xml index ac9c147d1..0962d5e12 100644 --- a/clirr-ignored-differences.xml +++ b/clirr-ignored-differences.xml @@ -111,4 +111,26 @@ com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection void setReturnCommitStats(boolean) + + + + 7012 + com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection + java.lang.String getTransactionTag() + + + 7012 + com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection + void setTransactionTag(java.lang.String) + + + 7012 + com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection + java.lang.String getStatementTag() + + + 7012 + com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection + void setStatementTag(java.lang.String) + diff --git a/java.header b/java.header index 3a9b503aa..d0970ba7d 100644 --- a/java.header +++ b/java.header @@ -1,5 +1,5 @@ ^/\*$ -^ \* Copyright \d\d\d\d,? Google (Inc\.|LLC)( All [rR]ights [rR]eserved\.)?$ +^ \* Copyright \d\d\d\d,? Google (Inc\.|LLC)$ ^ \*$ ^ \* Licensed under the Apache License, Version 2\.0 \(the "License"\);$ ^ \* you may not use this file except in compliance with the License\.$ diff --git a/pom.xml b/pom.xml index a64cd171e..1fc8eb149 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 google-cloud-spanner-jdbc - 2.0.2 + 2.3.6-SNAPSHOT jar Google Cloud Spanner JDBC https://github.com/googleapis/java-spanner-jdbc @@ -14,7 +14,7 @@ com.google.cloud google-cloud-shared-config - 0.11.2 + 1.0.1 @@ -40,16 +40,7 @@ https://github.com/googleapis/java-spanner-jdbc/issues GitHub Issues - - - sonatype-nexus-snapshots - https://oss.sonatype.org/content/repositories/snapshots - - - sonatype-nexus-staging - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - + Apache-2.0 @@ -61,7 +52,7 @@ 4.13.2 3.0.2 1.4.4 - 1.1.2 + 1.1.3 1.10.19 2.2 @@ -71,14 +62,14 @@ com.google.cloud google-cloud-spanner-bom - 6.3.3 + 6.12.0 pom import com.google.cloud google-cloud-shared-dependencies - 1.0.0 + 2.1.0 pom import @@ -163,6 +154,12 @@ truth ${truth.version} test + + + org.checkerframework + checker-qual + + org.hamcrest @@ -333,26 +330,26 @@ - com - com.google.cloud.spanner.jdbc.shaded.com + com. + com.google.cloud.spanner.jdbc.shaded.com. com.google.cloud.spanner.** - android - com.google.cloud.spanner.jdbc.shaded.android + android. + com.google.cloud.spanner.jdbc.shaded.android. - io - com.google.cloud.spanner.jdbc.shaded.io + io. + com.google.cloud.spanner.jdbc.shaded.io. io.grpc.netty.shaded.** - org - com.google.cloud.spanner.jdbc.shaded.org + org. + com.google.cloud.spanner.jdbc.shaded.org. org.conscrypt.** @@ -370,7 +367,7 @@ org.apache.maven.plugins maven-project-info-reports-plugin - 3.1.1 + 3.1.2 @@ -397,7 +394,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.2.0 + 3.3.0 html diff --git a/renovate.json b/renovate.json index 4ac4d97c6..a95a109bd 100644 --- a/renovate.json +++ b/renovate.json @@ -69,5 +69,8 @@ } ], "semanticCommits": true, - "masterIssue": true + "dependencyDashboard": true, + "dependencyDashboardLabels": [ + "type: process" + ] } diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml index e5e5c8570..93f09b833 100644 --- a/samples/install-without-bom/pom.xml +++ b/samples/install-without-bom/pom.xml @@ -14,7 +14,7 @@ com.google.cloud.samples shared-configuration - 1.0.22 + 1.0.23 @@ -29,7 +29,7 @@ com.google.cloud google-cloud-spanner-jdbc - 2.0.1 + 2.3.4 @@ -42,7 +42,7 @@ com.google.truth truth - 1.1.2 + 1.1.3 test diff --git a/samples/pom.xml b/samples/pom.xml index 08d34f32f..b50770aae 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -18,7 +18,7 @@ com.google.cloud.samples shared-configuration - 1.0.22 + 1.0.23 diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index 30d747066..7d0dbe500 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -14,7 +14,7 @@ com.google.cloud.samples shared-configuration - 1.0.22 + 1.0.23 @@ -28,7 +28,7 @@ com.google.cloud google-cloud-spanner-jdbc - 2.0.2 + 2.3.6-SNAPSHOT @@ -41,7 +41,7 @@ com.google.truth truth - 1.1.2 + 1.1.3 test diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index cb66073c1..ae8f5954d 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -14,7 +14,7 @@ com.google.cloud.samples shared-configuration - 1.0.22 + 1.0.23 @@ -30,7 +30,7 @@ com.google.cloud libraries-bom - 20.1.0 + 21.0.0 pom import @@ -53,7 +53,7 @@ com.google.truth truth - 1.1.2 + 1.1.3 test diff --git a/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcPreparedStatement.java b/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcPreparedStatement.java index 0507d5d5d..2a905660b 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcPreparedStatement.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcPreparedStatement.java @@ -198,7 +198,7 @@ public void setObject(int parameterIndex, Object value, int targetSqlType) throw @Override public void setObject(int parameterIndex, Object value) throws SQLException { checkClosed(); - parameters.setParameter(parameterIndex, value, null); + parameters.setParameter(parameterIndex, value, (SQLType) null); } @Override diff --git a/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcWrapper.java b/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcWrapper.java index 9f9752452..5f2967310 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcWrapper.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcWrapper.java @@ -48,6 +48,7 @@ static int extractColumnType(Type type) { if (type.equals(Type.int64())) return Types.BIGINT; if (type.equals(Type.numeric())) return Types.NUMERIC; if (type.equals(Type.string())) return Types.NVARCHAR; + if (type.equals(Type.json())) return Types.NVARCHAR; if (type.equals(Type.timestamp())) return Types.TIMESTAMP; if (type.getCode() == Code.ARRAY) return Types.ARRAY; return Types.OTHER; @@ -106,6 +107,7 @@ static String getClassName(Type type) { if (type == Type.int64()) return Long.class.getName(); if (type == Type.numeric()) return BigDecimal.class.getName(); if (type == Type.string()) return String.class.getName(); + if (type == Type.json()) return String.class.getName(); if (type == Type.timestamp()) return Timestamp.class.getName(); if (type.getCode() == Code.ARRAY) { if (type.getArrayElementType() == Type.bool()) return Boolean[].class.getName(); @@ -115,6 +117,7 @@ static String getClassName(Type type) { if (type.getArrayElementType() == Type.int64()) return Long[].class.getName(); if (type.getArrayElementType() == Type.numeric()) return BigDecimal[].class.getName(); if (type.getArrayElementType() == Type.string()) return String[].class.getName(); + if (type.getArrayElementType() == Type.json()) return String[].class.getName(); if (type.getArrayElementType() == Type.timestamp()) return Timestamp[].class.getName(); } return null; diff --git a/src/main/java/com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection.java b/src/main/java/com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection.java index 4a5f001a8..50ae71c56 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection.java @@ -39,6 +39,47 @@ */ public interface CloudSpannerJdbcConnection extends Connection { + /** + * Sets the transaction tag to use for the current transaction. This method may only be called + * when in a transaction, and before the transaction is actually started, i.e. before any + * statements have been executed in the transaction. + * + *

The tag will be set as the transaction tag of all statements during the transaction, and as + * the transaction tag of the commit. + * + *

The transaction tag will automatically be cleared after the transaction has ended. + * + * @param tag The tag to use. + */ + default void setTransactionTag(String tag) throws SQLException { + throw new UnsupportedOperationException(); + }; + + /** @return The transaction tag of the current transaction. */ + default String getTransactionTag() throws SQLException { + throw new UnsupportedOperationException(); + }; + + /** + * Sets the statement tag to use for the next statement that will be executed. The tag is + * automatically cleared after the statement is executed. Statement tags can be used both with + * autocommit=true and autocommit=false, and can be used for partitioned DML. + * + * @param tag The statement tag to use with the next statement that will be executed on this + * connection. + */ + default void setStatementTag(String tag) throws SQLException { + throw new UnsupportedOperationException(); + }; + + /** + * @return The statement tag that will be used with the next statement that is executed on this + * connection. + */ + default String getStatementTag() throws SQLException { + throw new UnsupportedOperationException(); + }; + /** * Sets the transaction mode to use for current transaction. This method may only be called when * in a transaction, and before the transaction is actually started, i.e. before any statements diff --git a/src/main/java/com/google/cloud/spanner/jdbc/JdbcArray.java b/src/main/java/com/google/cloud/spanner/jdbc/JdbcArray.java index 2a9d9e776..436774050 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/JdbcArray.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/JdbcArray.java @@ -21,6 +21,7 @@ import com.google.cloud.spanner.Struct; import com.google.cloud.spanner.Type; import com.google.cloud.spanner.Type.StructField; +import com.google.cloud.spanner.Value; import com.google.cloud.spanner.ValueBinder; import com.google.common.collect.ImmutableList; import com.google.rpc.Code; @@ -201,6 +202,9 @@ public ResultSet getResultSet(long startIndex, int count) throws SQLException { case STRING: builder = binder.to((String) value); break; + case JSON: + builder = binder.to(Value.json((String) value)); + break; case TIMESTAMP: builder = binder.to(JdbcTypeConverter.toGoogleTimestamp((Timestamp) value)); break; diff --git a/src/main/java/com/google/cloud/spanner/jdbc/JdbcConnection.java b/src/main/java/com/google/cloud/spanner/jdbc/JdbcConnection.java index bf9120f53..53c1dc096 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/JdbcConnection.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/JdbcConnection.java @@ -78,6 +78,38 @@ public String nativeSQL(String sql) throws SQLException { .sqlWithNamedParameters; } + @Override + public String getStatementTag() throws SQLException { + checkClosed(); + return getSpannerConnection().getStatementTag(); + } + + @Override + public void setStatementTag(String tag) throws SQLException { + checkClosed(); + try { + getSpannerConnection().setStatementTag(tag); + } catch (SpannerException e) { + throw JdbcSqlExceptionFactory.of(e); + } + } + + @Override + public String getTransactionTag() throws SQLException { + checkClosed(); + return getSpannerConnection().getTransactionTag(); + } + + @Override + public void setTransactionTag(String tag) throws SQLException { + checkClosed(); + try { + getSpannerConnection().setTransactionTag(tag); + } catch (SpannerException e) { + throw JdbcSqlExceptionFactory.of(e); + } + } + @Override public void setTransactionMode(TransactionMode mode) throws SQLException { checkClosed(); diff --git a/src/main/java/com/google/cloud/spanner/jdbc/JdbcDataType.java b/src/main/java/com/google/cloud/spanner/jdbc/JdbcDataType.java index 1dc5f0e49..8da36e4c4 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/JdbcDataType.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/JdbcDataType.java @@ -17,6 +17,7 @@ package com.google.cloud.spanner.jdbc; import com.google.cloud.spanner.ResultSet; +import com.google.cloud.spanner.Struct; import com.google.cloud.spanner.Type; import com.google.cloud.spanner.Type.Code; import java.math.BigDecimal; @@ -228,6 +229,32 @@ public Type getSpannerType() { return Type.string(); } }, + JSON { + @Override + public int getSqlType() { + return JsonType.VENDOR_TYPE_NUMBER; + } + + @Override + public Class getJavaClass() { + return String.class; + } + + @Override + public Code getCode() { + return Code.JSON; + } + + @Override + public List getArrayElements(ResultSet rs, int columnIndex) { + return rs.getJsonList(columnIndex); + } + + @Override + public Type getSpannerType() { + return Type.json(); + } + }, TIMESTAMP { @Override public int getSqlType() { @@ -253,6 +280,32 @@ public List getArrayElements(ResultSet rs, int columnIndex) { public Type getSpannerType() { return Type.timestamp(); } + }, + STRUCT { + @Override + public int getSqlType() { + return Types.STRUCT; + } + + @Override + public Class getJavaClass() { + return Struct.class; + } + + @Override + public Code getCode() { + return Code.STRUCT; + } + + @Override + public List getArrayElements(ResultSet rs, int columnIndex) { + return rs.getStructList(columnIndex); + } + + @Override + public Type getSpannerType() { + return Type.struct(); + } }; public abstract int getSqlType(); diff --git a/src/main/java/com/google/cloud/spanner/jdbc/JdbcDriver.java b/src/main/java/com/google/cloud/spanner/jdbc/JdbcDriver.java index dbb2df5ca..08dd5fafe 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/JdbcDriver.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/JdbcDriver.java @@ -76,14 +76,29 @@ *

  • credentials (String): URL for the credentials file to use for the connection. If you do not * specify any credentials at all, the default credentials of the environment as returned by * {@link GoogleCredentials#getApplicationDefault()} is used. + *
  • autocommit (boolean): Sets the initial autocommit mode for the connection. Default is true. + *
  • readonly (boolean): Sets the initial readonly mode for the connection. Default is false. + *
  • autoConfigEmulator (boolean): Automatically configure the connection to try to connect to + * the Cloud Spanner emulator. You do not need to specify any host or port in the connection + * string as long as the emulator is running on the default host/port (localhost:9010). The + * instance and database in the connection string will automatically be created if these do + * not yet exist on the emulator. This means that you do not need to execute any `gcloud` + * commands on the emulator to create the instance and database before you can connect to it. + *
  • usePlainText (boolean): Sets whether the JDBC connection should establish an unencrypted + * connection to the server. This option can only be used when connecting to a local emulator + * that does not require an encrypted connection, and that does not require authentication. + *
  • optimizerVersion (string): The query optimizer version to use for the connection. The value + * must be either a valid version number or LATEST. If no value is specified, the + * query optimizer version specified in the environment variable + * SPANNER_OPTIMIZER_VERSION is used. If no query optimizer version is specified in the + * connection URL or in the environment variable, the default query optimizer version of Cloud + * Spanner is used. *
  • oauthtoken (String): A valid OAuth2 token to use for the JDBC connection. The token must * have been obtained with one or both of the scopes * 'https://www.googleapis.com/auth/spanner.admin' and/or * 'https://www.googleapis.com/auth/spanner.data'. If you specify both a credentials file and * an OAuth token, the JDBC driver will throw an exception when you try to obtain a * connection. - *
  • autocommit (boolean): Sets the initial autocommit mode for the connection. Default is true. - *
  • readonly (boolean): Sets the initial readonly mode for the connection. Default is false. *
  • retryAbortsInternally (boolean): Sets the initial retryAbortsInternally mode for the * connection. Default is true. @see {@link * com.google.cloud.spanner.jdbc.CloudSpannerJdbcConnection#setRetryAbortsInternally(boolean)} @@ -93,15 +108,6 @@ *
  • maxSessions (int): Sets the maximum number of sessions in the backing session pool. * Defaults to 400. *
  • numChannels (int): Sets the number of gRPC channels to use. Defaults to 4. - *
  • usePlainText (boolean): Sets whether the JDBC connection should establish an unencrypted - * connection to the server. This option can only be used when connecting to a local emulator - * that does not require an encrypted connection, and that does not require authentication. - *
  • optimizerVersion (string): The query optimizer version to use for the connection. The value - * must be either a valid version number or LATEST. If no value is specified, the - * query optimizer version specified in the environment variable - * SPANNER_OPTIMIZER_VERSION is used. If no query optimizer version is specified in the - * connection URL or in the environment variable, the default query optimizer version of Cloud - * Spanner is used. * */ public class JdbcDriver implements Driver { diff --git a/src/main/java/com/google/cloud/spanner/jdbc/JdbcParameterStore.java b/src/main/java/com/google/cloud/spanner/jdbc/JdbcParameterStore.java index 2c529c4e7..24773cdce 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/JdbcParameterStore.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/JdbcParameterStore.java @@ -19,6 +19,8 @@ import com.google.cloud.ByteArray; import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.Statement.Builder; +import com.google.cloud.spanner.Type; +import com.google.cloud.spanner.Value; import com.google.cloud.spanner.ValueBinder; import com.google.cloud.spanner.jdbc.JdbcSqlExceptionFactory.JdbcSqlExceptionImpl; import com.google.common.io.CharStreams; @@ -39,6 +41,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.SQLType; import java.sql.Time; import java.sql.Timestamp; import java.sql.Types; @@ -129,7 +132,8 @@ void setColumn(int parameterIndex, String column) throws SQLException { getParameter(parameterIndex), getType(parameterIndex), getScaleOrLength(parameterIndex), - column); + column, + null); } void setType(int parameterIndex, Integer type) throws SQLException { @@ -138,26 +142,71 @@ void setType(int parameterIndex, Integer type) throws SQLException { getParameter(parameterIndex), type, getScaleOrLength(parameterIndex), - getColumn(parameterIndex)); + getColumn(parameterIndex), + null); } + /** Sets a parameter value. The type will be determined based on the type of the value. */ + void setParameter(int parameterIndex, Object value) throws SQLException { + setParameter(parameterIndex, value, null, null, null, null); + } + + /** Sets a parameter value as the specified vendor-specific {@link SQLType}. */ + void setParameter(int parameterIndex, Object value, SQLType sqlType) throws SQLException { + setParameter(parameterIndex, value, null, null, null, sqlType); + } + + /** + * Sets a parameter value as the specified vendor-specific {@link SQLType} with the specified + * scale or length. This method is only here to support the {@link + * PreparedStatement#setObject(int, Object, SQLType, int)} method. + */ + void setParameter(int parameterIndex, Object value, SQLType sqlType, Integer scaleOrLength) + throws SQLException { + setParameter(parameterIndex, value, null, scaleOrLength, null, sqlType); + } + + /** + * Sets a parameter value as the specified sql type. The type can be one of the constants in + * {@link Types} or a vendor specific type code supplied by a vendor specific {@link SQLType}. + */ void setParameter(int parameterIndex, Object value, Integer sqlType) throws SQLException { setParameter(parameterIndex, value, sqlType, null); } + /** + * Sets a parameter value as the specified sql type with the specified scale or length. The type + * can be one of the constants in {@link Types} or a vendor specific type code supplied by a + * vendor specific {@link SQLType}. + */ void setParameter(int parameterIndex, Object value, Integer sqlType, Integer scaleOrLength) throws SQLException { - setParameter(parameterIndex, value, sqlType, scaleOrLength, null); + setParameter(parameterIndex, value, sqlType, scaleOrLength, null, null); } + /** + * Sets a parameter value as the specified sql type with the specified scale or length. Any {@link + * SQLType} instance will take precedence over sqlType. The type can be one of the constants in + * {@link Types} or a vendor specific type code supplied by a vendor specific {@link SQLType}. + */ void setParameter( - int parameterIndex, Object value, Integer sqlType, Integer scaleOrLength, String column) + int parameterIndex, + Object value, + Integer sqlType, + Integer scaleOrLength, + String column, + SQLType sqlTypeObject) throws SQLException { - // check that only valid type/value combinations are entered - if (sqlType != null) { - checkTypeAndValueSupported(value, sqlType); - } - // set the parameter + // Ignore the sql type if the application has created a Spanner Value object. + if (!(value instanceof Value)) { + // check that only valid type/value combinations are entered + if (sqlTypeObject != null && sqlType == null) { + sqlType = sqlTypeObject.getVendorTypeNumber(); + } + if (sqlType != null) { + checkTypeAndValueSupported(value, sqlType); + } + } // set the parameter highestIndex = Math.max(parameterIndex, highestIndex); int arrayIndex = parameterIndex - 1; if (arrayIndex >= parametersList.size() || parametersList.get(arrayIndex) == null) { @@ -216,6 +265,7 @@ private boolean isTypeSupported(int sqlType) { case Types.NCLOB: case Types.NUMERIC: case Types.DECIMAL: + case JsonType.VENDOR_TYPE_NUMBER: return true; } return false; @@ -267,6 +317,11 @@ private boolean isValidTypeAndValue(Object value, int sqlType) { return value instanceof Clob || value instanceof Reader; case Types.NCLOB: return value instanceof NClob || value instanceof Reader; + case JsonType.VENDOR_TYPE_NUMBER: + return value instanceof String + || value instanceof InputStream + || value instanceof Reader + || (value instanceof Value && ((Value) value).getType().getCode() == Type.Code.JSON); } return false; } @@ -416,7 +471,11 @@ Builder bindParameterValue(ValueBinder binder, int index) throws SQLExc /** Set a value from a JDBC parameter on a Spanner {@link Statement}. */ Builder setValue(ValueBinder binder, Object value, Integer sqlType) throws SQLException { Builder res; - if (sqlType != null && sqlType == Types.ARRAY) { + if (value instanceof Value) { + // If a Value has been constructed, then that should override any sqlType that might have been + // supplied. + res = binder.to((Value) value); + } else if (sqlType != null && sqlType == Types.ARRAY) { if (value instanceof Array) { Array array = (Array) value; value = array.getArray(); @@ -492,30 +551,34 @@ private Builder setParamWithKnownType(ValueBinder binder, Object value, case Types.NCHAR: case Types.NVARCHAR: case Types.LONGNVARCHAR: + String stringValue; if (value instanceof String) { - return binder.to((String) value); + stringValue = (String) value; } else if (value instanceof InputStream) { - InputStreamReader reader = - new InputStreamReader((InputStream) value, StandardCharsets.US_ASCII); - try { - return binder.to(CharStreams.toString(reader)); - } catch (IOException e) { - throw JdbcSqlExceptionFactory.of( - "could not set string from input stream", Code.INVALID_ARGUMENT, e); - } + stringValue = getStringFromInputStream((InputStream) value); } else if (value instanceof Reader) { - try { - return binder.to(CharStreams.toString((Reader) value)); - } catch (IOException e) { - throw JdbcSqlExceptionFactory.of( - "could not set string from reader", Code.INVALID_ARGUMENT, e); - } + stringValue = getStringFromReader((Reader) value); } else if (value instanceof URL) { - return binder.to(((URL) value).toString()); + stringValue = ((URL) value).toString(); } else if (value instanceof UUID) { - return binder.to(((UUID) value).toString()); + stringValue = ((UUID) value).toString(); + } else { + throw JdbcSqlExceptionFactory.of(value + " is not a valid string", Code.INVALID_ARGUMENT); + } + return binder.to(stringValue); + case JsonType.VENDOR_TYPE_NUMBER: + String jsonValue; + if (value instanceof String) { + jsonValue = (String) value; + } else if (value instanceof InputStream) { + jsonValue = getStringFromInputStream((InputStream) value); + } else if (value instanceof Reader) { + jsonValue = getStringFromReader((Reader) value); + } else { + throw JdbcSqlExceptionFactory.of( + value + " is not a valid JSON value", Code.INVALID_ARGUMENT); } - throw JdbcSqlExceptionFactory.of(value + " is not a valid string", Code.INVALID_ARGUMENT); + return binder.to(Value.json(jsonValue)); case Types.DATE: if (value instanceof Date) { return binder.to(JdbcTypeConverter.toGoogleDate((Date) value)); @@ -600,6 +663,25 @@ private Builder setParamWithKnownType(ValueBinder binder, Object value, return null; } + private String getStringFromInputStream(InputStream inputStream) throws SQLException { + InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.US_ASCII); + try { + return CharStreams.toString(reader); + } catch (IOException e) { + throw JdbcSqlExceptionFactory.of( + "could not set string from input stream", Code.INVALID_ARGUMENT, e); + } + } + + private String getStringFromReader(Reader reader) throws SQLException { + try { + return CharStreams.toString(reader); + } catch (IOException e) { + throw JdbcSqlExceptionFactory.of( + "could not set string from reader", Code.INVALID_ARGUMENT, e); + } + } + /** Set the parameter value based purely on the type of the value. */ private Builder setParamWithUnknownType(ValueBinder binder, Object value) throws SQLException { @@ -717,14 +799,16 @@ private Builder setArrayValue(ValueBinder binder, int type, Object valu case Types.LONGNVARCHAR: case Types.CLOB: case Types.NCLOB: - return binder.toStringArray((Iterable) null); + return binder.toStringArray(null); + case JsonType.VENDOR_TYPE_NUMBER: + return binder.toJsonArray(null); case Types.DATE: - return binder.toDateArray((Iterable) null); + return binder.toDateArray(null); case Types.TIME: case Types.TIME_WITH_TIMEZONE: case Types.TIMESTAMP: case Types.TIMESTAMP_WITH_TIMEZONE: - return binder.toTimestampArray((Iterable) null); + return binder.toTimestampArray(null); case Types.BINARY: case Types.VARBINARY: case Types.LONGVARBINARY: @@ -777,7 +861,11 @@ private Builder setArrayValue(ValueBinder binder, int type, Object valu } else if (Timestamp[].class.isAssignableFrom(value.getClass())) { return binder.toTimestampArray(JdbcTypeConverter.toGoogleTimestamps((Timestamp[]) value)); } else if (String[].class.isAssignableFrom(value.getClass())) { - return binder.toStringArray(Arrays.asList((String[]) value)); + if (type == JsonType.VENDOR_TYPE_NUMBER) { + return binder.toJsonArray(Arrays.asList((String[]) value)); + } else { + return binder.toStringArray(Arrays.asList((String[]) value)); + } } else if (byte[][].class.isAssignableFrom(value.getClass())) { return binder.toBytesArray(JdbcTypeConverter.toGoogleBytes((byte[][]) value)); } diff --git a/src/main/java/com/google/cloud/spanner/jdbc/JdbcPreparedStatement.java b/src/main/java/com/google/cloud/spanner/jdbc/JdbcPreparedStatement.java index b0032e44e..919aad302 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/JdbcPreparedStatement.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/JdbcPreparedStatement.java @@ -24,6 +24,7 @@ import com.google.cloud.spanner.Type; import com.google.cloud.spanner.connection.StatementParser; import com.google.cloud.spanner.jdbc.JdbcParameterStore.ParametersInfo; +import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableList; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -48,7 +49,8 @@ ParametersInfo getParametersInfo() throws SQLException { return parameters; } - private Statement createStatement() throws SQLException { + @VisibleForTesting + Statement createStatement() throws SQLException { ParametersInfo paramInfo = getParametersInfo(); Statement.Builder builder = Statement.newBuilder(paramInfo.sqlWithNamedParameters); for (int index = 1; index <= getParameters().getHighestIndex(); index++) { diff --git a/src/main/java/com/google/cloud/spanner/jdbc/JdbcResultSet.java b/src/main/java/com/google/cloud/spanner/jdbc/JdbcResultSet.java index c4ca6b5e2..489c2d27f 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/JdbcResultSet.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/JdbcResultSet.java @@ -142,6 +142,8 @@ public String getString(int columnIndex) throws SQLException { return isNull ? null : spanner.getBigDecimal(spannerIndex).toString(); case STRING: return isNull ? null : spanner.getString(spannerIndex); + case JSON: + return isNull ? null : spanner.getJson(spannerIndex); case TIMESTAMP: return isNull ? null : spanner.getTimestamp(spannerIndex).toString(); case STRUCT: @@ -169,6 +171,7 @@ public boolean getBoolean(int columnIndex) throws SQLException { case STRING: return isNull ? false : Boolean.valueOf(spanner.getString(spannerIndex)); case BYTES: + case JSON: case DATE: case STRUCT: case TIMESTAMP: @@ -198,6 +201,7 @@ public byte getByte(int columnIndex) throws SQLException { case STRING: return isNull ? (byte) 0 : checkedCastToByte(parseLong(spanner.getString(spannerIndex))); case BYTES: + case JSON: case DATE: case STRUCT: case TIMESTAMP: @@ -227,6 +231,7 @@ public short getShort(int columnIndex) throws SQLException { case STRING: return isNull ? 0 : checkedCastToShort(parseLong(spanner.getString(spannerIndex))); case BYTES: + case JSON: case DATE: case STRUCT: case TIMESTAMP: @@ -256,6 +261,7 @@ public int getInt(int columnIndex) throws SQLException { case STRING: return isNull ? 0 : checkedCastToInt(parseLong(spanner.getString(spannerIndex))); case BYTES: + case JSON: case DATE: case STRUCT: case TIMESTAMP: @@ -283,6 +289,7 @@ public long getLong(int columnIndex) throws SQLException { case STRING: return isNull ? 0L : parseLong(spanner.getString(spannerIndex)); case BYTES: + case JSON: case DATE: case STRUCT: case TIMESTAMP: @@ -310,6 +317,7 @@ public float getFloat(int columnIndex) throws SQLException { case STRING: return isNull ? 0 : checkedCastToFloat(parseDouble(spanner.getString(spannerIndex))); case BYTES: + case JSON: case DATE: case STRUCT: case TIMESTAMP: @@ -337,6 +345,7 @@ public double getDouble(int columnIndex) throws SQLException { case STRING: return isNull ? 0 : parseDouble(spanner.getString(spannerIndex)); case BYTES: + case JSON: case DATE: case STRUCT: case TIMESTAMP: @@ -372,6 +381,7 @@ public Date getDate(int columnIndex) throws SQLException { case INT64: case NUMERIC: case BYTES: + case JSON: case STRUCT: case ARRAY: default: @@ -396,6 +406,7 @@ public Time getTime(int columnIndex) throws SQLException { case INT64: case NUMERIC: case BYTES: + case JSON: case STRUCT: case ARRAY: default: @@ -421,6 +432,7 @@ public Timestamp getTimestamp(int columnIndex) throws SQLException { case INT64: case NUMERIC: case BYTES: + case JSON: case STRUCT: case ARRAY: default: @@ -576,6 +588,7 @@ private Object getObject(Type type, int columnIndex) throws SQLException { if (type == Type.int64()) return getLong(columnIndex); if (type == Type.numeric()) return getBigDecimal(columnIndex); if (type == Type.string()) return getString(columnIndex); + if (type == Type.json()) return getString(columnIndex); if (type == Type.timestamp()) return getTimestamp(columnIndex); if (type.getCode() == Code.ARRAY) return getArray(columnIndex); throw JdbcSqlExceptionFactory.of( @@ -664,6 +677,7 @@ private BigDecimal getBigDecimal(int columnIndex, boolean fixedScale, int scale) e); } case BYTES: + case JSON: case DATE: case TIMESTAMP: case STRUCT: @@ -749,6 +763,7 @@ public Date getDate(int columnIndex, Calendar cal) throws SQLException { case INT64: case NUMERIC: case BYTES: + case JSON: case STRUCT: case ARRAY: default: @@ -778,6 +793,7 @@ public Time getTime(int columnIndex, Calendar cal) throws SQLException { case INT64: case NUMERIC: case BYTES: + case JSON: case STRUCT: case ARRAY: default: @@ -810,6 +826,7 @@ public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException case INT64: case NUMERIC: case BYTES: + case JSON: case STRUCT: case ARRAY: default: diff --git a/src/main/java/com/google/cloud/spanner/jdbc/JdbcTypeConverter.java b/src/main/java/com/google/cloud/spanner/jdbc/JdbcTypeConverter.java index c1f4b929d..40b7604f7 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/JdbcTypeConverter.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/JdbcTypeConverter.java @@ -21,6 +21,7 @@ import com.google.cloud.Timestamp; import com.google.cloud.spanner.Type; import com.google.cloud.spanner.Type.Code; +import com.google.cloud.spanner.Value; import java.math.BigDecimal; import java.math.BigInteger; import java.nio.charset.Charset; @@ -28,6 +29,7 @@ import java.sql.SQLException; import java.sql.Time; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.List; import java.util.concurrent.TimeUnit; @@ -59,8 +61,13 @@ static Object convert(Object value, Type type, Class targetType) throws SQLEx JdbcPreconditions.checkArgument(targetType != null, "targetType may not be null"); checkValidTypeAndValueForConvert(type, value); - if (value == null) return null; + if (value == null) { + return null; + } try { + if (targetType.equals(Value.class)) { + return convertToSpannerValue(value, type); + } if (targetType.equals(String.class)) { if (type.getCode() == Code.BYTES) return new String((byte[]) value, UTF8); if (type.getCode() == Code.TIMESTAMP) { @@ -74,7 +81,8 @@ static Object convert(Object value, Type type, Class targetType) throws SQLEx } if (targetType.equals(byte[].class)) { if (type.getCode() == Code.BYTES) return value; - if (type.getCode() == Code.STRING) return ((String) value).getBytes(UTF8); + if (type.getCode() == Code.STRING || type.getCode() == Code.JSON) + return ((String) value).getBytes(UTF8); } if (targetType.equals(Boolean.class)) { if (type.getCode() == Code.BOOL) return value; @@ -155,6 +163,58 @@ static Object convert(Object value, Type type, Class targetType) throws SQLEx com.google.rpc.Code.INVALID_ARGUMENT); } + private static Value convertToSpannerValue(Object value, Type type) throws SQLException { + switch (type.getCode()) { + case ARRAY: + switch (type.getArrayElementType().getCode()) { + case BOOL: + return Value.boolArray(Arrays.asList((Boolean[]) ((java.sql.Array) value).getArray())); + case BYTES: + return Value.bytesArray(toGoogleBytes((byte[][]) ((java.sql.Array) value).getArray())); + case DATE: + return Value.dateArray( + toGoogleDates((java.sql.Date[]) ((java.sql.Array) value).getArray())); + case FLOAT64: + return Value.float64Array( + Arrays.asList((Double[]) ((java.sql.Array) value).getArray())); + case INT64: + return Value.int64Array(Arrays.asList((Long[]) ((java.sql.Array) value).getArray())); + case NUMERIC: + return Value.numericArray( + Arrays.asList((BigDecimal[]) ((java.sql.Array) value).getArray())); + case STRING: + return Value.stringArray(Arrays.asList((String[]) ((java.sql.Array) value).getArray())); + case TIMESTAMP: + return Value.timestampArray( + toGoogleTimestamps((java.sql.Timestamp[]) ((java.sql.Array) value).getArray())); + case STRUCT: + default: + throw JdbcSqlExceptionFactory.of( + "invalid argument: " + value, com.google.rpc.Code.INVALID_ARGUMENT); + } + case BOOL: + return Value.bool((Boolean) value); + case BYTES: + return Value.bytes(ByteArray.copyFrom((byte[]) value)); + case DATE: + return Value.date(toGoogleDate((java.sql.Date) value)); + case FLOAT64: + return Value.float64((Double) value); + case INT64: + return Value.int64((Long) value); + case NUMERIC: + return Value.numeric((BigDecimal) value); + case STRING: + return Value.string((String) value); + case TIMESTAMP: + return Value.timestamp(toGoogleTimestamp((java.sql.Timestamp) value)); + case STRUCT: + default: + throw JdbcSqlExceptionFactory.of( + "invalid argument: " + value, com.google.rpc.Code.INVALID_ARGUMENT); + } + } + private static void checkValidTypeAndValueForConvert(Type type, Object value) throws SQLException { if (value == null) return; diff --git a/src/main/java/com/google/cloud/spanner/jdbc/JsonType.java b/src/main/java/com/google/cloud/spanner/jdbc/JsonType.java new file mode 100644 index 000000000..44af26b6e --- /dev/null +++ b/src/main/java/com/google/cloud/spanner/jdbc/JsonType.java @@ -0,0 +1,55 @@ +/* + * Copyright 2021 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 + * + * http://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. + */ + +package com.google.cloud.spanner.jdbc; + +import com.google.spanner.v1.TypeCode; +import java.sql.PreparedStatement; +import java.sql.SQLType; + +/** + * Custom SQL type for Spanner JSON data type. This type (or the vendor type number) must be used + * when setting a JSON parameter using {@link PreparedStatement#setObject(int, Object, SQLType)}. + */ +public class JsonType implements SQLType { + public static final JsonType INSTANCE = new JsonType(); + /** + * Spanner does not have any type numbers, but the code values are unique. Add 100,000 to avoid + * conflicts with the type numbers in java.sql.Types. + */ + public static final int VENDOR_TYPE_NUMBER = 100_000 + TypeCode.JSON_VALUE; + + private JsonType() {} + + @Override + public String getName() { + return "JSON"; + } + + @Override + public String getVendor() { + return JsonType.class.getPackage().getName(); + } + + @Override + public Integer getVendorTypeNumber() { + return VENDOR_TYPE_NUMBER; + } + + public String toString() { + return getName(); + } +} diff --git a/src/main/resources/com/google/cloud/spanner/jdbc/ClientSideStatements.json b/src/main/resources/com/google/cloud/spanner/jdbc/ClientSideStatements.json deleted file mode 100644 index 8d8cca207..000000000 --- a/src/main/resources/com/google/cloud/spanner/jdbc/ClientSideStatements.json +++ /dev/null @@ -1,268 +0,0 @@ -{ -"statements": - [ - { - "name": "SHOW VARIABLE AUTOCOMMIT", - "executorName": "ClientSideStatementNoParamExecutor", - "resultType": "RESULT_SET", - "regex": "(?is)\\A\\s*show\\s+variable\\s+autocommit\\s*\\z", - "method": "statementShowAutocommit", - "exampleStatements": ["show variable autocommit"] - }, - { - "name": "SHOW VARIABLE READONLY", - "executorName": "ClientSideStatementNoParamExecutor", - "resultType": "RESULT_SET", - "regex": "(?is)\\A\\s*show\\s+variable\\s+readonly\\s*\\z", - "method": "statementShowReadOnly", - "exampleStatements": ["show variable readonly"] - }, - { - "name": "SHOW VARIABLE RETRY_ABORTS_INTERNALLY", - "executorName": "ClientSideStatementNoParamExecutor", - "resultType": "RESULT_SET", - "regex": "(?is)\\A\\s*show\\s+variable\\s+retry_aborts_internally\\s*\\z", - "method": "statementShowRetryAbortsInternally", - "exampleStatements": ["show variable retry_aborts_internally"], - "examplePrerequisiteStatements": ["set readonly=false", "set autocommit=false"] - }, - { - "name": "SHOW VARIABLE AUTOCOMMIT_DML_MODE", - "executorName": "ClientSideStatementNoParamExecutor", - "resultType": "RESULT_SET", - "regex": "(?is)\\A\\s*show\\s+variable\\s+autocommit_dml_mode\\s*\\z", - "method": "statementShowAutocommitDmlMode", - "exampleStatements": ["show variable autocommit_dml_mode"] - }, - { - "name": "SHOW VARIABLE STATEMENT_TIMEOUT", - "executorName": "ClientSideStatementNoParamExecutor", - "resultType": "RESULT_SET", - "regex": "(?is)\\A\\s*show\\s+variable\\s+statement_timeout\\s*\\z", - "method": "statementShowStatementTimeout", - "exampleStatements": ["show variable statement_timeout"] - }, - { - "name": "SHOW VARIABLE READ_TIMESTAMP", - "executorName": "ClientSideStatementNoParamExecutor", - "resultType": "RESULT_SET", - "regex": "(?is)\\A\\s*show\\s+variable\\s+read_timestamp\\s*\\z", - "method": "statementShowReadTimestamp", - "exampleStatements": ["show variable read_timestamp"], - "examplePrerequisiteStatements": ["set readonly = true", "SELECT 1 AS TEST"] - }, - { - "name": "SHOW VARIABLE COMMIT_TIMESTAMP", - "executorName": "ClientSideStatementNoParamExecutor", - "resultType": "RESULT_SET", - "regex": "(?is)\\A\\s*show\\s+variable\\s+commit_timestamp\\s*\\z", - "method": "statementShowCommitTimestamp", - "exampleStatements": ["show variable commit_timestamp"], - "examplePrerequisiteStatements": ["update foo set bar=1"] - }, - { - "name": "SHOW VARIABLE READ_ONLY_STALENESS", - "executorName": "ClientSideStatementNoParamExecutor", - "resultType": "RESULT_SET", - "regex": "(?is)\\A\\s*show\\s+variable\\s+read_only_staleness\\s*\\z", - "method": "statementShowReadOnlyStaleness", - "exampleStatements": ["show variable read_only_staleness"] - }, - { - "name": "SHOW VARIABLE OPTIMIZER_VERSION", - "executorName": "ClientSideStatementNoParamExecutor", - "resultType": "RESULT_SET", - "regex": "(?is)\\A\\s*show\\s+variable\\s+optimizer_version\\s*\\z", - "method": "statementShowOptimizerVersion", - "exampleStatements": ["show variable optimizer_version"] - }, - { - "name": "BEGIN TRANSACTION", - "executorName": "ClientSideStatementNoParamExecutor", - "resultType": "NO_RESULT", - "regex": "(?is)\\A\\s*(?:begin|start)(?:\\s+transaction)?\\s*\\z", - "method": "statementBeginTransaction", - "exampleStatements": ["begin", "start", "begin transaction", "start transaction"] - }, - { - "name": "COMMIT TRANSACTION", - "executorName": "ClientSideStatementNoParamExecutor", - "resultType": "NO_RESULT", - "regex": "(?is)\\A\\s*(?:commit)(?:\\s+transaction)?\\s*\\z", - "method": "statementCommit", - "exampleStatements": ["commit", "commit transaction"], - "examplePrerequisiteStatements": ["begin transaction"] - }, - { - "name": "ROLLBACK TRANSACTION", - "executorName": "ClientSideStatementNoParamExecutor", - "resultType": "NO_RESULT", - "regex": "(?is)\\A\\s*(?:rollback)(?:\\s+transaction)?\\s*\\z", - "method": "statementRollback", - "exampleStatements": ["rollback", "rollback transaction"], - "examplePrerequisiteStatements": ["begin transaction"] - }, - { - "name": "START BATCH DDL", - "executorName": "ClientSideStatementNoParamExecutor", - "resultType": "NO_RESULT", - "regex": "(?is)\\A\\s*(?:start)(?:\\s+batch)(?:\\s+ddl)\\s*\\z", - "method": "statementStartBatchDdl", - "exampleStatements": ["start batch ddl"] - }, - { - "name": "START BATCH DML", - "executorName": "ClientSideStatementNoParamExecutor", - "resultType": "NO_RESULT", - "regex": "(?is)\\A\\s*(?:start)(?:\\s+batch)(?:\\s+dml)\\s*\\z", - "method": "statementStartBatchDml", - "exampleStatements": ["start batch dml"] - }, - { - "name": "RUN BATCH", - "executorName": "ClientSideStatementNoParamExecutor", - "resultType": "NO_RESULT", - "regex": "(?is)\\A\\s*(?:run)(?:\\s+batch)\\s*\\z", - "method": "statementRunBatch", - "exampleStatements": ["run batch"], - "examplePrerequisiteStatements": ["start batch ddl"] - }, - { - "name": "ABORT BATCH", - "executorName": "ClientSideStatementNoParamExecutor", - "resultType": "NO_RESULT", - "regex": "(?is)\\A\\s*(?:abort)(?:\\s+batch)\\s*\\z", - "method": "statementAbortBatch", - "exampleStatements": ["abort batch"], - "examplePrerequisiteStatements": ["start batch ddl"] - }, - { - "name": "SET AUTOCOMMIT = TRUE|FALSE", - "executorName": "ClientSideStatementSetExecutor", - "resultType": "NO_RESULT", - "regex": "(?is)\\A\\s*set\\s+autocommit\\s*(?:=)\\s*(.*)\\z", - "method": "statementSetAutocommit", - "exampleStatements": ["set autocommit = true", "set autocommit = false"], - "setStatement": { - "propertyName": "AUTOCOMMIT", - "separator": "=", - "allowedValues": "(TRUE|FALSE)", - "converterName": "ClientSideStatementValueConverters$BooleanConverter" - } - }, - { - "name": "SET READONLY = TRUE|FALSE", - "executorName": "ClientSideStatementSetExecutor", - "resultType": "NO_RESULT", - "regex": "(?is)\\A\\s*set\\s+readonly\\s*(?:=)\\s*(.*)\\z", - "method": "statementSetReadOnly", - "exampleStatements": ["set readonly = true", "set readonly = false"], - "setStatement": { - "propertyName": "READONLY", - "separator": "=", - "allowedValues": "(TRUE|FALSE)", - "converterName": "ClientSideStatementValueConverters$BooleanConverter" - } - }, - { - "name": "SET RETRY_ABORTS_INTERNALLY = TRUE|FALSE", - "executorName": "ClientSideStatementSetExecutor", - "resultType": "NO_RESULT", - "regex": "(?is)\\A\\s*set\\s+retry_aborts_internally\\s*(?:=)\\s*(.*)\\z", - "method": "statementSetRetryAbortsInternally", - "exampleStatements": ["set retry_aborts_internally = true", "set retry_aborts_internally = false"], - "examplePrerequisiteStatements": ["set readonly = false", "set autocommit = false"], - "setStatement": { - "propertyName": "RETRY_ABORTS_INTERNALLY", - "separator": "=", - "allowedValues": "(TRUE|FALSE)", - "converterName": "ClientSideStatementValueConverters$BooleanConverter" - } - }, - { - "name": "SET AUTOCOMMIT_DML_MODE = 'PARTITIONED_NON_ATOMIC'|'TRANSACTIONAL'", - "executorName": "ClientSideStatementSetExecutor", - "resultType": "NO_RESULT", - "regex": "(?is)\\A\\s*set\\s+autocommit_dml_mode\\s*(?:=)\\s*(.*)\\z", - "method": "statementSetAutocommitDmlMode", - "exampleStatements": ["set autocommit_dml_mode='PARTITIONED_NON_ATOMIC'", "set autocommit_dml_mode='TRANSACTIONAL'"], - "setStatement": { - "propertyName": "AUTOCOMMIT_DML_MODE", - "separator": "=", - "allowedValues": "'(PARTITIONED_NON_ATOMIC|TRANSACTIONAL)'", - "converterName": "ClientSideStatementValueConverters$AutocommitDmlModeConverter" - } - }, - { - "name": "SET STATEMENT_TIMEOUT = ''|NULL", - "executorName": "ClientSideStatementSetExecutor", - "resultType": "NO_RESULT", - "regex": "(?is)\\A\\s*set\\s+statement_timeout\\s*(?:=)\\s*(.*)\\z", - "method": "statementSetStatementTimeout", - "exampleStatements": ["set statement_timeout=null", "set statement_timeout='1s'", "set statement_timeout='100ms'", "set statement_timeout='10000us'", "set statement_timeout='9223372036854775807ns'"], - "setStatement": { - "propertyName": "STATEMENT_TIMEOUT", - "separator": "=", - "allowedValues": "('(\\d{1,19})(s|ms|us|ns)'|NULL)", - "converterName": "ClientSideStatementValueConverters$DurationConverter" - } - }, - { - "name": "SET TRANSACTION READ ONLY|READ WRITE", - "executorName": "ClientSideStatementSetExecutor", - "resultType": "NO_RESULT", - "regex": "(?is)\\A\\s*set\\s+transaction\\s*(?:\\s+)\\s*(.*)\\z", - "method": "statementSetTransactionMode", - "exampleStatements": ["set transaction read only", "set transaction read write"], - "examplePrerequisiteStatements": ["set autocommit = false"], - "setStatement": { - "propertyName": "TRANSACTION", - "separator": "\\s+", - "allowedValues": "(READ\\s+ONLY|READ\\s+WRITE)", - "converterName": "ClientSideStatementValueConverters$TransactionModeConverter" - } - }, - { - "name": "SET READ_ONLY_STALENESS = 'STRONG' | 'MIN_READ_TIMESTAMP ' | 'READ_TIMESTAMP ' | 'MAX_STALENESS s|ms|us|ns' | 'EXACT_STALENESS (s|ms|us|ns)'", - "executorName": "ClientSideStatementSetExecutor", - "resultType": "NO_RESULT", - "regex": "(?is)\\A\\s*set\\s+read_only_staleness\\s*(?:=)\\s*(.*)\\z", - "method": "statementSetReadOnlyStaleness", - "exampleStatements": ["set read_only_staleness='STRONG'", - "set read_only_staleness='MIN_READ_TIMESTAMP 2018-01-02T03:04:05.123-08:00'", - "set read_only_staleness='MIN_READ_TIMESTAMP 2018-01-02T03:04:05.123Z'", - "set read_only_staleness='MIN_READ_TIMESTAMP 2018-01-02T03:04:05.123+07:45'", - "set read_only_staleness='READ_TIMESTAMP 2018-01-02T03:04:05.54321-07:00'", - "set read_only_staleness='READ_TIMESTAMP 2018-01-02T03:04:05.54321Z'", - "set read_only_staleness='READ_TIMESTAMP 2018-01-02T03:04:05.54321+05:30'", - "set read_only_staleness='MAX_STALENESS 12s'", - "set read_only_staleness='MAX_STALENESS 100ms'", - "set read_only_staleness='MAX_STALENESS 99999us'", - "set read_only_staleness='MAX_STALENESS 10ns'", - "set read_only_staleness='EXACT_STALENESS 15s'", - "set read_only_staleness='EXACT_STALENESS 1500ms'", - "set read_only_staleness='EXACT_STALENESS 15000000us'", - "set read_only_staleness='EXACT_STALENESS 9999ns'"], - "setStatement": { - "propertyName": "READ_ONLY_STALENESS", - "separator": "=", - "allowedValues": "'((STRONG)|(MIN_READ_TIMESTAMP)[\\t ]+((\\d{4})-(\\d{2})-(\\d{2})([Tt](\\d{2}):(\\d{2}):(\\d{2})(\\.\\d{1,9})?)([Zz]|([+-])(\\d{2}):(\\d{2})))|(READ_TIMESTAMP)[\\t ]+((\\d{4})-(\\d{2})-(\\d{2})([Tt](\\d{2}):(\\d{2}):(\\d{2})(\\.\\d{1,9})?)([Zz]|([+-])(\\d{2}):(\\d{2})))|(MAX_STALENESS)[\\t ]+((\\d{1,19})(s|ms|us|ns))|(EXACT_STALENESS)[\\t ]+((\\d{1,19})(s|ms|us|ns)))'", - "converterName": "ClientSideStatementValueConverters$ReadOnlyStalenessConverter" - } - }, - { - "name": "SET OPTIMIZER_VERSION = ''|'LATEST'|''", - "executorName": "ClientSideStatementSetExecutor", - "resultType": "NO_RESULT", - "regex": "(?is)\\A\\s*set\\s+optimizer_version\\s*(?:=)\\s*(.*)\\z", - "method": "statementSetOptimizerVersion", - "exampleStatements": ["set optimizer_version='1'", "set optimizer_version='200'", "set optimizer_version='LATEST'", "set optimizer_version=''"], - "setStatement": { - "propertyName": "OPTIMIZER_VERSION", - "separator": "=", - "allowedValues": "'((\\d{1,20})|(LATEST)|())'", - "converterName": "ClientSideStatementValueConverters$StringValueConverter" - } - } - ] -} \ No newline at end of file diff --git a/src/main/resources/com/google/cloud/spanner/jdbc/DatabaseMetaData_GetColumns.sql b/src/main/resources/com/google/cloud/spanner/jdbc/DatabaseMetaData_GetColumns.sql index 69b1f6a8e..14106ee1e 100644 --- a/src/main/resources/com/google/cloud/spanner/jdbc/DatabaseMetaData_GetColumns.sql +++ b/src/main/resources/com/google/cloud/spanner/jdbc/DatabaseMetaData_GetColumns.sql @@ -24,6 +24,7 @@ SELECT TABLE_CATALOG AS TABLE_CAT, TABLE_SCHEMA AS TABLE_SCHEM, TABLE_NAME, COLU WHEN SPANNER_TYPE = 'INT64' THEN -5 WHEN SPANNER_TYPE = 'NUMERIC' THEN 2 WHEN SPANNER_TYPE LIKE 'STRING%' THEN -9 + WHEN SPANNER_TYPE = 'JSON' THEN -9 WHEN SPANNER_TYPE = 'TIMESTAMP' THEN 93 END AS DATA_TYPE, SPANNER_TYPE AS TYPE_NAME, @@ -36,6 +37,7 @@ SELECT TABLE_CATALOG AS TABLE_CAT, TABLE_SCHEMA AS TABLE_SCHEM, TABLE_NAME, COLU WHEN SPANNER_TYPE = 'BOOL' OR SPANNER_TYPE = 'ARRAY' THEN NULL WHEN SPANNER_TYPE = 'DATE' OR SPANNER_TYPE = 'ARRAY' THEN 10 WHEN SPANNER_TYPE = 'TIMESTAMP' OR SPANNER_TYPE = 'ARRAY' THEN 35 + WHEN SPANNER_TYPE = 'JSON' OR SPANNER_TYPE = 'ARRAY' THEN 2621440 ELSE 0 END ELSE CAST(REPLACE(SUBSTR(SPANNER_TYPE, STRPOS(SPANNER_TYPE, '(')+1, STRPOS(SPANNER_TYPE, ')')-STRPOS(SPANNER_TYPE, '(')-1), 'MAX', CASE WHEN UPPER(SPANNER_TYPE) LIKE '%STRING%' THEN '2621440' ELSE '10485760' END) AS INT64) @@ -63,6 +65,7 @@ SELECT TABLE_CATALOG AS TABLE_CAT, TABLE_SCHEMA AS TABLE_SCHEM, TABLE_NAME, COLU CASE WHEN (SPANNER_TYPE LIKE 'STRING%' OR SPANNER_TYPE LIKE 'ARRAY array.getResultSet()); } @Test diff --git a/src/test/java/com/google/cloud/spanner/jdbc/JdbcParameterStoreTest.java b/src/test/java/com/google/cloud/spanner/jdbc/JdbcParameterStoreTest.java index 7f6860138..9d12b1b05 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/JdbcParameterStoreTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/JdbcParameterStoreTest.java @@ -44,6 +44,7 @@ import java.sql.Timestamp; import java.sql.Types; import java.util.Arrays; +import java.util.Collections; import java.util.UUID; import org.junit.Test; import org.junit.runner.RunWith; @@ -52,6 +53,61 @@ @RunWith(JUnit4.class) public class JdbcParameterStoreTest { + /** + * Tests setting a {@link Value} as a parameter value. + * + * @throws SQLException + */ + @Test + public void testSetValueAsParameter() throws SQLException { + JdbcParameterStore params = new JdbcParameterStore(); + params.setParameter(1, Value.bool(true)); + verifyParameter(params, Value.bool(true)); + params.setParameter(1, Value.bytes(ByteArray.copyFrom("test"))); + verifyParameter(params, Value.bytes(ByteArray.copyFrom("test"))); + params.setParameter(1, Value.date(com.google.cloud.Date.fromYearMonthDay(2021, 5, 3))); + verifyParameter(params, Value.date(com.google.cloud.Date.fromYearMonthDay(2021, 5, 3))); + params.setParameter(1, Value.float64(3.14d)); + verifyParameter(params, Value.float64(3.14d)); + params.setParameter(1, Value.int64(1L)); + verifyParameter(params, Value.int64(1L)); + params.setParameter(1, Value.numeric(BigDecimal.TEN)); + verifyParameter(params, Value.numeric(BigDecimal.TEN)); + params.setParameter(1, Value.string("test")); + verifyParameter(params, Value.string("test")); + params.setParameter( + 1, Value.timestamp(com.google.cloud.Timestamp.ofTimeSecondsAndNanos(9999L, 101))); + verifyParameter( + params, Value.timestamp(com.google.cloud.Timestamp.ofTimeSecondsAndNanos(9999L, 101))); + + params.setParameter(1, Value.boolArray(new boolean[] {true, false})); + verifyParameter(params, Value.boolArray(new boolean[] {true, false})); + params.setParameter(1, Value.bytesArray(Collections.singleton(ByteArray.copyFrom("test")))); + verifyParameter(params, Value.bytesArray(Collections.singleton(ByteArray.copyFrom("test")))); + params.setParameter( + 1, + Value.dateArray(Collections.singleton(com.google.cloud.Date.fromYearMonthDay(2021, 5, 3)))); + verifyParameter( + params, + Value.dateArray(Collections.singleton(com.google.cloud.Date.fromYearMonthDay(2021, 5, 3)))); + params.setParameter(1, Value.float64Array(Collections.singleton(3.14d))); + verifyParameter(params, Value.float64Array(Collections.singleton(3.14d))); + params.setParameter(1, Value.int64Array(Collections.singleton(1L))); + verifyParameter(params, Value.int64Array(Collections.singleton(1L))); + params.setParameter(1, Value.numericArray(Collections.singleton(BigDecimal.TEN))); + verifyParameter(params, Value.numericArray(Collections.singleton(BigDecimal.TEN))); + params.setParameter(1, Value.stringArray(Collections.singleton("test"))); + verifyParameter(params, Value.stringArray(Collections.singleton("test"))); + params.setParameter( + 1, + Value.timestampArray( + Collections.singleton(com.google.cloud.Timestamp.ofTimeSecondsAndNanos(9999L, 101)))); + verifyParameter( + params, + Value.timestampArray( + Collections.singleton(com.google.cloud.Timestamp.ofTimeSecondsAndNanos(9999L, 101)))); + } + /** Tests setting a parameter value together with a sql type */ @SuppressWarnings("deprecation") @Test @@ -125,6 +181,15 @@ public void testSetParameterWithType() throws SQLException, IOException { assertTrue(stringReadersEqual((StringReader) params.getParameter(1), new StringReader("test"))); verifyParameter(params, Value.string("test")); + String jsonString = "{\"test\": \"value\"}"; + params.setParameter(1, jsonString, JsonType.VENDOR_TYPE_NUMBER); + assertEquals(jsonString, params.getParameter(1)); + verifyParameter(params, Value.json(jsonString)); + + params.setParameter(1, jsonString, JsonType.INSTANCE); + assertEquals(jsonString, params.getParameter(1)); + verifyParameter(params, Value.json(jsonString)); + params.setParameter(1, BigDecimal.ONE, Types.DECIMAL); verifyParameter(params, Value.numeric(BigDecimal.ONE)); @@ -360,7 +425,8 @@ public void testSetInvalidParameterWithType() throws SQLException, IOException { Types.LONGVARCHAR, Types.NCHAR, Types.NVARCHAR, - Types.LONGNVARCHAR + Types.LONGNVARCHAR, + JsonType.VENDOR_TYPE_NUMBER }) { assertInvalidParameter(params, new Object(), type); assertInvalidParameter(params, Boolean.TRUE, type); @@ -385,7 +451,8 @@ public void testSetInvalidParameterWithType() throws SQLException, IOException { Types.LONGVARCHAR, Types.NCHAR, Types.NVARCHAR, - Types.LONGNVARCHAR + Types.LONGNVARCHAR, + JsonType.VENDOR_TYPE_NUMBER }) { Reader reader = new StringReader("test"); reader.close(); @@ -422,57 +489,62 @@ private void assertInvalidParameter(JdbcParameterStore params, Object value, int @Test public void testSetParameterWithoutType() throws SQLException { JdbcParameterStore params = new JdbcParameterStore(); - params.setParameter(1, (byte) 1, null); + params.setParameter(1, (byte) 1, (Integer) null); assertEquals(1, ((Byte) params.getParameter(1)).byteValue()); verifyParameter(params, Value.int64(1)); - params.setParameter(1, (short) 1, null); + params.setParameter(1, (short) 1, (Integer) null); assertEquals(1, ((Short) params.getParameter(1)).shortValue()); verifyParameter(params, Value.int64(1)); - params.setParameter(1, 1, null); + params.setParameter(1, 1, (Integer) null); assertEquals(1, ((Integer) params.getParameter(1)).intValue()); verifyParameter(params, Value.int64(1)); - params.setParameter(1, 1L, null); + params.setParameter(1, 1L, (Integer) null); assertEquals(1, ((Long) params.getParameter(1)).longValue()); verifyParameter(params, Value.int64(1)); - params.setParameter(1, (float) 1, null); + params.setParameter(1, (float) 1, (Integer) null); assertEquals(1.0f, ((Float) params.getParameter(1)).floatValue(), 0.0f); verifyParameter(params, Value.float64(1)); - params.setParameter(1, (double) 1, null); + params.setParameter(1, (double) 1, (Integer) null); assertEquals(1.0d, ((Double) params.getParameter(1)).doubleValue(), 0.0d); verifyParameter(params, Value.float64(1)); - params.setParameter(1, new Date(1970 - 1900, 0, 1), null); + params.setParameter(1, new Date(1970 - 1900, 0, 1), (Integer) null); assertEquals(new Date(1970 - 1900, 0, 1), params.getParameter(1)); verifyParameter(params, Value.date(com.google.cloud.Date.fromYearMonthDay(1970, 1, 1))); - params.setParameter(1, new Time(0L), null); + params.setParameter(1, new Time(0L), (Integer) null); assertEquals(new Time(0L), params.getParameter(1)); verifyParameter( params, Value.timestamp(com.google.cloud.Timestamp.ofTimeSecondsAndNanos(0L, 0))); - params.setParameter(1, new Timestamp(0L), null); + params.setParameter(1, new Timestamp(0L), (Integer) null); assertEquals(new Timestamp(0L), params.getParameter(1)); verifyParameter( params, Value.timestamp(com.google.cloud.Timestamp.ofTimeSecondsAndNanos(0L, 0))); - params.setParameter(1, new byte[] {1, 2, 3}, null); + params.setParameter(1, new byte[] {1, 2, 3}, (Integer) null); assertArrayEquals(new byte[] {1, 2, 3}, (byte[]) params.getParameter(1)); verifyParameter(params, Value.bytes(ByteArray.copyFrom(new byte[] {1, 2, 3}))); - params.setParameter(1, new JdbcBlob(new byte[] {1, 2, 3}), null); + params.setParameter(1, new JdbcBlob(new byte[] {1, 2, 3}), (Integer) null); assertEquals(new JdbcBlob(new byte[] {1, 2, 3}), params.getParameter(1)); verifyParameter(params, Value.bytes(ByteArray.copyFrom(new byte[] {1, 2, 3}))); - params.setParameter(1, new JdbcClob("test"), null); + params.setParameter(1, new JdbcClob("test"), (Integer) null); assertEquals(new JdbcClob("test"), params.getParameter(1)); verifyParameter(params, Value.string("test")); - params.setParameter(1, true, null); + params.setParameter(1, true, (Integer) null); assertTrue((Boolean) params.getParameter(1)); verifyParameter(params, Value.bool(true)); - params.setParameter(1, "test", null); + params.setParameter(1, "test", (Integer) null); assertEquals("test", params.getParameter(1)); verifyParameter(params, Value.string("test")); - params.setParameter(1, new JdbcClob("test"), null); + params.setParameter(1, new JdbcClob("test"), (Integer) null); assertEquals(new JdbcClob("test"), params.getParameter(1)); verifyParameter(params, Value.string("test")); - params.setParameter(1, UUID.fromString("83b988cf-1f4e-428a-be3d-cc712621942e"), null); + params.setParameter(1, UUID.fromString("83b988cf-1f4e-428a-be3d-cc712621942e"), (Integer) null); assertEquals(UUID.fromString("83b988cf-1f4e-428a-be3d-cc712621942e"), params.getParameter(1)); verifyParameter(params, Value.string("83b988cf-1f4e-428a-be3d-cc712621942e")); + + String jsonString = "{\"test\": \"value\"}"; + params.setParameter(1, Value.json(jsonString), (Integer) null); + assertEquals(Value.json(jsonString), params.getParameter(1)); + verifyParameter(params, Value.json(jsonString)); } private boolean stringReadersEqual(StringReader r1, StringReader r2) throws IOException { @@ -627,6 +699,26 @@ public void testSetArrayParameter() throws SQLException { params.setParameter(1, JdbcArray.createArray("STRING", null), Types.ARRAY); assertEquals(JdbcArray.createArray("STRING", null), params.getParameter(1)); verifyParameter(params, Value.stringArray(null)); + + String jsonString1 = "{\"test\": \"value1\"}"; + String jsonString2 = "{\"test\": \"value2\"}"; + params.setParameter( + 1, + JdbcArray.createArray("JSON", new String[] {jsonString1, jsonString2, null}), + Types.ARRAY); + assertEquals( + JdbcArray.createArray("JSON", new String[] {jsonString1, jsonString2, null}), + params.getParameter(1)); + verifyParameter(params, Value.jsonArray(Arrays.asList(jsonString1, jsonString2, null))); + + params.setParameter(1, JdbcArray.createArray("JSON", null), Types.ARRAY); + assertEquals(JdbcArray.createArray("JSON", null), params.getParameter(1)); + verifyParameter(params, Value.jsonArray(null)); + + params.setParameter(1, Value.jsonArray(Arrays.asList(jsonString1, jsonString2, null))); + assertEquals( + Value.jsonArray(Arrays.asList(jsonString1, jsonString2, null)), params.getParameter(1)); + verifyParameter(params, Value.jsonArray(Arrays.asList(jsonString1, jsonString2, null))); } private void verifyParameter(JdbcParameterStore params, Value value) throws SQLException { diff --git a/src/test/java/com/google/cloud/spanner/jdbc/JdbcPreparedStatementTest.java b/src/test/java/com/google/cloud/spanner/jdbc/JdbcPreparedStatementTest.java index b19aa54c1..40ad1ad01 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/JdbcPreparedStatementTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/JdbcPreparedStatementTest.java @@ -25,6 +25,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import com.google.cloud.ByteArray; import com.google.cloud.spanner.ReadContext.QueryAnalyzeMode; import com.google.cloud.spanner.ResultSet; import com.google.cloud.spanner.ResultSets; @@ -32,10 +33,12 @@ import com.google.cloud.spanner.Struct; import com.google.cloud.spanner.Type; import com.google.cloud.spanner.Type.StructField; +import com.google.cloud.spanner.Value; import com.google.cloud.spanner.connection.Connection; import com.google.rpc.Code; import java.io.ByteArrayInputStream; import java.io.StringReader; +import java.math.BigDecimal; import java.net.MalformedURLException; import java.net.URL; import java.sql.Date; @@ -51,6 +54,7 @@ import java.sql.Types; import java.util.Arrays; import java.util.Calendar; +import java.util.Collections; import java.util.TimeZone; import java.util.UUID; import org.junit.Test; @@ -99,6 +103,41 @@ private JdbcConnection createMockConnection(Connection spanner) throws SQLExcept return connection; } + @Test + public void testValueAsParameter() throws SQLException { + String sql = generateSqlWithParameters(1); + JdbcConnection connection = createMockConnection(); + for (Value value : + new Value[] { + Value.bool(true), + Value.bool(false), + Value.bytes(ByteArray.copyFrom("foo")), + Value.date(com.google.cloud.Date.fromYearMonthDay(2021, 5, 17)), + Value.float64(6.626d), + Value.int64(13L), + Value.numeric(new BigDecimal("3.14")), + Value.string("bar"), + Value.timestamp(com.google.cloud.Timestamp.ofTimeSecondsAndNanos(999L, 99)), + Value.boolArray(Collections.singleton(true)), + Value.bytesArray(Collections.singleton(ByteArray.copyFrom("foo"))), + Value.dateArray( + Collections.singleton(com.google.cloud.Date.fromYearMonthDay(2021, 5, 17))), + Value.float64Array(Collections.singleton(6.626d)), + Value.int64Array(Collections.singleton(13L)), + Value.numericArray(Collections.singleton(new BigDecimal("3.14"))), + Value.stringArray(Collections.singleton("bar")), + Value.timestampArray( + Collections.singleton(com.google.cloud.Timestamp.ofTimeSecondsAndNanos(999L, 99))), + }) { + + try (JdbcPreparedStatement ps = new JdbcPreparedStatement(connection, sql)) { + ps.setObject(1, value); + Statement statement = ps.createStatement(); + assertEquals(statement.getParameters().get("p1"), value); + } + } + } + @SuppressWarnings("deprecation") @Test public void testParameters() throws SQLException, MalformedURLException { diff --git a/src/test/java/com/google/cloud/spanner/jdbc/JdbcQueryOptionsTest.java b/src/test/java/com/google/cloud/spanner/jdbc/JdbcQueryOptionsTest.java index f628e17ee..d1aeeb92d 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/JdbcQueryOptionsTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/JdbcQueryOptionsTest.java @@ -20,20 +20,28 @@ import com.google.cloud.spanner.MockSpannerServiceImpl.StatementResult; import com.google.cloud.spanner.SpannerOptions; +import com.google.cloud.spanner.SpannerOptions.SpannerEnvironment; import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.connection.AbstractMockServerTest; import com.google.common.base.MoreObjects; import com.google.spanner.v1.ExecuteSqlRequest; import java.sql.DriverManager; import java.sql.SQLException; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public class JdbcQueryOptionsTest extends AbstractMockServerTest { + @Before + public void setup() throws Exception { + stopServer(); + startStaticServer(); + } + @Test - public void testDefaultOptimizerVersion() throws SQLException { + public void testDefaultOptions() throws SQLException { try (java.sql.Connection connection = createJdbcConnection()) { try (java.sql.ResultSet rs = connection.createStatement().executeQuery("SHOW VARIABLE OPTIMIZER_VERSION")) { @@ -41,25 +49,39 @@ public void testDefaultOptimizerVersion() throws SQLException { assertThat(rs.getString("OPTIMIZER_VERSION")).isEqualTo(""); assertThat(rs.next()).isFalse(); } + try (java.sql.ResultSet rs = + connection.createStatement().executeQuery("SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE")) { + assertThat(rs.next()).isTrue(); + assertThat(rs.getString("OPTIMIZER_STATISTICS_PACKAGE")).isEqualTo(""); + assertThat(rs.next()).isFalse(); + } } } @Test - public void testOptimizerVersionInConnectionUrl() throws SQLException { + public void testOptionsInConnectionUrl() throws SQLException { try (java.sql.Connection connection = DriverManager.getConnection( - String.format("jdbc:%s;optimizerVersion=%s", getBaseUrl(), "100"))) { + String.format( + "jdbc:%s;optimizerVersion=%s;optimizerStatisticsPackage=%s", + getBaseUrl(), "100", "url_package"))) { try (java.sql.ResultSet rs = connection.createStatement().executeQuery("SHOW VARIABLE OPTIMIZER_VERSION")) { assertThat(rs.next()).isTrue(); assertThat(rs.getString("OPTIMIZER_VERSION")).isEqualTo("100"); assertThat(rs.next()).isFalse(); } + try (java.sql.ResultSet rs = + connection.createStatement().executeQuery("SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE")) { + assertThat(rs.next()).isTrue(); + assertThat(rs.getString("OPTIMIZER_STATISTICS_PACKAGE")).isEqualTo("url_package"); + assertThat(rs.next()).isFalse(); + } } } @Test - public void testSetOptimizerVersion() throws SQLException { + public void testSetOptions() throws SQLException { try (java.sql.Connection connection = createJdbcConnection()) { connection.createStatement().execute("SET OPTIMIZER_VERSION='20'"); try (java.sql.ResultSet rs = @@ -82,41 +104,64 @@ public void testSetOptimizerVersion() throws SQLException { assertThat(rs.getString("OPTIMIZER_VERSION")).isEqualTo(""); assertThat(rs.next()).isFalse(); } + + connection.createStatement().execute("SET OPTIMIZER_STATISTICS_PACKAGE='20210609'"); + try (java.sql.ResultSet rs = + connection.createStatement().executeQuery("SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE")) { + assertThat(rs.next()).isTrue(); + assertThat(rs.getString("OPTIMIZER_STATISTICS_PACKAGE")).isEqualTo("20210609"); + assertThat(rs.next()).isFalse(); + } + connection.createStatement().execute("SET OPTIMIZER_STATISTICS_PACKAGE='latest'"); + try (java.sql.ResultSet rs = + connection.createStatement().executeQuery("SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE")) { + assertThat(rs.next()).isTrue(); + assertThat(rs.getString("OPTIMIZER_STATISTICS_PACKAGE")).isEqualTo("latest"); + assertThat(rs.next()).isFalse(); + } + connection.createStatement().execute("SET OPTIMIZER_STATISTICS_PACKAGE=''"); + try (java.sql.ResultSet rs = + connection.createStatement().executeQuery("SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE")) { + assertThat(rs.next()).isTrue(); + assertThat(rs.getString("OPTIMIZER_STATISTICS_PACKAGE")).isEqualTo(""); + assertThat(rs.next()).isFalse(); + } } } @Test - public void testSetAndUseOptimizerVersion() throws SQLException { + public void testSetAndUseOptions() throws SQLException { try (java.sql.Connection connection = createJdbcConnection()) { connection.createStatement().execute("SET OPTIMIZER_VERSION='20'"); + connection.createStatement().execute("SET OPTIMIZER_STATISTICS_PACKAGE='20210609'"); try (java.sql.ResultSet rs = connection.createStatement().executeQuery(SELECT_COUNT_STATEMENT.getSql())) { assertThat(rs.next()).isTrue(); assertThat(rs.getLong(1)).isEqualTo(COUNT_BEFORE_INSERT); assertThat(rs.next()).isFalse(); - // Verify that the last ExecuteSqlRequest that the server received specified optimizer - // version 20. + // Verify that the last ExecuteSqlRequest that the server received used the options that + // were set. ExecuteSqlRequest request = getLastExecuteSqlRequest(); assertThat(request.getQueryOptions().getOptimizerVersion()).isEqualTo("20"); + assertThat(request.getQueryOptions().getOptimizerStatisticsPackage()).isEqualTo("20210609"); } - // Do another query, but now with optimizer version 'latest'. connection.createStatement().execute("SET OPTIMIZER_VERSION='latest'"); + connection.createStatement().execute("SET OPTIMIZER_STATISTICS_PACKAGE='latest'"); try (java.sql.ResultSet rs = connection.createStatement().executeQuery(SELECT_COUNT_STATEMENT.getSql())) { assertThat(rs.next()).isTrue(); assertThat(rs.getLong(1)).isEqualTo(COUNT_BEFORE_INSERT); assertThat(rs.next()).isFalse(); - // Verify that the last ExecuteSqlRequest that the server received specified optimizer - // version 'latest'. ExecuteSqlRequest request = getLastExecuteSqlRequest(); assertThat(request.getQueryOptions().getOptimizerVersion()).isEqualTo("latest"); + assertThat(request.getQueryOptions().getOptimizerStatisticsPackage()).isEqualTo("latest"); } - // Set the optimizer version to ''. This will do a fallback to the default, meaning that it - // will be read from the environment variable SPANNER_OPTIMIZER_VERSION as we have nothing set - // on the connection URL. + // Set the options to ''. This will do a fallback to the default, meaning that it will be read + // from the environment variables as we have nothing set on the connection URL. connection.createStatement().execute("SET OPTIMIZER_VERSION=''"); + connection.createStatement().execute("SET OPTIMIZER_STATISTICS_PACKAGE=''"); try (java.sql.ResultSet rs = connection.createStatement().executeQuery(SELECT_COUNT_STATEMENT.getSql())) { assertThat(rs.next()).isTrue(); @@ -127,36 +172,48 @@ public void testSetAndUseOptimizerVersion() throws SQLException { ExecuteSqlRequest request = getLastExecuteSqlRequest(); assertThat(request.getQueryOptions().getOptimizerVersion()) .isEqualTo(MoreObjects.firstNonNull(System.getenv("SPANNER_OPTIMIZER_VERSION"), "")); + assertThat(request.getQueryOptions().getOptimizerStatisticsPackage()) + .isEqualTo(MoreObjects.firstNonNull(System.getenv("OPTIMIZER_STATISTICS_PACKAGE"), "")); } } } @Test - public void testUseOptimizerVersionFromConnectionUrl() throws SQLException { + public void testUseOptionsFromConnectionUrl() throws SQLException { try (java.sql.Connection connection = - DriverManager.getConnection(String.format("jdbc:%s;optimizerVersion=10", getBaseUrl()))) { + DriverManager.getConnection( + String.format( + "jdbc:%s;optimizerVersion=10;optimizerStatisticsPackage=20210609_10_00_00", + getBaseUrl()))) { // Do a query and verify that the version from the connection URL is used. try (java.sql.ResultSet rs = connection.createStatement().executeQuery(SELECT_COUNT_STATEMENT.getSql())) { assertThat(rs.next()).isTrue(); assertThat(rs.getLong(1)).isEqualTo(COUNT_BEFORE_INSERT); assertThat(rs.next()).isFalse(); - // The optimizer version used should be '10' from the connection URL. + // The options should come from the connection URL. ExecuteSqlRequest request = getLastExecuteSqlRequest(); assertThat(request.getQueryOptions().getOptimizerVersion()).isEqualTo("10"); + assertThat(request.getQueryOptions().getOptimizerStatisticsPackage()) + .isEqualTo("20210609_10_00_00"); } } } @Test - public void testUseOptimizerVersionFromEnvironment() throws SQLException { + public void testUseOptionsFromEnvironment() throws SQLException { try { SpannerOptions.useEnvironment( - new SpannerOptions.SpannerEnvironment() { + new SpannerEnvironment() { @Override public String getOptimizerVersion() { return "20"; } + + @Override + public String getOptimizerStatisticsPackage() { + return "env_package"; + } }); try (java.sql.Connection connection = DriverManager.getConnection(String.format("jdbc:%s", getBaseUrl()))) { @@ -169,6 +226,8 @@ public String getOptimizerVersion() { // Verify query options from the environment. ExecuteSqlRequest request = getLastExecuteSqlRequest(); assertThat(request.getQueryOptions().getOptimizerVersion()).isEqualTo("20"); + assertThat(request.getQueryOptions().getOptimizerStatisticsPackage()) + .isEqualTo("env_package"); } // Now set one of the query options on the connection. That option should be used in // combination with the other option from the environment. @@ -182,6 +241,9 @@ public String getOptimizerVersion() { ExecuteSqlRequest request = getLastExecuteSqlRequest(); // Optimizer version should come from the connection. assertThat(request.getQueryOptions().getOptimizerVersion()).isEqualTo("30"); + // Optimizer statistics package should come from the environment. + assertThat(request.getQueryOptions().getOptimizerStatisticsPackage()) + .isEqualTo("env_package"); } } } finally { @@ -194,7 +256,9 @@ public void testUseQueryHint() throws SQLException { mockSpanner.putStatementResult( StatementResult.query( Statement.of( - String.format("@{optimizer_version=1} %s", SELECT_COUNT_STATEMENT.getSql())), + String.format( + "@{optimizer_version=1, optimizer_statistics_package=hint_package} %s", + SELECT_COUNT_STATEMENT.getSql())), SELECT_COUNT_RESULTSET_BEFORE_INSERT)); try (java.sql.Connection connection = DriverManager.getConnection(String.format("jdbc:%s", getBaseUrl()))) { @@ -202,14 +266,17 @@ public void testUseQueryHint() throws SQLException { connection .createStatement() .executeQuery( - String.format("@{optimizer_version=1} %s", SELECT_COUNT_STATEMENT.getSql()))) { + String.format( + "@{optimizer_version=1, optimizer_statistics_package=hint_package} %s", + SELECT_COUNT_STATEMENT.getSql()))) { assertThat(rs.next()).isTrue(); assertThat(rs.getLong(1)).isEqualTo(COUNT_BEFORE_INSERT); assertThat(rs.next()).isFalse(); - // The optimizer version used in the ExecuteSqlRequest should be empty as the query hint is - // parsed by the backend. + // The options used in the ExecuteSqlRequest should be empty as the query hint is parsed by + // the backend. ExecuteSqlRequest request = getLastExecuteSqlRequest(); assertThat(request.getQueryOptions().getOptimizerVersion()).isEqualTo(""); + assertThat(request.getQueryOptions().getOptimizerStatisticsPackage()).isEqualTo(""); } } } diff --git a/src/test/java/com/google/cloud/spanner/jdbc/JdbcResultSetMetaDataTest.java b/src/test/java/com/google/cloud/spanner/jdbc/JdbcResultSetMetaDataTest.java index e97382d0a..b3fcffcf1 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/JdbcResultSetMetaDataTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/JdbcResultSetMetaDataTest.java @@ -74,6 +74,7 @@ private static int getDefaultSize(Type type) { if (type == Type.int64()) return 10; if (type == Type.timestamp()) return 24; if (type == Type.string()) return 50; + if (type == Type.json()) return 50; if (type == Type.bytes()) return 50; return 50; } @@ -182,6 +183,7 @@ private static List getAllTypes() { types.add(Type.float64()); types.add(Type.int64()); types.add(Type.string()); + types.add(Type.json()); types.add(Type.timestamp()); List arrayTypes = new ArrayList<>(); for (Type type : types) { @@ -219,6 +221,7 @@ private Value getDefaultValue(Type type, int row) { if (type == Type.float64()) return Value.float64(123.45D); if (type == Type.int64()) return Value.int64(12345L); if (type == Type.string()) return Value.string("test value " + row); + if (type == Type.json()) return Value.json("{\"test_value\": " + row + "}"); if (type == Type.timestamp()) return Value.timestamp(com.google.cloud.Timestamp.now()); if (type.getCode() == Code.ARRAY) { @@ -240,6 +243,9 @@ private Value getDefaultValue(Type type, int row) { return Value.int64Array(Arrays.asList(12345L, 54321L)); if (type.getArrayElementType() == Type.string()) return Value.stringArray(Arrays.asList("test value " + row, "test value " + row)); + if (type.getArrayElementType() == Type.json()) + return Value.jsonArray( + Arrays.asList("{\"test_value\": " + row + "}", "{\"test_value\": " + row + "}")); if (type.getArrayElementType() == Type.timestamp()) return Value.timestampArray( Arrays.asList(com.google.cloud.Timestamp.now(), com.google.cloud.Timestamp.now())); @@ -263,7 +269,9 @@ public void testIsAutoIncrement() throws SQLException { public void testIsCaseSensitive() throws SQLException { for (int i = 1; i <= TEST_COLUMNS.size(); i++) { Type type = TEST_COLUMNS.get(i - 1).type; - assertEquals(type == Type.string() || type == Type.bytes(), subject.isCaseSensitive(i)); + assertEquals( + type == Type.string() || type == Type.bytes() || type == Type.json(), + subject.isCaseSensitive(i)); } } @@ -319,6 +327,7 @@ private int getDefaultDisplaySize(Type type, int column) throws SQLException { int length = subject.getPrecision(column); return length == 0 ? 50 : length; } + if (type == Type.json()) return 50; if (type == Type.timestamp()) return 16; return 10; } @@ -397,6 +406,7 @@ private int getSqlType(Type type) { if (type == Type.float64()) return Types.DOUBLE; if (type == Type.int64()) return Types.BIGINT; if (type == Type.string()) return Types.NVARCHAR; + if (type == Type.json()) return Types.NVARCHAR; if (type == Type.timestamp()) return Types.TIMESTAMP; if (type.getCode() == Code.ARRAY) return Types.ARRAY; return Types.OTHER; @@ -446,6 +456,7 @@ private String getTypeClassName(Type type) { if (type == Type.float64()) return Double.class.getName(); if (type == Type.int64()) return Long.class.getName(); if (type == Type.string()) return String.class.getName(); + if (type == Type.json()) return String.class.getName(); if (type == Type.timestamp()) return Timestamp.class.getName(); if (type.getCode() == Code.ARRAY) { if (type.getArrayElementType() == Type.bool()) return Boolean[].class.getName(); @@ -454,6 +465,7 @@ private String getTypeClassName(Type type) { if (type.getArrayElementType() == Type.float64()) return Double[].class.getName(); if (type.getArrayElementType() == Type.int64()) return Long[].class.getName(); if (type.getArrayElementType() == Type.string()) return String[].class.getName(); + if (type.getArrayElementType() == Type.json()) return String[].class.getName(); if (type.getArrayElementType() == Type.timestamp()) return Timestamp[].class.getName(); } return null; @@ -466,15 +478,17 @@ private String getTypeClassName(Type type) { + "Col 4: COL4 FLOAT64\n" + "Col 5: COL5 INT64\n" + "Col 6: COL6 STRING\n" - + "Col 7: COL7 TIMESTAMP\n" - + "Col 8: COL8 ARRAY\n" + + "Col 7: COL7 JSON\n" + + "Col 8: COL8 TIMESTAMP\n" + "Col 9: COL9 ARRAY\n" + "Col 10: COL10 ARRAY\n" + "Col 11: COL11 ARRAY\n" + "Col 12: COL12 ARRAY\n" + "Col 13: COL13 ARRAY\n" + "Col 14: COL14 ARRAY\n" - + "Col 15: CALCULATED INT64\n"; + + "Col 15: COL15 ARRAY\n" + + "Col 16: COL16 ARRAY\n" + + "Col 17: CALCULATED INT64\n"; @Test public void testToString() { diff --git a/src/test/java/com/google/cloud/spanner/jdbc/JdbcResultSetTest.java b/src/test/java/com/google/cloud/spanner/jdbc/JdbcResultSetTest.java index 2ad4a6d48..506992c47 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/JdbcResultSetTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/JdbcResultSetTest.java @@ -35,6 +35,7 @@ import com.google.cloud.spanner.Struct; import com.google.cloud.spanner.Type; import com.google.cloud.spanner.Type.StructField; +import com.google.cloud.spanner.Value; import com.google.cloud.spanner.jdbc.JdbcSqlExceptionFactory.JdbcSqlExceptionImpl; import com.google.rpc.Code; import java.io.IOException; @@ -52,6 +53,7 @@ import java.util.Calendar; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.TimeZone; import org.junit.Test; @@ -125,6 +127,35 @@ public class JdbcResultSetTest { private static final String STRING_COL_TIME = "STRING_COL_TIME"; private static final int STRING_COLINDEX_TIME = 24; private static final String STRING_TIME_VALUE = "10:31:15"; + private static final String NUMERIC_COL_NULL = "NUMERIC_COL_NULL"; + private static final String NUMERIC_COL_NOT_NULL = "NUMERIC_COL_NOT_NULL"; + private static final BigDecimal NUMERIC_VALUE = new BigDecimal("3.14"); + private static final int NUMERIC_COLINDEX_NULL = 25; + private static final int NUMERIC_COLINDEX_NOTNULL = 26; + private static final String JSON_COL_NULL = "JSON_COL_NULL"; + private static final String JSON_COL_NOT_NULL = "JSON_COL_NOT_NULL"; + private static final int JSON_COLINDEX_NULL = 27; + private static final int JSON_COLINDEX_NOT_NULL = 28; + private static final String JSON_VALUE = "{\"name\":\"John\", \"age\":30, \"car\":null}"; + + private static final String BOOL_ARRAY_COL = "BOOL_ARRAY"; + private static final List BOOL_ARRAY_VALUE = Arrays.asList(true, null, false); + private static final String BYTES_ARRAY_COL = "BYTES_ARRAY"; + private static final List BYTES_ARRAY_VALUE = Arrays.asList(BYTES_VALUE, null); + private static final String DATE_ARRAY_COL = "DATE_ARRAY"; + private static final List DATE_ARRAY_VALUE = Arrays.asList(DATE_VALUE, null); + private static final String FLOAT64_ARRAY_COL = "FLOAT64_ARRAY"; + private static final List FLOAT64_ARRAY_VALUE = Arrays.asList(DOUBLE_VALUE, null); + private static final String INT64_ARRAY_COL = "INT64_ARRAY"; + private static final List INT64_ARRAY_VALUE = Arrays.asList(LONG_VALUE, null); + private static final String NUMERIC_ARRAY_COL = "NUMERIC_ARRAY"; + private static final List NUMERIC_ARRAY_VALUE = Arrays.asList(NUMERIC_VALUE, null); + private static final String STRING_ARRAY_COL = "STRING_ARRAY"; + private static final List STRING_ARRAY_VALUE = Arrays.asList(STRING_VALUE, null); + private static final String TIMESTAMP_ARRAY_COL = "TIMESTAMP_ARRAY"; + private static final List TIMESTAMP_ARRAY_VALUE = Arrays.asList(TIMESTAMP_VALUE, null); + private static final String JSON_ARRAY_COL = "JSON_ARRAY"; + private static final List JSON_ARRAY_VALUE = Arrays.asList(JSON_VALUE, null); private JdbcResultSet subject; @@ -154,7 +185,20 @@ static ResultSet getMockResultSet() { StructField.of(STRING_COL_NUMBER, Type.string()), StructField.of(STRING_COL_DATE, Type.string()), StructField.of(STRING_COL_TIMESTAMP, Type.string()), - StructField.of(STRING_COL_TIME, Type.string())), + StructField.of(STRING_COL_TIME, Type.string()), + StructField.of(NUMERIC_COL_NULL, Type.numeric()), + StructField.of(NUMERIC_COL_NOT_NULL, Type.numeric()), + StructField.of(JSON_COL_NULL, Type.json()), + StructField.of(JSON_COL_NOT_NULL, Type.json()), + StructField.of(BOOL_ARRAY_COL, Type.array(Type.bool())), + StructField.of(BYTES_ARRAY_COL, Type.array(Type.bytes())), + StructField.of(DATE_ARRAY_COL, Type.array(Type.date())), + StructField.of(FLOAT64_ARRAY_COL, Type.array(Type.float64())), + StructField.of(INT64_ARRAY_COL, Type.array(Type.int64())), + StructField.of(NUMERIC_ARRAY_COL, Type.array(Type.numeric())), + StructField.of(JSON_ARRAY_COL, Type.array(Type.json())), + StructField.of(STRING_ARRAY_COL, Type.array(Type.string())), + StructField.of(TIMESTAMP_ARRAY_COL, Type.array(Type.timestamp()))), Arrays.asList( Struct.newBuilder() .set(STRING_COL_NULL) @@ -205,6 +249,32 @@ static ResultSet getMockResultSet() { .to(STRING_TIMESTAMP_VALUE) .set(STRING_COL_TIME) .to(STRING_TIME_VALUE) + .set(NUMERIC_COL_NULL) + .to((BigDecimal) null) + .set(NUMERIC_COL_NOT_NULL) + .to(NUMERIC_VALUE) + .set(JSON_COL_NULL) + .to(Value.json(null)) + .set(JSON_COL_NOT_NULL) + .to(Value.json(JSON_VALUE)) + .set(BOOL_ARRAY_COL) + .toBoolArray(BOOL_ARRAY_VALUE) + .set(BYTES_ARRAY_COL) + .toBytesArray(BYTES_ARRAY_VALUE) + .set(DATE_ARRAY_COL) + .toDateArray(DATE_ARRAY_VALUE) + .set(FLOAT64_ARRAY_COL) + .toFloat64Array(FLOAT64_ARRAY_VALUE) + .set(INT64_ARRAY_COL) + .toInt64Array(INT64_ARRAY_VALUE) + .set(NUMERIC_ARRAY_COL) + .toNumericArray(NUMERIC_ARRAY_VALUE) + .set(JSON_ARRAY_COL) + .toJsonArray(JSON_ARRAY_VALUE) + .set(STRING_ARRAY_COL) + .toStringArray(STRING_ARRAY_VALUE) + .set(TIMESTAMP_ARRAY_COL) + .toTimestampArray(TIMESTAMP_ARRAY_VALUE) .build())); } @@ -268,6 +338,15 @@ public void testGetStringIndex() throws SQLException { assertTrue(subject.wasNull()); } + @Test + public void testGetJsonIndex() throws SQLException { + assertNotNull(subject.getString(JSON_COLINDEX_NOT_NULL)); + assertEquals(JSON_VALUE, subject.getString(JSON_COLINDEX_NOT_NULL)); + assertFalse(subject.wasNull()); + assertNull(subject.getString(JSON_COLINDEX_NULL)); + assertTrue(subject.wasNull()); + } + @Test public void testGetStringIndexForBool() throws SQLException { assertNotNull(subject.getString(BOOLEAN_COLINDEX_NOTNULL)); @@ -835,7 +914,7 @@ public void testFindColumn() throws SQLException { } @Test - public void testGetBigDecimalIndex() throws SQLException { + public void testGetBigDecimalFromDouble_usingIndex() throws SQLException { assertNotNull(subject.getBigDecimal(DOUBLE_COLINDEX_NOTNULL)); assertEquals(BigDecimal.valueOf(DOUBLE_VALUE), subject.getBigDecimal(DOUBLE_COLINDEX_NOTNULL)); assertFalse(subject.wasNull()); @@ -844,7 +923,7 @@ public void testGetBigDecimalIndex() throws SQLException { } @Test - public void testGetBigDecimalLabel() throws SQLException { + public void testGetBigDecimalFromDouble_usingLabel() throws SQLException { assertNotNull(subject.getBigDecimal(DOUBLE_COL_NOT_NULL)); assertEquals(BigDecimal.valueOf(DOUBLE_VALUE), subject.getBigDecimal(DOUBLE_COL_NOT_NULL)); assertFalse(subject.wasNull()); @@ -852,6 +931,24 @@ public void testGetBigDecimalLabel() throws SQLException { assertTrue(subject.wasNull()); } + @Test + public void testGetBigDecimalIndex() throws SQLException { + assertNotNull(subject.getBigDecimal(NUMERIC_COLINDEX_NOTNULL)); + assertEquals(NUMERIC_VALUE, subject.getBigDecimal(NUMERIC_COLINDEX_NOTNULL)); + assertFalse(subject.wasNull()); + assertNull(subject.getBigDecimal(NUMERIC_COLINDEX_NULL)); + assertTrue(subject.wasNull()); + } + + @Test + public void testGetBigDecimalLabel() throws SQLException { + assertNotNull(subject.getBigDecimal(NUMERIC_COL_NOT_NULL)); + assertEquals(NUMERIC_VALUE, subject.getBigDecimal(NUMERIC_COL_NOT_NULL)); + assertFalse(subject.wasNull()); + assertNull(subject.getBigDecimal(NUMERIC_COL_NULL)); + assertTrue(subject.wasNull()); + } + @Test public void testGetStatement() throws SQLException { assertNotNull(subject.getStatement()); @@ -1272,6 +1369,15 @@ public void testGetObjectIndex() throws SQLException { assertTrue(subject.wasNull()); } + @Test + public void testGetJsonAsObjectIndex() throws SQLException { + assertNotNull(subject.getObject(JSON_COLINDEX_NOT_NULL)); + assertEquals(JSON_VALUE, subject.getObject(JSON_COLINDEX_NOT_NULL)); + assertFalse(subject.wasNull()); + assertNull(subject.getObject(JSON_COLINDEX_NULL)); + assertTrue(subject.wasNull()); + } + @SuppressWarnings("deprecation") @Test public void testGetObjectLabelMap() throws SQLException { @@ -1618,4 +1724,38 @@ public void testGetRowAndIsFirst() throws SQLException { public void testGetHoldability() throws SQLException { assertEquals(java.sql.ResultSet.CLOSE_CURSORS_AT_COMMIT, subject.getHoldability()); } + + @Test + public void testGetObjectAsValue() throws SQLException { + assertEquals( + Value.bool(BOOLEAN_VALUE), subject.getObject(BOOLEAN_COLINDEX_NOTNULL, Value.class)); + assertEquals(Value.bytes(BYTES_VALUE), subject.getObject(BYTES_COLINDEX_NOTNULL, Value.class)); + assertEquals(Value.date(DATE_VALUE), subject.getObject(DATE_COLINDEX_NOTNULL, Value.class)); + assertEquals( + Value.float64(DOUBLE_VALUE), subject.getObject(DOUBLE_COLINDEX_NOTNULL, Value.class)); + assertEquals(Value.int64(LONG_VALUE), subject.getObject(LONG_COLINDEX_NOTNULL, Value.class)); + assertEquals( + Value.numeric(NUMERIC_VALUE), subject.getObject(NUMERIC_COLINDEX_NOTNULL, Value.class)); + assertEquals( + Value.string(STRING_VALUE), subject.getObject(STRING_COLINDEX_NOTNULL, Value.class)); + assertEquals( + Value.timestamp(TIMESTAMP_VALUE), + subject.getObject(TIMESTAMP_COLINDEX_NOTNULL, Value.class)); + + assertEquals(Value.boolArray(BOOL_ARRAY_VALUE), subject.getObject(BOOL_ARRAY_COL, Value.class)); + assertEquals( + Value.bytesArray(BYTES_ARRAY_VALUE), subject.getObject(BYTES_ARRAY_COL, Value.class)); + assertEquals(Value.dateArray(DATE_ARRAY_VALUE), subject.getObject(DATE_ARRAY_COL, Value.class)); + assertEquals( + Value.float64Array(FLOAT64_ARRAY_VALUE), subject.getObject(FLOAT64_ARRAY_COL, Value.class)); + assertEquals( + Value.int64Array(INT64_ARRAY_VALUE), subject.getObject(INT64_ARRAY_COL, Value.class)); + assertEquals( + Value.numericArray(NUMERIC_ARRAY_VALUE), subject.getObject(NUMERIC_ARRAY_COL, Value.class)); + assertEquals( + Value.stringArray(STRING_ARRAY_VALUE), subject.getObject(STRING_ARRAY_COL, Value.class)); + assertEquals( + Value.timestampArray(TIMESTAMP_ARRAY_VALUE), + subject.getObject(TIMESTAMP_ARRAY_COL, Value.class)); + } } diff --git a/src/test/java/com/google/cloud/spanner/jdbc/JdbcTypeConverterTest.java b/src/test/java/com/google/cloud/spanner/jdbc/JdbcTypeConverterTest.java index 19f760bb6..1bb0e374e 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/JdbcTypeConverterTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/JdbcTypeConverterTest.java @@ -70,6 +70,7 @@ public void testConvertArray() throws SQLException { Type.float64(), Type.int64(), Type.string(), + Type.json(), Type.timestamp(), Type.numeric() }) { @@ -126,6 +127,23 @@ public void testConvertBytes() throws SQLException { assertThat(convert(testValues, Type.bytes(), String.class)).isEqualTo("test"); } + @Test + public void testConvertJson() throws SQLException { + String testValue = "{\"test\": foo}"; + assertConvertThrows(testValue, Type.json(), Boolean.class, Code.INVALID_ARGUMENT); + assertConvertThrows(testValue, Type.json(), Byte.class, Code.INVALID_ARGUMENT); + assertConvertThrows(testValue, Type.json(), Short.class, Code.INVALID_ARGUMENT); + assertConvertThrows(testValue, Type.json(), Integer.class, Code.INVALID_ARGUMENT); + assertConvertThrows(testValue, Type.json(), Long.class, Code.INVALID_ARGUMENT); + assertConvertThrows(testValue, Type.json(), Float.class, Code.INVALID_ARGUMENT); + assertConvertThrows(testValue, Type.json(), Double.class, Code.INVALID_ARGUMENT); + assertConvertThrows(testValue, Type.json(), BigInteger.class, Code.INVALID_ARGUMENT); + assertConvertThrows(testValue, Type.json(), BigDecimal.class, Code.INVALID_ARGUMENT); + + assertThat(convert(testValue, Type.json(), byte[].class)).isEqualTo(testValue.getBytes(UTF8)); + assertThat(convert(testValue, Type.json(), String.class)).isEqualTo(testValue); + } + private TimeZone[] getTestTimeZones() { return new TimeZone[] { TimeZone.getTimeZone("GMT-12:00"), diff --git a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcDatabaseMetaDataTest.java b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcDatabaseMetaDataTest.java index 755539987..087d688fc 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcDatabaseMetaDataTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcDatabaseMetaDataTest.java @@ -122,6 +122,7 @@ private Column( new Column("ColTimestamp", Types.TIMESTAMP, "TIMESTAMP", 35, null, null, false, null), new Column("ColCommitTS", Types.TIMESTAMP, "TIMESTAMP", 35, null, null, false, null), new Column("ColNumeric", Types.NUMERIC, "NUMERIC", 15, null, 10, false, null), + new Column("ColJson", Types.NVARCHAR, "JSON", 2621440, null, null, false, 2621440), new Column("ColInt64Array", Types.ARRAY, "ARRAY", 19, null, 10, true, null), new Column("ColFloat64Array", Types.ARRAY, "ARRAY", 15, 16, 2, true, null), new Column("ColBoolArray", Types.ARRAY, "ARRAY", null, null, null, true, null), @@ -151,6 +152,8 @@ private Column( new Column( "ColTimestampArray", Types.ARRAY, "ARRAY", 35, null, null, true, null), new Column("ColNumericArray", Types.ARRAY, "ARRAY", 15, null, 10, true, null), + new Column( + "ColJsonArray", Types.ARRAY, "ARRAY", 2621440, null, null, true, 2621440), new Column( "ColComputed", Types.NVARCHAR, diff --git a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcPreparedStatementTest.java b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcPreparedStatementTest.java index 2890ed9ce..ed4f0f4f0 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcPreparedStatementTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcPreparedStatementTest.java @@ -26,8 +26,12 @@ import static org.junit.Assert.fail; import static org.junit.Assume.assumeFalse; +import com.google.cloud.ByteArray; import com.google.cloud.spanner.IntegrationTest; +import com.google.cloud.spanner.Value; import com.google.cloud.spanner.jdbc.ITAbstractJdbcTest; +import com.google.cloud.spanner.jdbc.JsonType; +import com.google.cloud.spanner.testing.EmulatorSpannerHelper; import com.google.common.base.Strings; import com.google.common.io.BaseEncoding; import java.io.File; @@ -46,6 +50,7 @@ import java.sql.Timestamp; import java.sql.Types; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.List; import java.util.Scanner; @@ -745,84 +750,113 @@ public void test07_StatementBatchUpdateWithException() throws SQLException { @Test public void test08_InsertAllColumnTypes() throws SQLException { + String sql; + if (EmulatorSpannerHelper.isUsingEmulator()) { + sql = + "INSERT INTO TableWithAllColumnTypes (" + + "ColInt64, ColFloat64, ColBool, ColString, ColStringMax, ColBytes, ColBytesMax, ColDate, ColTimestamp, ColCommitTS, ColNumeric, " + + "ColInt64Array, ColFloat64Array, ColBoolArray, ColStringArray, ColStringMaxArray, ColBytesArray, ColBytesMaxArray, ColDateArray, ColTimestampArray, ColNumericArray" + + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, PENDING_COMMIT_TIMESTAMP(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + } else { + sql = + "INSERT INTO TableWithAllColumnTypes (" + + "ColInt64, ColFloat64, ColBool, ColString, ColStringMax, ColBytes, ColBytesMax, ColDate, ColTimestamp, ColCommitTS, ColNumeric, ColJson, " + + "ColInt64Array, ColFloat64Array, ColBoolArray, ColStringArray, ColStringMaxArray, ColBytesArray, ColBytesMaxArray, ColDateArray, ColTimestampArray, ColNumericArray, ColJsonArray" + + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, PENDING_COMMIT_TIMESTAMP(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + } try (Connection con = createConnection()) { - try (PreparedStatement ps = - con.prepareStatement( - "INSERT INTO TableWithAllColumnTypes (" - + "ColInt64, ColFloat64, ColBool, ColString, ColStringMax, ColBytes, ColBytesMax, ColDate, ColTimestamp, ColCommitTS, ColNumeric, " - + "ColInt64Array, ColFloat64Array, ColBoolArray, ColStringArray, ColStringMaxArray, ColBytesArray, ColBytesMaxArray, ColDateArray, ColTimestampArray, ColNumericArray" - + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, PENDING_COMMIT_TIMESTAMP(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")) { - ps.setLong(1, 1L); - ps.setDouble(2, 2D); - ps.setBoolean(3, true); - ps.setString(4, "test"); - ps.setObject(5, UUID.fromString("2d37f522-e0a5-4f22-8e09-4d77d299c967")); - ps.setBytes(6, "test".getBytes()); - ps.setBytes(7, "testtest".getBytes()); - ps.setDate(8, new Date(System.currentTimeMillis())); - ps.setTimestamp(9, new Timestamp(System.currentTimeMillis())); - ps.setBigDecimal(10, BigDecimal.TEN); - ps.setArray(11, con.createArrayOf("INT64", new Long[] {1L, 2L, 3L})); - ps.setArray(12, con.createArrayOf("FLOAT64", new Double[] {1.1D, 2.2D, 3.3D})); + try (PreparedStatement ps = con.prepareStatement(sql)) { + int index = 0; + ps.setLong(++index, 1L); + ps.setDouble(++index, 2D); + ps.setBoolean(++index, true); + ps.setString(++index, "test"); + ps.setObject(++index, UUID.fromString("2d37f522-e0a5-4f22-8e09-4d77d299c967")); + ps.setBytes(++index, "test".getBytes()); + ps.setBytes(++index, "testtest".getBytes()); + ps.setDate(++index, new Date(System.currentTimeMillis())); + ps.setTimestamp(++index, new Timestamp(System.currentTimeMillis())); + ps.setBigDecimal(++index, BigDecimal.TEN); + if (!EmulatorSpannerHelper.isUsingEmulator()) { + ps.setObject(++index, "{\"test_value\": \"foo\"}", JsonType.INSTANCE); + } + ps.setArray(++index, con.createArrayOf("INT64", new Long[] {1L, 2L, 3L})); + ps.setArray(++index, con.createArrayOf("FLOAT64", new Double[] {1.1D, 2.2D, 3.3D})); ps.setArray( - 13, con.createArrayOf("BOOL", new Boolean[] {Boolean.TRUE, null, Boolean.FALSE})); - ps.setArray(14, con.createArrayOf("STRING", new String[] {"1", "2", "3"})); - ps.setArray(15, con.createArrayOf("STRING", new String[] {"3", "2", "1"})); + ++index, con.createArrayOf("BOOL", new Boolean[] {Boolean.TRUE, null, Boolean.FALSE})); + ps.setArray(++index, con.createArrayOf("STRING", new String[] {"1", "2", "3"})); + ps.setArray(++index, con.createArrayOf("STRING", new String[] {"3", "2", "1"})); ps.setArray( - 16, + ++index, con.createArrayOf( "BYTES", new byte[][] {"1".getBytes(), "2".getBytes(), "3".getBytes()})); ps.setArray( - 17, + ++index, con.createArrayOf( "BYTES", new byte[][] {"333".getBytes(), "222".getBytes(), "111".getBytes()})); ps.setArray( - 18, + ++index, con.createArrayOf( "DATE", new Date[] {new Date(System.currentTimeMillis()), null, new Date(0)})); ps.setArray( - 19, + ++index, con.createArrayOf( "TIMESTAMP", new Timestamp[] { new Timestamp(System.currentTimeMillis()), null, new Timestamp(0) })); ps.setArray( - 20, + ++index, con.createArrayOf("NUMERIC", new BigDecimal[] {BigDecimal.ONE, null, BigDecimal.TEN})); + if (!EmulatorSpannerHelper.isUsingEmulator()) { + ps.setArray( + ++index, + con.createArrayOf( + "JSON", new String[] {"{\"test_value\": \"foo\"}", "{}", "[]", null})); + } assertEquals(1, ps.executeUpdate()); } try (ResultSet rs = con.createStatement().executeQuery("SELECT * FROM TableWithAllColumnTypes")) { + int index = 0; assertTrue(rs.next()); - assertEquals(1L, rs.getLong(1)); - assertEquals(2d, rs.getDouble(2), 0.0d); - assertTrue(rs.getBoolean(3)); - assertEquals("test", rs.getString(4)); - assertEquals("2d37f522-e0a5-4f22-8e09-4d77d299c967", rs.getString(5)); - assertArrayEquals("test".getBytes(), rs.getBytes(6)); - assertArrayEquals("testtest".getBytes(), rs.getBytes(7)); - assertNotNull(rs.getDate(8)); - assertNotNull(rs.getTimestamp(9)); - assertNotNull(rs.getTime(10)); // Commit timestamp - assertEquals(BigDecimal.TEN, rs.getBigDecimal(11)); - assertArrayEquals(new Long[] {1L, 2L, 3L}, (Long[]) rs.getArray(12).getArray()); - assertArrayEquals(new Double[] {1.1D, 2.2D, 3.3D}, (Double[]) rs.getArray(13).getArray()); + assertEquals(1L, rs.getLong(++index)); + assertEquals(2d, rs.getDouble(++index), 0.0d); + assertTrue(rs.getBoolean(++index)); + assertEquals("test", rs.getString(++index)); + assertEquals("2d37f522-e0a5-4f22-8e09-4d77d299c967", rs.getString(++index)); + assertArrayEquals("test".getBytes(), rs.getBytes(++index)); + assertArrayEquals("testtest".getBytes(), rs.getBytes(++index)); + assertNotNull(rs.getDate(++index)); + assertNotNull(rs.getTimestamp(++index)); + assertNotNull(rs.getTime(++index)); // Commit timestamp + assertEquals(BigDecimal.TEN, rs.getBigDecimal(++index)); + if (!EmulatorSpannerHelper.isUsingEmulator()) { + assertEquals("{\"test_value\":\"foo\"}", rs.getString(++index)); + } + assertArrayEquals(new Long[] {1L, 2L, 3L}, (Long[]) rs.getArray(++index).getArray()); assertArrayEquals( - new Boolean[] {true, null, false}, (Boolean[]) rs.getArray(14).getArray()); - assertArrayEquals(new String[] {"1", "2", "3"}, (String[]) rs.getArray(15).getArray()); - assertArrayEquals(new String[] {"3", "2", "1"}, (String[]) rs.getArray(16).getArray()); + new Double[] {1.1D, 2.2D, 3.3D}, (Double[]) rs.getArray(++index).getArray()); + assertArrayEquals( + new Boolean[] {true, null, false}, (Boolean[]) rs.getArray(++index).getArray()); + assertArrayEquals(new String[] {"1", "2", "3"}, (String[]) rs.getArray(++index).getArray()); + assertArrayEquals(new String[] {"3", "2", "1"}, (String[]) rs.getArray(++index).getArray()); assertArrayEquals( new byte[][] {"1".getBytes(), "2".getBytes(), "3".getBytes()}, - (byte[][]) rs.getArray(17).getArray()); + (byte[][]) rs.getArray(++index).getArray()); assertArrayEquals( new byte[][] {"333".getBytes(), "222".getBytes(), "111".getBytes()}, - (byte[][]) rs.getArray(18).getArray()); - assertEquals(3, ((Date[]) rs.getArray(19).getArray()).length); - assertEquals(3, ((Timestamp[]) rs.getArray(20).getArray()).length); + (byte[][]) rs.getArray(++index).getArray()); + assertEquals(3, ((Date[]) rs.getArray(++index).getArray()).length); + assertEquals(3, ((Timestamp[]) rs.getArray(++index).getArray()).length); assertArrayEquals( new BigDecimal[] {BigDecimal.ONE, null, BigDecimal.TEN}, - (BigDecimal[]) rs.getArray(21).getArray()); + (BigDecimal[]) rs.getArray(++index).getArray()); + if (!EmulatorSpannerHelper.isUsingEmulator()) { + assertArrayEquals( + new String[] {"{\"test_value\": \"foo\"}", "{}", "[]", null}, + (String[]) rs.getArray(++index).getArray()); + } assertFalse(rs.next()); } } @@ -835,7 +869,7 @@ public void test09_MetaData_FromQuery() throws SQLException { try (PreparedStatement ps = con.prepareStatement("SELECT * FROM TableWithAllColumnTypes WHERE ColInt64=?")) { ResultSetMetaData metadata = ps.getMetaData(); - assertEquals(22, metadata.getColumnCount()); + assertEquals(24, metadata.getColumnCount()); int index = 0; assertEquals("ColInt64", metadata.getColumnLabel(++index)); assertEquals("ColFloat64", metadata.getColumnLabel(++index)); @@ -848,6 +882,7 @@ public void test09_MetaData_FromQuery() throws SQLException { assertEquals("ColTimestamp", metadata.getColumnLabel(++index)); assertEquals("ColCommitTS", metadata.getColumnLabel(++index)); assertEquals("ColNumeric", metadata.getColumnLabel(++index)); + assertEquals("ColJson", metadata.getColumnLabel(++index)); assertEquals("ColInt64Array", metadata.getColumnLabel(++index)); assertEquals("ColFloat64Array", metadata.getColumnLabel(++index)); assertEquals("ColBoolArray", metadata.getColumnLabel(++index)); @@ -858,6 +893,7 @@ public void test09_MetaData_FromQuery() throws SQLException { assertEquals("ColDateArray", metadata.getColumnLabel(++index)); assertEquals("ColTimestampArray", metadata.getColumnLabel(++index)); assertEquals("ColNumericArray", metadata.getColumnLabel(++index)); + assertEquals("ColJsonArray", metadata.getColumnLabel(++index)); assertEquals("ColComputed", metadata.getColumnLabel(++index)); } } @@ -875,6 +911,142 @@ public void test10_MetaData_FromDML() throws SQLException { } } + @Test + public void test11_InsertDataUsingSpannerValue() throws SQLException { + String sql; + if (EmulatorSpannerHelper.isUsingEmulator()) { + sql = + "INSERT INTO TableWithAllColumnTypes (" + + "ColInt64, ColFloat64, ColBool, ColString, ColStringMax, ColBytes, ColBytesMax, ColDate, ColTimestamp, ColCommitTS, ColNumeric, " + + "ColInt64Array, ColFloat64Array, ColBoolArray, ColStringArray, ColStringMaxArray, ColBytesArray, ColBytesMaxArray, ColDateArray, ColTimestampArray, ColNumericArray" + + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, PENDING_COMMIT_TIMESTAMP(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + } else { + sql = + "INSERT INTO TableWithAllColumnTypes (" + + "ColInt64, ColFloat64, ColBool, ColString, ColStringMax, ColBytes, ColBytesMax, ColDate, ColTimestamp, ColCommitTS, ColNumeric, ColJson, " + + "ColInt64Array, ColFloat64Array, ColBoolArray, ColStringArray, ColStringMaxArray, ColBytesArray, ColBytesMaxArray, ColDateArray, ColTimestampArray, ColNumericArray, ColJsonArray" + + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, PENDING_COMMIT_TIMESTAMP(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + } + try (Connection con = createConnection()) { + try (PreparedStatement ps = con.prepareStatement(sql)) { + int index = 1; + ps.setObject(index++, Value.int64(2L)); + ps.setObject(index++, Value.float64(2D)); + ps.setObject(index++, Value.bool(true)); + ps.setObject(index++, Value.string("testvalues")); + ps.setObject(index++, Value.string("2d37f522-e0a5-4f22-8e09-4d77d299c967")); + ps.setObject(index++, Value.bytes(ByteArray.copyFrom("test".getBytes()))); + ps.setObject(index++, Value.bytes(ByteArray.copyFrom("testtest".getBytes()))); + ps.setObject(index++, Value.date(com.google.cloud.Date.fromYearMonthDay(2021, 5, 3))); + ps.setObject( + index++, Value.timestamp(com.google.cloud.Timestamp.ofTimeSecondsAndNanos(99999L, 99))); + ps.setObject(index++, Value.numeric(BigDecimal.TEN)); + if (!EmulatorSpannerHelper.isUsingEmulator()) { + ps.setObject(index++, Value.json("{\"test_value\": \"foo\"}")); + } + ps.setObject(index++, Value.int64Array(new long[] {1L, 2L, 3L})); + ps.setObject(index++, Value.float64Array(new double[] {1.1D, 2.2D, 3.3D})); + ps.setObject(index++, Value.boolArray(Arrays.asList(Boolean.TRUE, null, Boolean.FALSE))); + ps.setObject(index++, Value.stringArray(Arrays.asList("1", "2", "3"))); + ps.setObject(index++, Value.stringArray(Arrays.asList("3", "2", "1"))); + ps.setObject( + index++, + Value.bytesArray( + Arrays.asList( + ByteArray.copyFrom("1"), ByteArray.copyFrom("2"), ByteArray.copyFrom("3")))); + ps.setObject( + index++, + Value.bytesArray( + Arrays.asList( + ByteArray.copyFrom("333"), + ByteArray.copyFrom("222"), + ByteArray.copyFrom("111")))); + ps.setObject( + index++, + Value.dateArray( + Arrays.asList(com.google.cloud.Date.fromYearMonthDay(2021, 5, 3), null))); + ps.setObject( + index++, + Value.timestampArray( + Arrays.asList(com.google.cloud.Timestamp.ofTimeSecondsAndNanos(99999L, 99), null))); + ps.setObject( + index++, Value.numericArray(Arrays.asList(BigDecimal.ONE, null, BigDecimal.TEN))); + if (!EmulatorSpannerHelper.isUsingEmulator()) { + ps.setObject( + index++, + Value.jsonArray(Arrays.asList("{\"key1\": \"val1\"}", null, "{\"key2\": \"val2\"}"))); + } + assertEquals(1, ps.executeUpdate()); + } + try (ResultSet rs = + con.createStatement() + .executeQuery("SELECT * FROM TableWithAllColumnTypes WHERE ColInt64=2")) { + assertTrue(rs.next()); + int index = 1; + assertEquals(Value.int64(2L), rs.getObject(index++, Value.class)); + assertEquals(Value.float64(2d), rs.getObject(index++, Value.class)); + assertEquals(Value.bool(true), rs.getObject(index++, Value.class)); + assertEquals(Value.string("testvalues"), rs.getObject(index++, Value.class)); + assertEquals( + Value.string("2d37f522-e0a5-4f22-8e09-4d77d299c967"), + rs.getObject(index++, Value.class)); + assertEquals(Value.bytes(ByteArray.copyFrom("test")), rs.getObject(index++, Value.class)); + assertEquals( + Value.bytes(ByteArray.copyFrom("testtest")), rs.getObject(index++, Value.class)); + assertEquals( + Value.date(com.google.cloud.Date.fromYearMonthDay(2021, 5, 3)), + rs.getObject(index++, Value.class)); + assertEquals( + Value.timestamp(com.google.cloud.Timestamp.ofTimeSecondsAndNanos(99999L, 99)), + rs.getObject(index++, Value.class)); + assertNotNull(rs.getObject(index++, Value.class)); // Commit timestamp + assertEquals(Value.numeric(BigDecimal.TEN), rs.getObject(index++, Value.class)); + if (!EmulatorSpannerHelper.isUsingEmulator()) { + assertEquals(Value.json("{\"test_value\":\"foo\"}"), rs.getObject(index++, Value.class)); + } + assertEquals(Value.int64Array(new long[] {1L, 2L, 3L}), rs.getObject(index++, Value.class)); + assertEquals( + Value.float64Array(new double[] {1.1D, 2.2D, 3.3D}), + rs.getObject(index++, Value.class)); + assertEquals( + Value.boolArray(Arrays.asList(true, null, false)), rs.getObject(index++, Value.class)); + assertEquals( + Value.stringArray(Arrays.asList("1", "2", "3")), rs.getObject(index++, Value.class)); + assertEquals( + Value.stringArray(Arrays.asList("3", "2", "1")), rs.getObject(index++, Value.class)); + assertEquals( + Value.bytesArray( + Arrays.asList( + ByteArray.copyFrom("1"), ByteArray.copyFrom("2"), ByteArray.copyFrom("3"))), + rs.getObject(index++, Value.class)); + assertEquals( + Value.bytesArray( + Arrays.asList( + ByteArray.copyFrom("333"), + ByteArray.copyFrom("222"), + ByteArray.copyFrom("111"))), + rs.getObject(index++, Value.class)); + assertEquals( + Value.dateArray( + Arrays.asList(com.google.cloud.Date.fromYearMonthDay(2021, 5, 3), null)), + rs.getObject(index++, Value.class)); + assertEquals( + Value.timestampArray( + Arrays.asList(com.google.cloud.Timestamp.ofTimeSecondsAndNanos(99999L, 99), null)), + rs.getObject(index++, Value.class)); + assertEquals( + Value.numericArray(Arrays.asList(BigDecimal.ONE, null, BigDecimal.TEN)), + rs.getObject(index++, Value.class)); + if (!EmulatorSpannerHelper.isUsingEmulator()) { + assertEquals( + Value.jsonArray(Arrays.asList("{\"key1\":\"val1\"}", null, "{\"key2\":\"val2\"}")), + rs.getObject(index++, Value.class)); + } + assertFalse(rs.next()); + } + } + } + private void assertDefaultParameterMetaData(ParameterMetaData pmd, int expectedParamCount) throws SQLException { assertEquals(expectedParamCount, pmd.getParameterCount()); diff --git a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcQueryOptionsTest.java b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcQueryOptionsTest.java index 7ca650dfc..ac90687c8 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcQueryOptionsTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcQueryOptionsTest.java @@ -17,6 +17,9 @@ package com.google.cloud.spanner.jdbc.it; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.junit.Assume.assumeFalse; @@ -25,6 +28,7 @@ import com.google.cloud.spanner.connection.SpannerPool; import com.google.cloud.spanner.jdbc.ITAbstractJdbcTest; import com.google.cloud.spanner.jdbc.JdbcSqlException; +import com.google.cloud.spanner.testing.EmulatorSpannerHelper; import com.google.rpc.Code; import com.google.spanner.v1.ExecuteSqlRequest.QueryOptions; import java.sql.Connection; @@ -96,7 +100,8 @@ public void connectionUrl() throws SQLException { @Test public void connectionUrlWithInvalidOptimizerVersion() throws SQLException { - assumeFalse("optimizer version is ignored on emulator", env.getTestHelper().isEmulator()); + assumeFalse( + "optimizer version is ignored on emulator", EmulatorSpannerHelper.isUsingEmulator()); this.connectionUriSuffix = ";optimizerVersion=9999999"; try (Connection connection = createConnection()) { try (ResultSet rs = connection.createStatement().executeQuery("SELECT 1")) { @@ -139,7 +144,8 @@ public void setLatestOptimizerVersion() throws SQLException { @Test public void setInvalidOptimizerVersion() throws SQLException { - assumeFalse("optimizer version is ignored on emulator", env.getTestHelper().isEmulator()); + assumeFalse( + "optimizer version is ignored on emulator", EmulatorSpannerHelper.isUsingEmulator()); try (Connection connection = createConnection()) { connection.createStatement().execute("SET OPTIMIZER_VERSION='9999999'"); try (ResultSet rs = connection.createStatement().executeQuery("SELECT 1")) { @@ -156,7 +162,7 @@ public void setInvalidOptimizerVersion() throws SQLException { public void optimizerVersionInQueryHint() throws SQLException { assumeFalse( "optimizer version in query hint is not supported on emulator", - env.getTestHelper().isEmulator()); + EmulatorSpannerHelper.isUsingEmulator()); try (Connection connection = createConnection()) { verifyOptimizerVersion(connection, ""); try (ResultSet rs = @@ -175,8 +181,9 @@ public void optimizerVersionInQueryHint() throws SQLException { } @Test - public void optimizerVersionInEnvironment() throws SQLException { - assumeFalse("optimizer version is ignored on emulator", env.getTestHelper().isEmulator()); + public void testOptionsInEnvironment() throws SQLException { + assumeFalse( + "optimizer version is ignored on emulator", EmulatorSpannerHelper.isUsingEmulator()); try { SpannerOptions.useEnvironment( new SpannerOptions.SpannerEnvironment() { @@ -184,6 +191,11 @@ public void optimizerVersionInEnvironment() throws SQLException { public String getOptimizerVersion() { return "1"; } + + @Override + public String getOptimizerStatisticsPackage() { + return "latest"; + } }); try (Connection connection = createConnection()) { // Environment query options are not visible to the connection. @@ -204,15 +216,19 @@ public String getOptimizerVersion() { public String getOptimizerVersion() { return "9999999"; } + + @Override + public String getOptimizerStatisticsPackage() { + return "latest"; + } }); try (Connection connection = createConnection()) { - try (ResultSet rs = connection.createStatement().executeQuery("SELECT 1")) { - fail("missing expected exception"); - } catch (SQLException e) { - assertThat((Throwable) e).isInstanceOf(JdbcSqlException.class); - JdbcSqlException je = (JdbcSqlException) e; - assertThat(je.getCode()).isEqualTo(Code.INVALID_ARGUMENT); - } + SQLException e = + assertThrows( + SQLException.class, () -> connection.createStatement().executeQuery("SELECT 1")); + assertTrue(e instanceof JdbcSqlException); + JdbcSqlException je = (JdbcSqlException) e; + assertEquals(Code.INVALID_ARGUMENT, je.getCode()); } } finally { SpannerOptions.useDefaultEnvironment(); diff --git a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcSimpleStatementsTest.java b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcSimpleStatementsTest.java index 15f25b919..fcb3b0e44 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcSimpleStatementsTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcSimpleStatementsTest.java @@ -17,14 +17,22 @@ package com.google.cloud.spanner.jdbc.it; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import com.google.cloud.spanner.IntegrationTest; +import com.google.cloud.spanner.Struct; +import com.google.cloud.spanner.Value; import com.google.cloud.spanner.jdbc.ITAbstractJdbcTest; +import java.sql.Array; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; import java.sql.Statement; import org.junit.Test; import org.junit.experimental.categories.Category; @@ -149,4 +157,38 @@ public void testAddBatchWhenAlreadyInBatch() { "Calling addBatch() is not allowed when a DML or DDL batch has been started on the connection."); } } + + @Test + public void testSelectArrayOfStructs() throws SQLException { + String sql = + "WITH points AS\n" + + " (SELECT [1, 5] as point\n" + + " UNION ALL SELECT [2, 8] as point\n" + + " UNION ALL SELECT [3, 7] as point\n" + + " UNION ALL SELECT [4, 1] as point\n" + + " UNION ALL SELECT [5, 7] as point)\n" + + "SELECT ARRAY(\n" + + " SELECT STRUCT(point)\n" + + " FROM points)\n" + + " AS coordinates"; + try (Connection connection = createConnection()) { + try (ResultSet resultSet = connection.createStatement().executeQuery(sql)) { + assertTrue(resultSet.next()); + assertEquals(resultSet.getMetaData().getColumnCount(), 1); + Array array = resultSet.getArray(1); + assertThat((Struct[]) array.getArray()) + .asList() + .containsExactly( + Struct.newBuilder().set("point").to(Value.int64Array(new long[] {1L, 5L})).build(), + Struct.newBuilder().set("point").to(Value.int64Array(new long[] {2L, 8L})).build(), + Struct.newBuilder().set("point").to(Value.int64Array(new long[] {3L, 7L})).build(), + Struct.newBuilder().set("point").to(Value.int64Array(new long[] {4L, 1L})).build(), + Struct.newBuilder().set("point").to(Value.int64Array(new long[] {5L, 7L})).build()); + // Getting a result set from an array of structs is not supported, as structs are not + // supported as a valid column type in a result set. + assertThrows(SQLFeatureNotSupportedException.class, () -> array.getResultSet()); + assertFalse(resultSet.next()); + } + } + } } diff --git a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcSqlScriptTest.java b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcSqlScriptTest.java index 8fc331bb5..5133fc4d3 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcSqlScriptTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcSqlScriptTest.java @@ -23,6 +23,7 @@ import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.IntegrationTest; +import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.connection.SqlScriptVerifier; import com.google.cloud.spanner.jdbc.ITAbstractJdbcTest; import com.google.cloud.spanner.jdbc.JdbcSqlScriptVerifier; @@ -93,6 +94,11 @@ public void test02_InsertTestData() throws Exception { // Ignore, this is expected as errors during a read/write transaction are sticky on the // emulator. } + } catch (SpannerException e) { + if (env.getTestHelper().isEmulator() && e.getErrorCode() == ErrorCode.ALREADY_EXISTS) { + // Ignore, this is expected as errors during a read/write transaction are sticky on the + // emulator. + } } } @@ -114,6 +120,11 @@ public void test04_TestGetCommitTimestamp() throws Exception { && e.getErrorCode() == ErrorCode.INVALID_ARGUMENT.getGrpcStatusCode().value()) { // Ignore as errors during read/write transactions are sticky on the emulator. } + } catch (SpannerException e) { + if (env.getTestHelper().isEmulator() && e.getErrorCode() == ErrorCode.ALREADY_EXISTS) { + // Ignore, this is expected as errors during a read/write transaction are sticky on the + // emulator. + } } } diff --git a/src/test/resources/com/google/cloud/spanner/jdbc/it/CreateMusicTables.sql b/src/test/resources/com/google/cloud/spanner/jdbc/it/CreateMusicTables.sql index 6a8c4616d..9b2cb3bad 100644 --- a/src/test/resources/com/google/cloud/spanner/jdbc/it/CreateMusicTables.sql +++ b/src/test/resources/com/google/cloud/spanner/jdbc/it/CreateMusicTables.sql @@ -74,6 +74,7 @@ CREATE TABLE TableWithAllColumnTypes ( ColTimestamp TIMESTAMP NOT NULL, ColCommitTS TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true), ColNumeric NUMERIC NOT NULL, + ColJson JSON NOT NULL, ColInt64Array ARRAY, ColFloat64Array ARRAY, @@ -85,6 +86,7 @@ CREATE TABLE TableWithAllColumnTypes ( ColDateArray ARRAY, ColTimestampArray ARRAY, ColNumericArray ARRAY, + ColJsonArray ARRAY, ColComputed STRING(MAX) AS (CONCAT(COALESCE(ColString, ''), ' ', COALESCE(ColStringMax, ''))) STORED, ) PRIMARY KEY (ColInt64) diff --git a/src/test/resources/com/google/cloud/spanner/jdbc/it/CreateMusicTables_Emulator.sql b/src/test/resources/com/google/cloud/spanner/jdbc/it/CreateMusicTables_Emulator.sql new file mode 100644 index 000000000..d1e73bba2 --- /dev/null +++ b/src/test/resources/com/google/cloud/spanner/jdbc/it/CreateMusicTables_Emulator.sql @@ -0,0 +1,104 @@ +/* + * Copyright 2019 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 + * + * http://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. + */ + +START BATCH DDL; + +CREATE TABLE Singers ( + SingerId INT64 NOT NULL, + FirstName STRING(1024), + LastName STRING(1024), + SingerInfo BYTES(MAX), + BirthDate DATE +) PRIMARY KEY(SingerId); + +CREATE INDEX SingersByFirstLastName ON Singers(FirstName, LastName); + +CREATE TABLE Albums ( + SingerId INT64 NOT NULL, + AlbumId INT64 NOT NULL, + AlbumTitle STRING(MAX), + MarketingBudget INT64 +) PRIMARY KEY(SingerId, AlbumId), + INTERLEAVE IN PARENT Singers ON DELETE CASCADE; + +CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle); + +CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) STORING (MarketingBudget); + +CREATE TABLE Songs ( + SingerId INT64 NOT NULL, + AlbumId INT64 NOT NULL, + TrackId INT64 NOT NULL, + SongName STRING(MAX), + Duration INT64, + SongGenre STRING(25) +) PRIMARY KEY(SingerId, AlbumId, TrackId), + INTERLEAVE IN PARENT Albums ON DELETE CASCADE; + +CREATE UNIQUE INDEX SongsBySingerAlbumSongNameDesc ON Songs(SingerId, AlbumId, SongName DESC), INTERLEAVE IN Albums; + +CREATE INDEX SongsBySongName ON Songs(SongName); + +CREATE TABLE Concerts ( + VenueId INT64 NOT NULL, + SingerId INT64 NOT NULL, + ConcertDate DATE NOT NULL, + BeginTime TIMESTAMP, + EndTime TIMESTAMP, + TicketPrices ARRAY, + CONSTRAINT Fk_Concerts_Singer FOREIGN KEY (SingerId) REFERENCES Singers (SingerId) +) PRIMARY KEY(VenueId, SingerId, ConcertDate); + +CREATE TABLE TableWithAllColumnTypes ( + ColInt64 INT64 NOT NULL, + ColFloat64 FLOAT64 NOT NULL, + ColBool BOOL NOT NULL, + ColString STRING(100) NOT NULL, + ColStringMax STRING(MAX) NOT NULL, + ColBytes BYTES(100) NOT NULL, + ColBytesMax BYTES(MAX) NOT NULL, + ColDate DATE NOT NULL, + ColTimestamp TIMESTAMP NOT NULL, + ColCommitTS TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true), + ColNumeric NUMERIC NOT NULL, + + ColInt64Array ARRAY, + ColFloat64Array ARRAY, + ColBoolArray ARRAY, + ColStringArray ARRAY, + ColStringMaxArray ARRAY, + ColBytesArray ARRAY, + ColBytesMaxArray ARRAY, + ColDateArray ARRAY, + ColTimestampArray ARRAY, + ColNumericArray ARRAY, + + ColComputed STRING(MAX) AS (CONCAT(COALESCE(ColString, ''), ' ', COALESCE(ColStringMax, ''))) STORED, +) PRIMARY KEY (ColInt64) +; + +CREATE TABLE TableWithRef ( + Id INT64 NOT NULL, + RefFloat FLOAT64 NOT NULL, + RefString STRING(100) NOT NULL, + RefDate DATE NOT NULL, + CONSTRAINT Fk_TableWithRef_TableWithAllColumnTypes + FOREIGN KEY (RefFloat, RefString, RefDate) + REFERENCES TableWithAllColumnTypes (ColFloat64, ColString, ColDate) +) PRIMARY KEY (Id) +; + +RUN BATCH; \ No newline at end of file diff --git a/synth.metadata b/synth.metadata index 203fa091c..8f46bdb7c 100644 --- a/synth.metadata +++ b/synth.metadata @@ -4,14 +4,14 @@ "git": { "name": ".", "remote": "https://github.com/googleapis/java-spanner-jdbc.git", - "sha": "212d9d05c4f28ade71ab5484792188b11a5bcd8b" + "sha": "813a13d993ef2ad61ca7acda6700760a4cfcd512" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "8285c2b4cdbc3771d031ad91e1c4ec9e55fff45d" + "sha": "ff01716e16d2c6e87eaf87197b753ac9fcbbed5d" } } ], @@ -21,12 +21,9 @@ ".github/ISSUE_TEMPLATE/feature_request.md", ".github/ISSUE_TEMPLATE/support_request.md", ".github/PULL_REQUEST_TEMPLATE.md", - ".github/blunderbuss.yml", ".github/generated-files-bot.yml", ".github/readme/synth.py", - ".github/release-please.yml", ".github/snippet-bot.yml", - ".github/sync-repo-settings.yaml", ".github/trusted-contribution.yml", ".github/workflows/approve-readme.yaml", ".github/workflows/auto-release.yaml", @@ -82,6 +79,7 @@ "CODE_OF_CONDUCT.md", "CONTRIBUTING.md", "LICENSE", + "SECURITY.md", "codecov.yaml", "java.header", "license-checks.xml", diff --git a/versions.txt b/versions.txt index 7710d28ba..4e03da498 100644 --- a/versions.txt +++ b/versions.txt @@ -1,4 +1,4 @@ # Format: # module:released-version:current-version -google-cloud-spanner-jdbc:2.0.2:2.0.2 +google-cloud-spanner-jdbc:2.3.5:2.3.6-SNAPSHOT From b9e00d468529dfdf60498f7b92d20b0722b558e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Tue, 24 Aug 2021 15:02:01 +0200 Subject: [PATCH 2/3] fix: run linter --- src/test/java/com/google/cloud/spanner/jdbc/JdbcArrayTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/com/google/cloud/spanner/jdbc/JdbcArrayTest.java b/src/test/java/com/google/cloud/spanner/jdbc/JdbcArrayTest.java index cd416b651..74b8354eb 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/JdbcArrayTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/JdbcArrayTest.java @@ -23,7 +23,6 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertThrows; import static org.junit.Assert.fail; import com.google.cloud.spanner.ErrorCode; From 79fa20ea6b1a9f206cc4bc61f983a5f4af642b49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Tue, 24 Aug 2021 15:31:26 +0200 Subject: [PATCH 3/3] fix: integration test failure --- .../java/com/google/cloud/spanner/jdbc/JdbcTypeConverter.java | 4 ++++ .../cloud/spanner/jdbc/it/ITJdbcPreparedStatementTest.java | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/google/cloud/spanner/jdbc/JdbcTypeConverter.java b/src/main/java/com/google/cloud/spanner/jdbc/JdbcTypeConverter.java index 40b7604f7..4b2e4f0f7 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/JdbcTypeConverter.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/JdbcTypeConverter.java @@ -187,6 +187,8 @@ private static Value convertToSpannerValue(Object value, Type type) throws SQLEx case TIMESTAMP: return Value.timestampArray( toGoogleTimestamps((java.sql.Timestamp[]) ((java.sql.Array) value).getArray())); + case JSON: + return Value.jsonArray(Arrays.asList((String[]) ((java.sql.Array) value).getArray())); case STRUCT: default: throw JdbcSqlExceptionFactory.of( @@ -208,6 +210,8 @@ private static Value convertToSpannerValue(Object value, Type type) throws SQLEx return Value.string((String) value); case TIMESTAMP: return Value.timestamp(toGoogleTimestamp((java.sql.Timestamp) value)); + case JSON: + return Value.json((String) value); case STRUCT: default: throw JdbcSqlExceptionFactory.of( diff --git a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcPreparedStatementTest.java b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcPreparedStatementTest.java index ed4f0f4f0..ea1bbfb32 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcPreparedStatementTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcPreparedStatementTest.java @@ -854,7 +854,7 @@ public void test08_InsertAllColumnTypes() throws SQLException { (BigDecimal[]) rs.getArray(++index).getArray()); if (!EmulatorSpannerHelper.isUsingEmulator()) { assertArrayEquals( - new String[] {"{\"test_value\": \"foo\"}", "{}", "[]", null}, + new String[] {"{\"test_value\":\"foo\"}", "{}", "[]", null}, (String[]) rs.getArray(++index).getArray()); } assertFalse(rs.next());