diff --git a/.github/blunderbuss.yml b/.github/blunderbuss.yml
new file mode 100644
index 000000000..1a23ea42b
--- /dev/null
+++ b/.github/blunderbuss.yml
@@ -0,0 +1,7 @@
+# Configuration for the Blunderbuss GitHub app. For more info see
+# https://github.com/googleapis/repo-automation-bots/tree/master/packages/blunderbuss
+assign_prs_by:
+- labels:
+ - samples
+ to:
+ - googleapis/java-samples-reviewers
\ No newline at end of file
diff --git a/.github/readme/synth.metadata/synth.metadata b/.github/readme/synth.metadata/synth.metadata
index 19ca2958f..fe8ac6901 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": "3a305ba00b9739ceb17c879f82319b0a6b2a3f9f"
+ "sha": "9eea34c4206845a5e23b5b6ac78509497fd06069"
}
},
{
"git": {
"name": "synthtool",
"remote": "https://github.com/googleapis/synthtool.git",
- "sha": "1f1148d3c7a7a52f0c98077f976bd9b3c948ee2b"
+ "sha": "352f25621c28d2fa0784984ea0ed5ea697aa1525"
}
}
]
diff --git a/.github/workflows/approve-readme.yaml b/.github/workflows/approve-readme.yaml
index e2d841d6c..7513acaeb 100644
--- a/.github/workflows/approve-readme.yaml
+++ b/.github/workflows/approve-readme.yaml
@@ -6,7 +6,7 @@ jobs:
runs-on: ubuntu-latest
if: github.repository_owner == 'googleapis' && github.head_ref == 'autosynth-readme'
steps:
- - uses: actions/github-script@v3.0.0
+ - uses: actions/github-script@v3
with:
github-token: ${{secrets.YOSHI_APPROVER_TOKEN}}
script: |
diff --git a/.github/workflows/auto-release.yaml b/.github/workflows/auto-release.yaml
index bc1554aec..2b6cdbc97 100644
--- a/.github/workflows/auto-release.yaml
+++ b/.github/workflows/auto-release.yaml
@@ -6,7 +6,7 @@ jobs:
runs-on: ubuntu-latest
if: contains(github.head_ref, 'release-v')
steps:
- - uses: actions/github-script@v3.0.0
+ - uses: actions/github-script@v3
with:
github-token: ${{secrets.YOSHI_APPROVER_TOKEN}}
debug: true
diff --git a/.kokoro/common.sh b/.kokoro/common.sh
index a8d0ea04d..ace89f45a 100644
--- a/.kokoro/common.sh
+++ b/.kokoro/common.sh
@@ -25,7 +25,6 @@ function retry_with_backoff {
# allow a failures to continue
set +e
- echo "${command}"
${command}
exit_code=$?
diff --git a/.kokoro/release/publish_javadoc.sh b/.kokoro/release/publish_javadoc.sh
index 3c87c1b7f..7325bdc74 100755
--- a/.kokoro/release/publish_javadoc.sh
+++ b/.kokoro/release/publish_javadoc.sh
@@ -38,8 +38,8 @@ python3 -m pip install gcp-docuploader
# compile all packages
mvn clean install -B -q -DskipTests=true
-NAME=google-cloud-spanner-jdbc
-VERSION=$(grep ${NAME}: versions.txt | cut -d: -f3)
+export NAME=google-cloud-spanner-jdbc
+export VERSION=$(grep ${NAME}: versions.txt | cut -d: -f3)
# build the docs
mvn site -B -q
@@ -59,7 +59,8 @@ python3 -m docuploader upload . \
popd
-# V2
+# V2 due to problems w/ the released javadoc plugin doclava, Java 8 is required. Beware of accidental updates.
+
mvn clean site -B -q -Ddevsite.template="${KOKORO_GFILE_DIR}/java/"
pushd target/devsite/reference
diff --git a/.kokoro/release/stage.sh b/.kokoro/release/stage.sh
index 3c482cbc5..16126d2eb 100755
--- a/.kokoro/release/stage.sh
+++ b/.kokoro/release/stage.sh
@@ -20,19 +20,22 @@ python3 -m pip install gcp-releasetool
python3 -m releasetool publish-reporter-script > /tmp/publisher-script; source /tmp/publisher-script
source $(dirname "$0")/common.sh
+source $(dirname "$0")/../common.sh
MAVEN_SETTINGS_FILE=$(realpath $(dirname "$0")/../../)/settings.xml
pushd $(dirname "$0")/../../
setup_environment_secrets
create_settings_xml_file "settings.xml"
-mvn clean install deploy -B \
- --settings ${MAVEN_SETTINGS_FILE} \
- -DskipTests=true \
- -DperformRelease=true \
- -Dgpg.executable=gpg \
- -Dgpg.passphrase=${GPG_PASSPHRASE} \
- -Dgpg.homedir=${GPG_HOMEDIR}
+# attempt to stage 3 times with exponential backoff (starting with 10 seconds)
+retry_with_backoff 3 10 \
+ mvn clean install deploy -B \
+ --settings ${MAVEN_SETTINGS_FILE} \
+ -DskipTests=true \
+ -DperformRelease=true \
+ -Dgpg.executable=gpg \
+ -Dgpg.passphrase=${GPG_PASSPHRASE} \
+ -Dgpg.homedir=${GPG_HOMEDIR}
if [[ -n "${AUTORELEASE_PR}" ]]
then
diff --git a/.readme-partials.yaml b/.readme-partials.yaml
new file mode 100644
index 000000000..47e65e148
--- /dev/null
+++ b/.readme-partials.yaml
@@ -0,0 +1,25 @@
+custom_content: |
+ ### Creating a JDBC Connection
+
+ The following example shows how to create a JDBC connection to Cloud Spanner and execute a simple query.
+
+ ```java
+ String projectId = "my-project";
+ String instanceId = "my-instance";
+ String databaseId = "my-database";
+
+ try (Connection connection =
+ DriverManager.getConnection(
+ String.format(
+ "jdbc:cloudspanner:/projects/%s/instances/%s/databases/%s",
+ projectId, instanceId, databaseId))) {
+ try (Statement statement = connection.createStatement()) {
+ try (ResultSet rs = statement.executeQuery("SELECT CURRENT_TIMESTAMP()")) {
+ while (rs.next()) {
+ System.out.printf(
+ "Connected to Cloud Spanner at [%s]%n", rs.getTimestamp(1).toString());
+ }
+ }
+ }
+ }
+ ```
diff --git a/.repo-metadata.json b/.repo-metadata.json
index fe90fd731..524b2f3f2 100644
--- a/.repo-metadata.json
+++ b/.repo-metadata.json
@@ -1,7 +1,7 @@
{
"name": "spanner-jdbc",
"name_pretty": "Google Cloud Spanner JDBC",
- "product_documentation": "https://cloud.google.com/pubsub/docs/",
+ "product_documentation": "https://cloud.google.com/spanner/docs/use-oss-jdbc",
"client_documentation": "https://googleapis.dev/java/google-cloud-spanner-jdbc/latest/index.html",
"release_level": "ga",
"language": "java",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8aae6b617..e9772f916 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,27 @@
# Changelog
+## [1.18.0](https://www.github.com/googleapis/java-spanner-jdbc/compare/v1.17.3...v1.18.0) (2020-12-10)
+
+
+### Features
+
+* expose more methods from Connection in JDBC ([#255](https://www.github.com/googleapis/java-spanner-jdbc/issues/255)) ([697837c](https://www.github.com/googleapis/java-spanner-jdbc/commit/697837ce0ce646a9ca45a0afc3a2e1e368c712f7)), closes [#253](https://www.github.com/googleapis/java-spanner-jdbc/issues/253)
+* report whether column is generated in JDBC metadata ([#291](https://www.github.com/googleapis/java-spanner-jdbc/issues/291)) ([9aa9a1f](https://www.github.com/googleapis/java-spanner-jdbc/commit/9aa9a1f8f673554ae71e78937007166f220dd255)), closes [#290](https://www.github.com/googleapis/java-spanner-jdbc/issues/290)
+
+
+### Documentation
+
+* add connection example to readme ([#281](https://www.github.com/googleapis/java-spanner-jdbc/issues/281)) ([00314e6](https://www.github.com/googleapis/java-spanner-jdbc/commit/00314e643ee6570ed6025630616ad0df70789447))
+* fix product docs link ([#282](https://www.github.com/googleapis/java-spanner-jdbc/issues/282)) ([0065a9b](https://www.github.com/googleapis/java-spanner-jdbc/commit/0065a9b319b09e71bf285f85c33514442a163dea))
+
+
+### Dependencies
+
+* do not re-declare grpc dependencies as test dependencies ([#278](https://www.github.com/googleapis/java-spanner-jdbc/issues/278)) ([4bc59f8](https://www.github.com/googleapis/java-spanner-jdbc/commit/4bc59f8d7f27cee0bbc54b91271e2aadd7cb31da))
+* update dependency com.google.cloud:google-cloud-shared-dependencies to v0.16.0 ([#286](https://www.github.com/googleapis/java-spanner-jdbc/issues/286)) ([2d804f5](https://www.github.com/googleapis/java-spanner-jdbc/commit/2d804f5b52271356598588764c77d1a13f3b7183))
+* update dependency com.google.cloud:google-cloud-spanner-bom to v3 ([#260](https://www.github.com/googleapis/java-spanner-jdbc/issues/260)) ([40cdbc0](https://www.github.com/googleapis/java-spanner-jdbc/commit/40cdbc01c91c153c8c3fd36cf7bf91d80b187f03))
+* update dependency com.google.cloud:google-cloud-spanner-bom to v3.0.5 ([#287](https://www.github.com/googleapis/java-spanner-jdbc/issues/287)) ([9cef4d5](https://www.github.com/googleapis/java-spanner-jdbc/commit/9cef4d57f6b63caba71ba77160677f73569a8fea))
+
### [1.17.3](https://www.github.com/googleapis/java-spanner-jdbc/compare/v1.17.2...v1.17.3) (2020-11-17)
diff --git a/README.md b/README.md
index 3bbc90762..5df90dbc1 100644
--- a/README.md
+++ b/README.md
@@ -17,17 +17,17 @@ If you are using Maven, add this to your pom.xml file:
com.google.cloud
google-cloud-spanner-jdbc
- 1.17.0
+ 1.17.3
```
If you are using Gradle, add this to your dependencies
```Groovy
-compile 'com.google.cloud:google-cloud-spanner-jdbc:1.17.0'
+compile 'com.google.cloud:google-cloud-spanner-jdbc:1.17.3'
```
If you are using SBT, add this to your dependencies
```Scala
-libraryDependencies += "com.google.cloud" % "google-cloud-spanner-jdbc" % "1.17.0"
+libraryDependencies += "com.google.cloud" % "google-cloud-spanner-jdbc" % "1.17.3"
```
## Authentication
@@ -58,6 +58,31 @@ See the [Google Cloud Spanner JDBC client library docs][javadocs] to learn how t
use this Google Cloud Spanner JDBC Client Library.
+### Creating a JDBC Connection
+
+The following example shows how to create a JDBC connection to Cloud Spanner and execute a simple query.
+
+```java
+String projectId = "my-project";
+String instanceId = "my-instance";
+String databaseId = "my-database";
+
+try (Connection connection =
+ DriverManager.getConnection(
+ String.format(
+ "jdbc:cloudspanner:/projects/%s/instances/%s/databases/%s",
+ projectId, instanceId, databaseId))) {
+ try (Statement statement = connection.createStatement()) {
+ try (ResultSet rs = statement.executeQuery("SELECT CURRENT_TIMESTAMP()")) {
+ while (rs.next()) {
+ System.out.printf(
+ "Connected to Cloud Spanner at [%s]%n", rs.getTimestamp(1).toString());
+ }
+ }
+ }
+}
+```
+
@@ -101,7 +126,9 @@ Java 8 OSX | [![Kokoro CI][kokoro-badge-image-3]][kokoro-badge-link-3]
Java 8 Windows | [![Kokoro CI][kokoro-badge-image-4]][kokoro-badge-link-4]
Java 11 | [![Kokoro CI][kokoro-badge-image-5]][kokoro-badge-link-5]
-[product-docs]: https://cloud.google.com/pubsub/docs/
+Java is a registered trademark of Oracle and/or its affiliates.
+
+[product-docs]: https://cloud.google.com/spanner/docs/use-oss-jdbc
[javadocs]: https://googleapis.dev/java/google-cloud-spanner-jdbc/latest/index.html
[kokoro-badge-image-1]: http://storage.googleapis.com/cloud-devrel-public/java/badges/java-spanner-jdbc/java7.svg
[kokoro-badge-link-1]: http://storage.googleapis.com/cloud-devrel-public/java/badges/java-spanner-jdbc/java7.html
diff --git a/clirr-ignored-differences.xml b/clirr-ignored-differences.xml
index cfa113659..7e2437739 100644
--- a/clirr-ignored-differences.xml
+++ b/clirr-ignored-differences.xml
@@ -42,4 +42,56 @@
8001
com/google/cloud/spanner/jdbc/UnitOfWork$UnitOfWorkState
+
+
+
+ 7012
+ com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection
+ com.google.cloud.spanner.connection.AutocommitDmlMode getAutocommitDmlMode()
+
+
+ 7012
+ com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection
+ java.lang.String getOptimizerVersion()
+
+
+ 7012
+ com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection
+ com.google.cloud.spanner.TimestampBound getReadOnlyStaleness()
+
+
+ 7012
+ com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection
+ com.google.cloud.spanner.connection.TransactionMode getTransactionMode()
+
+
+ 7012
+ com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection
+ boolean isInTransaction()
+
+
+ 7012
+ com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection
+ boolean isTransactionStarted()
+
+
+ 7012
+ com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection
+ void setAutocommitDmlMode(com.google.cloud.spanner.connection.AutocommitDmlMode)
+
+
+ 7012
+ com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection
+ void setOptimizerVersion(java.lang.String)
+
+
+ 7012
+ com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection
+ void setReadOnlyStaleness(com.google.cloud.spanner.TimestampBound)
+
+
+ 7012
+ com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection
+ void setTransactionMode(com.google.cloud.spanner.connection.TransactionMode)
+
diff --git a/pom.xml b/pom.xml
index 659183364..40cc28c15 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
- 1.17.3
+ 1.18.0
jar
Google Cloud Spanner JDBC
https://github.com/googleapis/java-spanner-jdbc
@@ -61,7 +61,7 @@
4.13.1
3.0.2
1.4.4
- 1.0.1
+ 1.1
1.10.19
2.2
@@ -71,14 +71,14 @@
com.google.cloud
google-cloud-spanner-bom
- 2.0.2
+ 3.0.5
pom
import
com.google.cloud
google-cloud-shared-dependencies
- 0.15.0
+ 0.16.0
pom
import
@@ -147,9 +147,9 @@
com.google.api.grpc
- grpc-google-cloud-spanner-v1
+ proto-google-cloud-spanner-v1
-
+
com.google.cloud
@@ -157,21 +157,6 @@
test-jar
test
-
- com.google.api.grpc
- grpc-google-cloud-spanner-v1
- test
-
-
- com.google.api.grpc
- grpc-google-cloud-spanner-admin-instance-v1
- test
-
-
- com.google.api.grpc
- grpc-google-cloud-spanner-admin-database-v1
- test
-
com.google.truth
truth
diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml
index 72e625fbd..f6888f0e5 100644
--- a/samples/install-without-bom/pom.xml
+++ b/samples/install-without-bom/pom.xml
@@ -29,7 +29,7 @@
com.google.cloud
google-cloud-spanner-jdbc
- 1.17.0
+ 1.17.3
diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml
index d062d58e5..d8d1386b9 100644
--- a/samples/snapshot/pom.xml
+++ b/samples/snapshot/pom.xml
@@ -28,7 +28,7 @@
com.google.cloud
google-cloud-spanner-jdbc
- 1.17.3
+ 1.18.0
diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml
index a21d7304d..974bf1c3a 100644
--- a/samples/snippets/pom.xml
+++ b/samples/snippets/pom.xml
@@ -30,7 +30,7 @@
com.google.cloud
libraries-bom
- 15.1.0
+ 16.1.0
pom
import
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 dc52ca355..f13a64f5b 100644
--- a/src/main/java/com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection.java
+++ b/src/main/java/com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection.java
@@ -19,6 +19,9 @@
import com.google.cloud.spanner.AbortedException;
import com.google.cloud.spanner.Mutation;
import com.google.cloud.spanner.ResultSet;
+import com.google.cloud.spanner.TimestampBound;
+import com.google.cloud.spanner.connection.AutocommitDmlMode;
+import com.google.cloud.spanner.connection.TransactionMode;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Timestamp;
@@ -34,6 +37,113 @@
*/
public interface CloudSpannerJdbcConnection extends Connection {
+ /**
+ * 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
+ * have been executed in the transaction.
+ *
+ * @param transactionMode The transaction mode to use for the current transaction.
+ *
+ * - {@link TransactionMode#READ_ONLY_TRANSACTION} will create a read-only transaction and
+ * prevent any changes to written to the database through this transaction. The read
+ * timestamp to be used will be determined based on the current readOnlyStaleness
+ * setting of this connection. It is recommended to use {@link
+ * TransactionMode#READ_ONLY_TRANSACTION} instead of {@link
+ * TransactionMode#READ_WRITE_TRANSACTION} when possible, as read-only transactions do
+ * not acquire locks on Cloud Spanner, and read-only transactions never abort.
+ *
- {@link TransactionMode#READ_WRITE_TRANSACTION} this value is only allowed when the
+ * connection is not in read-only mode and will create a read-write transaction. If
+ * {@link Connection#isRetryAbortsInternally()} is
true, each read/write
+ * transaction will keep track of a running SHA256 checksum for each {@link ResultSet}
+ * that is returned in order to be able to retry the transaction in case the transaction
+ * is aborted by Spanner.
+ *
+ */
+ void setTransactionMode(TransactionMode transactionMode) throws SQLException;
+
+ /**
+ * @return the transaction mode of the current transaction. This method may only be called when
+ * the connection is in a transaction.
+ */
+ TransactionMode getTransactionMode() throws SQLException;
+
+ /**
+ * Sets the mode for executing DML statements in autocommit mode for this connection. This setting
+ * is only used when the connection is in autocommit mode, and may only be set while the
+ * transaction is in autocommit mode and not in a temporary transaction. The autocommit
+ * transaction mode is reset to its default value of {@link AutocommitDmlMode#TRANSACTIONAL} when
+ * autocommit mode is changed on the connection.
+ *
+ * @param mode The DML autocommit mode to use
+ *
+ * - {@link AutocommitDmlMode#TRANSACTIONAL} DML statements are executed as single
+ * read-write transaction. After successful execution, the DML statement is guaranteed
+ * to have been applied exactly once to the database
+ *
- {@link AutocommitDmlMode#PARTITIONED_NON_ATOMIC} DML statements are executed as
+ * partitioned DML transactions. If an error occurs during the execution of the DML
+ * statement, it is possible that the statement has been applied to some but not all of
+ * the rows specified in the statement.
+ *
+ */
+ void setAutocommitDmlMode(AutocommitDmlMode mode) throws SQLException;
+
+ /**
+ * @return the current {@link AutocommitDmlMode} setting for this connection. This method may only
+ * be called on a connection that is in autocommit mode and not while in a temporary
+ * transaction.
+ */
+ AutocommitDmlMode getAutocommitDmlMode() throws SQLException;
+
+ /**
+ * Sets the staleness to use for the current read-only transaction. This method may only be called
+ * when the transaction mode of the current transaction is {@link
+ * TransactionMode#READ_ONLY_TRANSACTION} and there is no transaction that has started, or when
+ * the connection is in read-only and autocommit mode.
+ *
+ * @param staleness The staleness to use for the current but not yet started read-only transaction
+ */
+ void setReadOnlyStaleness(TimestampBound staleness) throws SQLException;
+
+ /**
+ * @return the read-only staleness setting for the current read-only transaction. This method may
+ * only be called when the current transaction is a read-only transaction, or when the
+ * connection is in read-only and autocommit mode.
+ */
+ TimestampBound getReadOnlyStaleness() throws SQLException;
+
+ /**
+ * Sets the query optimizer version to use for this connection.
+ *
+ * @param optimizerVersion The query optimizer version to use. Must be a valid optimizer version
+ * number, the string LATEST or an empty string. The empty string will instruct
+ * the connection to use the optimizer version that is defined in the environment variable
+ * SPANNER_OPTIMIZER_VERSION. If no value is specified in the environment
+ * variable, the default query optimizer of Cloud Spanner is used.
+ */
+ void setOptimizerVersion(String optimizerVersion) throws SQLException;
+
+ /**
+ * Gets the current query optimizer version of this connection.
+ *
+ * @return The query optimizer version that is currently used by this connection.
+ */
+ String getOptimizerVersion() throws SQLException;
+
+ /**
+ * @return true if this connection has a transaction (that has not necessarily
+ * started). This method will only return false when the {@link Connection} is in autocommit
+ * mode and no explicit transaction has been started by calling {@link
+ * Connection#beginTransaction()}. If the {@link Connection} is not in autocommit mode, there
+ * will always be a transaction.
+ */
+ boolean isInTransaction() throws SQLException;
+
+ /**
+ * @return true if this connection has a transaction that has started. A transaction
+ * is automatically started by the first statement that is executed in the transaction.
+ */
+ boolean isTransactionStarted() throws SQLException;
+
/**
* @return the commit {@link Timestamp} of the last read/write transaction. If the last
* transaction was not a read/write transaction, or a read/write transaction that did not
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 4e2318092..3d79c5efb 100644
--- a/src/main/java/com/google/cloud/spanner/jdbc/JdbcConnection.java
+++ b/src/main/java/com/google/cloud/spanner/jdbc/JdbcConnection.java
@@ -19,8 +19,11 @@
import com.google.api.client.util.Preconditions;
import com.google.cloud.spanner.Mutation;
import com.google.cloud.spanner.SpannerException;
+import com.google.cloud.spanner.TimestampBound;
+import com.google.cloud.spanner.connection.AutocommitDmlMode;
import com.google.cloud.spanner.connection.ConnectionOptions;
import com.google.cloud.spanner.connection.StatementParser;
+import com.google.cloud.spanner.connection.TransactionMode;
import com.google.common.base.Function;
import com.google.common.collect.Iterators;
import java.sql.Array;
@@ -74,6 +77,66 @@ public String nativeSQL(String sql) throws SQLException {
.sqlWithNamedParameters;
}
+ @Override
+ public void setTransactionMode(TransactionMode mode) throws SQLException {
+ checkClosed();
+ getSpannerConnection().setTransactionMode(mode);
+ }
+
+ @Override
+ public TransactionMode getTransactionMode() throws SQLException {
+ checkClosed();
+ return getSpannerConnection().getTransactionMode();
+ }
+
+ @Override
+ public void setAutocommitDmlMode(AutocommitDmlMode mode) throws SQLException {
+ checkClosed();
+ getSpannerConnection().setAutocommitDmlMode(mode);
+ }
+
+ @Override
+ public AutocommitDmlMode getAutocommitDmlMode() throws SQLException {
+ checkClosed();
+ return getSpannerConnection().getAutocommitDmlMode();
+ }
+
+ @Override
+ public void setReadOnlyStaleness(TimestampBound staleness) throws SQLException {
+ checkClosed();
+ getSpannerConnection().setReadOnlyStaleness(staleness);
+ }
+
+ @Override
+ public TimestampBound getReadOnlyStaleness() throws SQLException {
+ checkClosed();
+ return getSpannerConnection().getReadOnlyStaleness();
+ }
+
+ @Override
+ public void setOptimizerVersion(String optimizerVersion) throws SQLException {
+ checkClosed();
+ getSpannerConnection().setOptimizerVersion(optimizerVersion);
+ }
+
+ @Override
+ public String getOptimizerVersion() throws SQLException {
+ checkClosed();
+ return getSpannerConnection().getOptimizerVersion();
+ }
+
+ @Override
+ public boolean isInTransaction() throws SQLException {
+ checkClosed();
+ return getSpannerConnection().isInTransaction();
+ }
+
+ @Override
+ public boolean isTransactionStarted() throws SQLException {
+ checkClosed();
+ return getSpannerConnection().isTransactionStarted();
+ }
+
@Override
public void setAutoCommit(boolean autoCommit) throws SQLException {
checkClosed();
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 8b29c15b1..69b1f6a8e 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
@@ -72,7 +72,10 @@ SELECT TABLE_CATALOG AS TABLE_CAT, TABLE_SCHEMA AS TABLE_SCHEM, TABLE_NAME, COLU
NULL AS SCOPE_TABLE,
NULL AS SOURCE_DATA_TYPE,
'NO' AS IS_AUTOINCREMENT,
- 'NO' AS IS_GENERATEDCOLUMN
+ CASE
+ WHEN (IS_GENERATED = 'NEVER') THEN 'NO'
+ ELSE 'YES'
+ END AS IS_GENERATEDCOLUMN
FROM INFORMATION_SCHEMA.COLUMNS C
WHERE UPPER(C.TABLE_CATALOG) LIKE ?
AND UPPER(C.TABLE_SCHEMA) LIKE ?
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 711363c29..755539987 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
@@ -25,6 +25,7 @@
import com.google.cloud.spanner.IntegrationTest;
import com.google.cloud.spanner.jdbc.ITAbstractJdbcTest;
+import com.google.cloud.spanner.testing.EmulatorSpannerHelper;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
@@ -53,7 +54,8 @@ public class ITJdbcDatabaseMetaDataTest extends ITAbstractJdbcTest {
@BeforeClass
public static void skipOnEmulator() {
- assumeFalse("foreign keys are not supported on the emulator", env.getTestHelper().isEmulator());
+ assumeFalse(
+ "foreign keys are not supported on the emulator", EmulatorSpannerHelper.isUsingEmulator());
}
@Override
@@ -70,6 +72,7 @@ private static final class Column {
private final Integer radix;
private final boolean nullable;
private final Integer charOctetLength;
+ private final boolean computed;
private Column(
String name,
@@ -80,6 +83,19 @@ private Column(
Integer radix,
boolean nullable,
Integer charOctetLength) {
+ this(name, type, typeName, colSize, decimalDigits, radix, nullable, charOctetLength, false);
+ }
+
+ private Column(
+ String name,
+ int type,
+ String typeName,
+ Integer colSize,
+ Integer decimalDigits,
+ Integer radix,
+ boolean nullable,
+ Integer charOctetLength,
+ boolean computed) {
this.name = name;
this.type = type;
this.typeName = typeName;
@@ -88,6 +104,7 @@ private Column(
this.radix = radix;
this.nullable = nullable;
this.charOctetLength = charOctetLength;
+ this.computed = computed;
}
}
@@ -133,7 +150,17 @@ private Column(
new Column("ColDateArray", Types.ARRAY, "ARRAY", 10, null, null, true, null),
new Column(
"ColTimestampArray", Types.ARRAY, "ARRAY", 35, null, null, true, null),
- new Column("ColNumericArray", Types.ARRAY, "ARRAY", 15, null, 10, true, null));
+ new Column("ColNumericArray", Types.ARRAY, "ARRAY", 15, null, 10, true, null),
+ new Column(
+ "ColComputed",
+ Types.NVARCHAR,
+ "STRING(MAX)",
+ 2621440,
+ null,
+ null,
+ true,
+ 2621440,
+ true));
@Test
public void testGetColumns() throws SQLException {
@@ -195,7 +222,7 @@ public void testGetColumns() throws SQLException {
assertThat(rs.getShort("SOURCE_DATA_TYPE"), is(equalTo((short) 0)));
assertThat(rs.wasNull(), is(true));
assertThat(rs.getString("IS_AUTOINCREMENT"), is(equalTo("NO")));
- assertThat(rs.getString("IS_GENERATEDCOLUMN"), is(equalTo("NO")));
+ assertThat(rs.getString("IS_GENERATEDCOLUMN"), is(equalTo(col.computed ? "YES" : "NO")));
assertThat(rs.getMetaData().getColumnCount(), is(equalTo(24)));
pos++;
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 4d05cdfb5..6a8c4616d 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
@@ -84,7 +84,9 @@ CREATE TABLE TableWithAllColumnTypes (
ColBytesMaxArray ARRAY,
ColDateArray ARRAY,
ColTimestampArray ARRAY,
- ColNumericArray ARRAY
+ ColNumericArray ARRAY,
+
+ ColComputed STRING(MAX) AS (CONCAT(COALESCE(ColString, ''), ' ', COALESCE(ColStringMax, ''))) STORED,
) PRIMARY KEY (ColInt64)
;
diff --git a/synth.metadata b/synth.metadata
index 73444be09..f231fec1c 100644
--- a/synth.metadata
+++ b/synth.metadata
@@ -4,14 +4,14 @@
"git": {
"name": ".",
"remote": "https://github.com/googleapis/java-spanner-jdbc.git",
- "sha": "96bb531c9ef8499b815bdb13cb07363da0e4f293"
+ "sha": "5531536d406e1fe3043a9d379c8102f1b0a5ade7"
}
},
{
"git": {
"name": "synthtool",
"remote": "https://github.com/googleapis/synthtool.git",
- "sha": "7d652819519dfa24da9e14548232e4aaba71a11c"
+ "sha": "5d11bd2888c38ce1fb6fa6bf25494a4219a73928"
}
}
],
@@ -21,6 +21,7 @@
".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",
diff --git a/versions.txt b/versions.txt
index e2424ad95..453fd664f 100644
--- a/versions.txt
+++ b/versions.txt
@@ -1,4 +1,4 @@
# Format:
# module:released-version:current-version
-google-cloud-spanner-jdbc:1.17.3:1.17.3
+google-cloud-spanner-jdbc:1.18.0:1.18.0