From c13a1200465a5bde4695d78e8ac95c8e32122ee4 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Fri, 21 Feb 2025 17:58:25 +0000 Subject: [PATCH 01/13] chore(main): release 2.27.1-SNAPSHOT (#1928) :robot: I have created a release *beep* *boop* --- ### Updating meta-information for bleeding-edge SNAPSHOT release. --- This PR was generated with [Release Please](https://togithub.com/googleapis/release-please). See [documentation](https://togithub.com/googleapis/release-please#release-please). --- pom.xml | 2 +- samples/snapshot/pom.xml | 2 +- versions.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 972790d25..b59795d6a 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.27.0 + 2.27.1-SNAPSHOT jar Google Cloud Spanner JDBC https://github.com/googleapis/java-spanner-jdbc diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index e6a944729..acab38c1c 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -29,7 +29,7 @@ com.google.cloud google-cloud-spanner-jdbc - 2.27.0 + 2.27.1-SNAPSHOT diff --git a/versions.txt b/versions.txt index fcd51f942..e675c53a8 100644 --- a/versions.txt +++ b/versions.txt @@ -1,4 +1,4 @@ # Format: # module:released-version:current-version -google-cloud-spanner-jdbc:2.27.0:2.27.0 +google-cloud-spanner-jdbc:2.27.0:2.27.1-SNAPSHOT From 21cd68b8128ba605a98c799d1c3886e9abe59bc9 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 27 Feb 2025 13:08:14 +0100 Subject: [PATCH 02/13] build(deps): update dependency org.apache.maven.plugins:maven-project-info-reports-plugin to v3.9.0 (#1933) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b59795d6a..ef72fd3e7 100644 --- a/pom.xml +++ b/pom.xml @@ -468,7 +468,7 @@ org.apache.maven.plugins maven-project-info-reports-plugin - 3.8.0 + 3.9.0 From 5cc7e3dcc4aaa53a81b4b45146ca8d6861063cb4 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 27 Feb 2025 13:08:37 +0100 Subject: [PATCH 03/13] build(deps): update dependency org.apache.maven.plugins:maven-deploy-plugin to v3.1.4 (#1932) --- samples/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/pom.xml b/samples/pom.xml index bfe9954b2..c36572ade 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -39,7 +39,7 @@ org.apache.maven.plugins maven-deploy-plugin - 3.1.3 + 3.1.4 true From 1e06aa434f324e87cd218e9babe2235ad9368511 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 27 Feb 2025 13:08:54 +0100 Subject: [PATCH 04/13] chore(deps): update dependency com.google.cloud:libraries-bom to v26.55.0 (#1930) --- samples/quickperf/pom.xml | 2 +- samples/snippets/pom.xml | 2 +- samples/spring-data-jdbc/pom.xml | 2 +- samples/spring-data-mybatis/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/samples/quickperf/pom.xml b/samples/quickperf/pom.xml index 31a5cb50c..0dc69e62f 100644 --- a/samples/quickperf/pom.xml +++ b/samples/quickperf/pom.xml @@ -27,7 +27,7 @@ com.google.cloud libraries-bom - 26.54.0 + 26.55.0 pom import diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 6e5560f6e..a6778c65b 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -26,7 +26,7 @@ com.google.cloud libraries-bom - 26.54.0 + 26.55.0 pom import diff --git a/samples/spring-data-jdbc/pom.xml b/samples/spring-data-jdbc/pom.xml index a9a18f70e..b9d7379df 100644 --- a/samples/spring-data-jdbc/pom.xml +++ b/samples/spring-data-jdbc/pom.xml @@ -37,7 +37,7 @@ com.google.cloud libraries-bom - 26.54.0 + 26.55.0 import pom diff --git a/samples/spring-data-mybatis/pom.xml b/samples/spring-data-mybatis/pom.xml index 1e6f6ac62..f556e1f68 100644 --- a/samples/spring-data-mybatis/pom.xml +++ b/samples/spring-data-mybatis/pom.xml @@ -35,7 +35,7 @@ com.google.cloud libraries-bom - 26.54.0 + 26.55.0 import pom From 74100a01989e2066b993faf2b2fd7da269c7a685 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 27 Feb 2025 13:09:16 +0100 Subject: [PATCH 05/13] chore(deps): update dependency com.google.cloud:google-cloud-spanner-jdbc to v2.27.0 (#1929) --- samples/install-without-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml index ef9e179f9..9456eaec5 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 - 2.26.1 + 2.27.0 From c30b09ab554d57adccaee72c36969407bbb1d4dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Thu, 27 Feb 2025 13:18:53 +0100 Subject: [PATCH 06/13] docs: add defaultSequenceKind connection property documentation (#1935) Adds documentation for the defaultSequenceKind connection property. --- documentation/connection_properties.md | 1 + 1 file changed, 1 insertion(+) diff --git a/documentation/connection_properties.md b/documentation/connection_properties.md index 52938f4ef..887278da1 100644 --- a/documentation/connection_properties.md +++ b/documentation/connection_properties.md @@ -22,6 +22,7 @@ The 'Context' value indicates whether the property can only be set when a connec | databaserole | Sets the database role to use for this connection. The default is privileges assigned to IAM role | | | STARTUP | | databoostenabled | Enable data boost for all partitioned queries that are executed by this connection. This setting is only used for partitioned queries and is ignored by all other statements. | false | true, false | USER | | ddlintransactionmode | Determines how the connection should handle DDL statements in a read/write transaction. | ALLOW_IN_EMPTY_TRANSACTION | FAIL, ALLOW_IN_EMPTY_TRANSACTION, AUTO_COMMIT_TRANSACTION | USER | +| defaultsequencekind | The default sequence kind that should be used for the database. This property is only used when a DDL statement that requires a default sequence kind is executed on this connection. | | | USER | | delaytransactionstartuntilfirstwrite | Enabling this option will delay the actual start of a read/write transaction until the first write operation is seen in that transaction. All reads that happen before the first write in a transaction will instead be executed as if the connection was in auto-commit mode. Enabling this option will make read/write transactions lose their SERIALIZABLE isolation level. Read operations that are executed after the first write operation in a read/write transaction will be executed using the read/write transaction. Enabling this mode can reduce locking and improve performance for applications that can handle the lower transaction isolation semantics. | false | true, false | USER | | dialect | Sets the dialect to use for new databases that are created by this connection. | GOOGLE_STANDARD_SQL | GOOGLE_STANDARD_SQL, POSTGRESQL | STARTUP | | directed_read | The directed read options to apply to read-only transactions. | | | USER | From 98eb542201330188570ef995e38fa2a690e1160f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Thu, 27 Feb 2025 15:09:51 +0100 Subject: [PATCH 07/13] fix: include COLUMN_DEFAULT in the returned metadata (#1937) Include the COLUMN_DEFAULT value in the DatabaseMetaData that is returned for the getColumns() method. These were missing, as Spanner previously did not support default values. --- .../jdbc/DatabaseMetaData_GetColumns.sql | 2 +- .../DatabaseMetaData_GetColumns.sql | 2 +- .../jdbc/it/ITJdbcDatabaseMetaDataTest.java | 130 ++++++++++++++---- .../spanner/jdbc/it/CreateMusicTables.sql | 10 +- 4 files changed, 112 insertions(+), 32 deletions(-) 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 94d2a0e61..b59f3b78a 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 @@ -63,7 +63,7 @@ SELECT TABLE_CATALOG AS TABLE_CAT, TABLE_SCHEMA AS TABLE_SCHEM, TABLE_NAME, COLU ELSE 2 END AS NULLABLE, NULL AS REMARKS, - NULL AS COLUMN_DEF, + COLUMN_DEFAULT AS COLUMN_DEF, 0 AS SQL_DATA_TYPE, 0 AS SQL_DATETIME_SUB, CASE diff --git a/src/main/resources/com/google/cloud/spanner/jdbc/postgresql/DatabaseMetaData_GetColumns.sql b/src/main/resources/com/google/cloud/spanner/jdbc/postgresql/DatabaseMetaData_GetColumns.sql index 38c105108..5924f980f 100644 --- a/src/main/resources/com/google/cloud/spanner/jdbc/postgresql/DatabaseMetaData_GetColumns.sql +++ b/src/main/resources/com/google/cloud/spanner/jdbc/postgresql/DatabaseMetaData_GetColumns.sql @@ -62,7 +62,7 @@ SELECT TABLE_CATALOG AS "TABLE_CAT", TABLE_SCHEMA AS "TABLE_SCHEM", TABLE_NAME A ELSE 2 END AS "NULLABLE", NULL AS "REMARKS", - NULL AS "COLUMN_DEF", + COLUMN_DEFAULT AS "COLUMN_DEF", 0 AS "SQL_DATA_TYPE", 0 AS "SQL_DATETIME_SUB", CHARACTER_MAXIMUM_LENGTH AS "CHAR_OCTET_LENGTH", 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 94d9ad140..0ebd0031a 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 @@ -21,7 +21,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeFalse; import com.google.cloud.spanner.Database; import com.google.cloud.spanner.DatabaseAdminClient; @@ -62,10 +61,6 @@ public class ITJdbcDatabaseMetaDataTest extends ITAbstractJdbcTest { @BeforeClass public static void setup() throws Exception { - assumeFalse( - "Named schemas are not yet supported on the emulator", - EmulatorSpannerHelper.isUsingEmulator()); - database = env.getOrCreateDatabase( Dialect.GOOGLE_STANDARD_SQL, getMusicTablesDdl(Dialect.GOOGLE_STANDARD_SQL)); @@ -89,6 +84,18 @@ public static void setup() throws Exception { .map(statement -> statement.replace(" ON ", " ON test.")) .map(statement -> statement.replace(" ON test.DELETE", " ON DELETE")) .map(statement -> statement.replace(" REFERENCES ", " REFERENCES test.")) + .map( + statement -> + EmulatorSpannerHelper.isUsingEmulator() + ? statement.replace("Fk_Concerts_Singer", "test_Fk_Concerts_Singer") + : statement) + .map( + statement -> + EmulatorSpannerHelper.isUsingEmulator() + ? statement.replace( + "Fk_TableWithRef_TableWithAllColumnTypes", + "test_Fk_TableWithRef_TableWithAllColumnTypes") + : statement) .collect(Collectors.toList()); tables.add(0, "create schema test"); client @@ -110,6 +117,7 @@ private static final class Column { private final boolean nullable; private final Integer charOctetLength; private final boolean computed; + private final String defaultValue; private Column( String name, @@ -120,7 +128,17 @@ private Column( Integer radix, boolean nullable, Integer charOctetLength) { - this(name, type, typeName, colSize, decimalDigits, radix, nullable, charOctetLength, false); + this( + name, + type, + typeName, + colSize, + decimalDigits, + radix, + nullable, + charOctetLength, + false, + null); } private Column( @@ -132,7 +150,8 @@ private Column( Integer radix, boolean nullable, Integer charOctetLength, - boolean computed) { + boolean computed, + String defaultValue) { this.name = name; this.type = type; this.typeName = typeName; @@ -142,21 +161,42 @@ private Column( this.nullable = nullable; this.charOctetLength = charOctetLength; this.computed = computed; + this.defaultValue = defaultValue; } } private static final List EXPECTED_COLUMNS = Arrays.asList( new Column("ColInt64", Types.BIGINT, "INT64", 19, null, 10, false, null), - new Column("ColFloat64", Types.DOUBLE, "FLOAT64", 15, 16, 2, false, null), - new Column("ColFloat32", Types.REAL, "FLOAT32", 15, 16, 2, false, null), + new Column("ColFloat64", Types.DOUBLE, "FLOAT64", 15, 16, 2, false, null, false, "0.0"), + new Column("ColFloat32", Types.REAL, "FLOAT32", 15, 16, 2, false, null, false, "0.0"), new Column("ColBool", Types.BOOLEAN, "BOOL", null, null, null, false, null), - new Column("ColString", Types.NVARCHAR, "STRING(100)", 100, null, null, false, 100), + new Column( + "ColString", + Types.NVARCHAR, + "STRING(100)", + 100, + null, + null, + false, + 100, + false, + "'Hello World!'"), new Column( "ColStringMax", Types.NVARCHAR, "STRING(MAX)", 2621440, null, null, false, 2621440), new Column("ColBytes", Types.BINARY, "BYTES(100)", 100, null, null, false, null), new Column("ColBytesMax", Types.BINARY, "BYTES(MAX)", 10485760, null, null, false, null), - new Column("ColDate", Types.DATE, "DATE", 10, null, null, false, null), + new Column( + "ColDate", + Types.DATE, + "DATE", + 10, + null, + null, + false, + null, + false, + "DATE '2000-01-01'"), 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), @@ -202,7 +242,8 @@ private Column( null, true, 2621440, - true)); + true, + null)); @Test public void testGetColumns() throws SQLException { @@ -244,7 +285,7 @@ public void testGetColumns() throws SQLException { col.nullable ? DatabaseMetaData.columnNullable : DatabaseMetaData.columnNoNulls, rs.getInt("NULLABLE")); assertNull(rs.getString("REMARKS")); - assertNull(rs.getString("COLUMN_DEF")); + assertEquals(col.defaultValue, rs.getString("COLUMN_DEF")); assertEquals(0, rs.getInt("SQL_DATA_TYPE")); assertEquals(0, rs.getInt("SQL_DATETIME_SUB")); if (col.charOctetLength == null) { @@ -360,7 +401,11 @@ public void testGetCrossReferences() throws SQLException { assertEquals(1, rs.getShort("KEY_SEQ")); assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getShort("UPDATE_RULE")); assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getShort("DELETE_RULE")); - assertEquals("Fk_Concerts_Singer", rs.getString("FK_NAME")); + if (EmulatorSpannerHelper.isUsingEmulator() && "test".equals(schema)) { + assertEquals("test_Fk_Concerts_Singer", rs.getString("FK_NAME")); + } else { + assertEquals("Fk_Concerts_Singer", rs.getString("FK_NAME")); + } assertEquals("PK_Singers", rs.getString("PK_NAME")); assertEquals(DatabaseMetaData.importedKeyNotDeferrable, rs.getShort("DEFERRABILITY")); assertFalse(rs.next()); @@ -389,7 +434,11 @@ public void testGetCrossReferences() throws SQLException { assertEquals(1, rs.getShort("KEY_SEQ")); assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getShort("UPDATE_RULE")); assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getShort("DELETE_RULE")); - assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + if (EmulatorSpannerHelper.isUsingEmulator() && "test".equals(schema)) { + assertEquals("test_Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } else { + assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } assertEquals(DatabaseMetaData.importedKeyNotDeferrable, rs.getShort("DEFERRABILITY")); assertTrue(rs.next()); @@ -404,7 +453,11 @@ public void testGetCrossReferences() throws SQLException { assertEquals(2, rs.getShort("KEY_SEQ")); assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getShort("UPDATE_RULE")); assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getShort("DELETE_RULE")); - assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + if (EmulatorSpannerHelper.isUsingEmulator() && "test".equals(schema)) { + assertEquals("test_Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } else { + assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } assertEquals(DatabaseMetaData.importedKeyNotDeferrable, rs.getShort("DEFERRABILITY")); assertTrue(rs.next()); @@ -419,7 +472,11 @@ public void testGetCrossReferences() throws SQLException { assertEquals(3, rs.getShort("KEY_SEQ")); assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getShort("UPDATE_RULE")); assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getShort("DELETE_RULE")); - assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + if (EmulatorSpannerHelper.isUsingEmulator() && "test".equals(schema)) { + assertEquals("test_Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } else { + assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } assertEquals(DatabaseMetaData.importedKeyNotDeferrable, rs.getShort("DEFERRABILITY")); assertFalse(rs.next()); @@ -519,6 +576,12 @@ public void testGetIndexInfo() throws SQLException { connection.getMetaData().getIndexInfo(DEFAULT_CATALOG, schema, null, false, false)) { for (IndexInfo index : EXPECTED_INDICES) { + // The emulator does not generate indexes for foreign keys in a non-default schema. + if (EmulatorSpannerHelper.isUsingEmulator() + && "test".equals(schema) + && ("FOREIGN_KEY".equals(index.indexName) || "GENERATED".equals(index.indexName))) { + continue; + } assertTrue(rs.next()); assertEquals(DEFAULT_CATALOG, rs.getString("TABLE_CAT")); assertEquals(schema, rs.getString("TABLE_SCHEM")); @@ -612,7 +675,11 @@ private void assertImportedKeysTableWithRef(String schema, ResultSet rs) throws assertEquals(1, rs.getShort("KEY_SEQ")); assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("UPDATE_RULE")); assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("DELETE_RULE")); - assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + if (EmulatorSpannerHelper.isUsingEmulator() && "test".equals(schema)) { + assertEquals("test_Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } else { + assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } assertNotNull(rs.getString("PK_NAME")); // Index name is generated. assertEquals(DatabaseMetaData.importedKeyNotDeferrable, rs.getInt("DEFERRABILITY")); @@ -628,7 +695,11 @@ private void assertImportedKeysTableWithRef(String schema, ResultSet rs) throws assertEquals(2, rs.getShort("KEY_SEQ")); assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("UPDATE_RULE")); assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("DELETE_RULE")); - assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + if (EmulatorSpannerHelper.isUsingEmulator() && "test".equals(schema)) { + assertEquals("test_Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } else { + assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } assertNotNull(rs.getString("PK_NAME")); // Index name is generated. assertEquals(DatabaseMetaData.importedKeyNotDeferrable, rs.getInt("DEFERRABILITY")); @@ -644,7 +715,11 @@ private void assertImportedKeysTableWithRef(String schema, ResultSet rs) throws assertEquals(3, rs.getShort("KEY_SEQ")); assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("UPDATE_RULE")); assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("DELETE_RULE")); - assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + if (EmulatorSpannerHelper.isUsingEmulator() && "test".equals(schema)) { + assertEquals("test_Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } else { + assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } assertNotNull(rs.getString("PK_NAME")); // Index name is generated. assertEquals(DatabaseMetaData.importedKeyNotDeferrable, rs.getInt("DEFERRABILITY")); @@ -684,7 +759,11 @@ private void assertImportedKeysConcerts(String schema, ResultSet rs) throws SQLE assertEquals(1, rs.getShort("KEY_SEQ")); assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("UPDATE_RULE")); assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("DELETE_RULE")); - assertEquals("Fk_Concerts_Singer", rs.getString("FK_NAME")); + if (EmulatorSpannerHelper.isUsingEmulator() && "test".equals(schema)) { + assertEquals("test_Fk_Concerts_Singer", rs.getString("FK_NAME")); + } else { + assertEquals("Fk_Concerts_Singer", rs.getString("FK_NAME")); + } assertEquals("PK_Singers", rs.getString("PK_NAME")); assertEquals(DatabaseMetaData.importedKeyNotDeferrable, rs.getInt("DEFERRABILITY")); @@ -720,7 +799,11 @@ private void assertExportedKeysSingers(String schema, ResultSet rs) throws SQLEx assertEquals(1, rs.getShort("KEY_SEQ")); assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("UPDATE_RULE")); assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("DELETE_RULE")); - assertEquals("Fk_Concerts_Singer", rs.getString("FK_NAME")); + if (EmulatorSpannerHelper.isUsingEmulator() && "test".equals(schema)) { + assertEquals("test_Fk_Concerts_Singer", rs.getString("FK_NAME")); + } else { + assertEquals("Fk_Concerts_Singer", rs.getString("FK_NAME")); + } assertEquals("PK_Singers", rs.getString("PK_NAME")); assertEquals(DatabaseMetaData.importedKeyNotDeferrable, rs.getInt("DEFERRABILITY")); @@ -888,9 +971,6 @@ public void testGetTables() throws SQLException { try (ResultSet rs = connection.getMetaData().getTables(DEFAULT_CATALOG, schema, null, null)) { for (Table table : EXPECTED_TABLES) { - if (EmulatorSpannerHelper.isUsingEmulator() && table.name.equals("SingersView")) { - continue; - } assertTrue(rs.next()); assertEquals(DEFAULT_CATALOG, rs.getString("TABLE_CAT")); assertEquals(schema, rs.getString("TABLE_SCHEM")); 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 51f7d1ea1..8e4a60b24 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 @@ -49,7 +49,7 @@ CREATE TABLE Songs ( TrackId INT64 NOT NULL, SongName STRING(MAX), Duration INT64, - SongGenre STRING(25) + SongGenre STRING(25) DEFAULT ('Jazz') ) PRIMARY KEY(SingerId, AlbumId, TrackId), INTERLEAVE IN PARENT Albums ON DELETE CASCADE; @@ -69,14 +69,14 @@ CREATE TABLE Concerts ( CREATE TABLE TableWithAllColumnTypes ( ColInt64 INT64 NOT NULL, - ColFloat64 FLOAT64 NOT NULL, - ColFloat32 FLOAT32 NOT NULL, + ColFloat64 FLOAT64 NOT NULL DEFAULT (0.0), + ColFloat32 FLOAT32 NOT NULL DEFAULT (0.0), ColBool BOOL NOT NULL, - ColString STRING(100) NOT NULL, + ColString STRING(100) NOT NULL DEFAULT ('Hello World!'), ColStringMax STRING(MAX) NOT NULL, ColBytes BYTES(100) NOT NULL, ColBytesMax BYTES(MAX) NOT NULL, - ColDate DATE NOT NULL, + ColDate DATE NOT NULL DEFAULT (DATE '2000-01-01'), ColTimestamp TIMESTAMP NOT NULL, ColCommitTS TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true), ColNumeric NUMERIC NOT NULL, From f534f3a3cd1f3e41637a6041e9bd5e08149edc40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Thu, 27 Feb 2025 15:10:08 +0100 Subject: [PATCH 08/13] test: add tests for using multiplexed sessions (#1934) Add a couple of tests to verify that multiplexed sessions are being used by the JDBC driver when the environment variable has been set. --- .../spanner/jdbc/MultiplexedSessionsTest.java | 238 ++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 src/test/java/com/google/cloud/spanner/jdbc/MultiplexedSessionsTest.java diff --git a/src/test/java/com/google/cloud/spanner/jdbc/MultiplexedSessionsTest.java b/src/test/java/com/google/cloud/spanner/jdbc/MultiplexedSessionsTest.java new file mode 100644 index 000000000..b7b2d2869 --- /dev/null +++ b/src/test/java/com/google/cloud/spanner/jdbc/MultiplexedSessionsTest.java @@ -0,0 +1,238 @@ +/* + * Copyright 2025 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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeFalse; +import static org.junit.Assume.assumeTrue; + +import com.google.cloud.spanner.MockServerHelper; +import com.google.cloud.spanner.MockSpannerServiceImpl.StatementResult; +import com.google.cloud.spanner.connection.AbstractMockServerTest; +import com.google.common.base.Strings; +import com.google.protobuf.ListValue; +import com.google.protobuf.Value; +import com.google.spanner.v1.ExecuteSqlRequest; +import com.google.spanner.v1.ResultSetMetadata; +import com.google.spanner.v1.ResultSetStats; +import com.google.spanner.v1.StructType; +import com.google.spanner.v1.StructType.Field; +import com.google.spanner.v1.Type; +import com.google.spanner.v1.TypeCode; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Collections; +import java.util.Map; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class MultiplexedSessionsTest extends AbstractMockServerTest { + private static final String PROCESS_ENVIRONMENT = "java.lang.ProcessEnvironment"; + private static final String ENVIRONMENT = "theUnmodifiableEnvironment"; + private static final String SOURCE_MAP = "m"; + private static final Object STATIC_METHOD = null; + private static final Class UMODIFIABLE_MAP_CLASS = + Collections.unmodifiableMap(Collections.emptyMap()).getClass(); + private static final Class MAP_CLASS = Map.class; + + private static boolean setEnvVar = false; + + private String query; + private String dml; + private String dmlReturning; + + @SuppressWarnings("unchecked") + private static Map getModifiableEnvironment() throws Exception { + Class environmentClass = Class.forName(PROCESS_ENVIRONMENT); + java.lang.reflect.Field environmentField = environmentClass.getDeclaredField(ENVIRONMENT); + assertNotNull(environmentField); + environmentField.setAccessible(true); + + Object unmodifiableEnvironmentMap = environmentField.get(STATIC_METHOD); + assertNotNull(unmodifiableEnvironmentMap); + assertTrue(UMODIFIABLE_MAP_CLASS.isAssignableFrom(unmodifiableEnvironmentMap.getClass())); + + java.lang.reflect.Field underlyingMapField = + unmodifiableEnvironmentMap.getClass().getDeclaredField(SOURCE_MAP); + underlyingMapField.setAccessible(true); + Object underlyingMap = underlyingMapField.get(unmodifiableEnvironmentMap); + assertNotNull(underlyingMap); + assertTrue(MAP_CLASS.isAssignableFrom(underlyingMap.getClass())); + + return (Map) underlyingMap; + } + + @BeforeClass + public static void setEnvVars() throws Exception { + // Java versions 8 and lower start with 1. (1.8, 1.7 etc.). + // Higher versions start with the major version number. + // So this effectively verifies that the test is running on Java 8. + assumeTrue(System.getProperty("java.version", "undefined").startsWith("1.")); + assumeFalse(System.getProperty("os.name", "").toLowerCase().startsWith("windows")); + + if (Strings.isNullOrEmpty(System.getenv("GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS_FOR_RW"))) { + Map env = getModifiableEnvironment(); + env.put("GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS_FOR_RW", "true"); + setEnvVar = true; + } + } + + @AfterClass + public static void clearEnvVars() throws Exception { + if (setEnvVar) { + Map env = getModifiableEnvironment(); + env.remove("GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS_FOR_RW"); + } + } + + @Before + public void setupResults() { + query = "select * from my_table"; + dml = "insert into my_table (id, value) values (1, 'One')"; + String DML_THEN_RETURN_ID = dml + "\nTHEN RETURN `id`"; + dmlReturning = "insert into my_table (id, value) values (1, 'One') THEN RETURN *"; + + super.setupResults(); + + com.google.spanner.v1.ResultSet resultSet = + com.google.spanner.v1.ResultSet.newBuilder() + .setMetadata( + ResultSetMetadata.newBuilder() + .setRowType( + StructType.newBuilder() + .addFields( + Field.newBuilder() + .setType(Type.newBuilder().setCode(TypeCode.INT64).build()) + .setName("id") + .build()) + .addFields( + Field.newBuilder() + .setType(Type.newBuilder().setCode(TypeCode.STRING).build()) + .setName("value") + .build()) + .build()) + .build()) + .addRows( + ListValue.newBuilder() + .addValues(Value.newBuilder().setStringValue("1").build()) + .addValues(Value.newBuilder().setStringValue("One").build()) + .build()) + .build(); + com.google.spanner.v1.ResultSet returnIdResultSet = + com.google.spanner.v1.ResultSet.newBuilder() + .setMetadata( + ResultSetMetadata.newBuilder() + .setRowType( + StructType.newBuilder() + .addFields( + Field.newBuilder() + .setType(Type.newBuilder().setCode(TypeCode.INT64).build()) + .setName("id") + .build()) + .build()) + .build()) + .addRows( + ListValue.newBuilder() + .addValues(Value.newBuilder().setStringValue("1").build()) + .build()) + .build(); + mockSpanner.putStatementResult( + StatementResult.query(com.google.cloud.spanner.Statement.of(query), resultSet)); + mockSpanner.putStatementResult( + StatementResult.update(com.google.cloud.spanner.Statement.of(dml), 1L)); + mockSpanner.putStatementResult( + StatementResult.query( + com.google.cloud.spanner.Statement.of(dmlReturning), + resultSet + .toBuilder() + .setStats(ResultSetStats.newBuilder().setRowCountExact(1L).build()) + .build())); + mockSpanner.putStatementResult( + StatementResult.query( + com.google.cloud.spanner.Statement.of(DML_THEN_RETURN_ID), + returnIdResultSet + .toBuilder() + .setStats(ResultSetStats.newBuilder().setRowCountExact(1L).build()) + .build())); + } + + private String createUrl() { + return String.format( + "jdbc:cloudspanner://localhost:%d/projects/%s/instances/%s/databases/%s?usePlainText=true", + getPort(), "proj", "inst", "db"); + } + + @Override + protected Connection createJdbcConnection() throws SQLException { + return DriverManager.getConnection(createUrl()); + } + + @Test + public void testStatementExecuteQuery() throws SQLException { + try (Connection connection = createJdbcConnection(); + Statement statement = connection.createStatement()) { + try (ResultSet resultSet = statement.executeQuery(query)) { + //noinspection StatementWithEmptyBody + while (resultSet.next()) {} + } + } + assertEquals(1, mockSpanner.countRequestsOfType(ExecuteSqlRequest.class)); + ExecuteSqlRequest request = mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).get(0); + assertTrue(MockServerHelper.getSession(mockSpanner, request.getSession()).getMultiplexed()); + } + + @Test + public void testStatementExecuteUpdate() throws SQLException { + try (Connection connection = createJdbcConnection(); + Statement statement = connection.createStatement()) { + assertEquals(1, statement.executeUpdate(dml)); + } + assertEquals(1, mockSpanner.countRequestsOfType(ExecuteSqlRequest.class)); + ExecuteSqlRequest request = mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).get(0); + assertTrue(MockServerHelper.getSession(mockSpanner, request.getSession()).getMultiplexed()); + assertTrue(request.hasTransaction()); + assertTrue(request.getTransaction().hasBegin()); + assertTrue(request.getTransaction().getBegin().hasReadWrite()); + } + + @Test + public void testStatementExecuteQueryDmlReturning() throws SQLException { + try (Connection connection = createJdbcConnection(); + Statement statement = connection.createStatement()) { + try (ResultSet resultSet = statement.executeQuery(dmlReturning)) { + //noinspection StatementWithEmptyBody + while (resultSet.next()) {} + } + } + assertEquals(1, mockSpanner.countRequestsOfType(ExecuteSqlRequest.class)); + ExecuteSqlRequest request = mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).get(0); + assertTrue(MockServerHelper.getSession(mockSpanner, request.getSession()).getMultiplexed()); + assertTrue(request.hasTransaction()); + assertTrue(request.getTransaction().hasBegin()); + assertTrue(request.getTransaction().getBegin().hasReadWrite()); + } +} From 54580230f61584f0691730693497171ff9bfc734 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 28 Feb 2025 07:42:52 +0100 Subject: [PATCH 09/13] deps: update dependency com.google.api.grpc:proto-google-cloud-trace-v1 to v2.59.0 (#1938) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ef72fd3e7..89a17c43c 100644 --- a/pom.xml +++ b/pom.xml @@ -222,7 +222,7 @@ com.google.api.grpc proto-google-cloud-trace-v1 - 2.58.0 + 2.59.0 test From b31dd6e78b5f9b529b7cc7a9a34ea176231e22dc Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 28 Feb 2025 07:43:11 +0100 Subject: [PATCH 10/13] deps: update dependency com.google.cloud:google-cloud-trace to v2.59.0 (#1940) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 89a17c43c..1b87263cc 100644 --- a/pom.xml +++ b/pom.xml @@ -216,7 +216,7 @@ com.google.cloud google-cloud-trace - 2.58.0 + 2.59.0 test From 568a464f29055383b7930deb42505bedad506339 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 28 Feb 2025 09:05:58 +0100 Subject: [PATCH 11/13] deps: update dependency com.google.cloud:sdk-platform-java-config to v3.44.0 (#1931) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * deps: update dependency com.google.cloud:sdk-platform-java-config to v3.44.0 * chore: add more logging * test: skip timezone tests on GraalVM * chore: skip based on vendor name --------- Co-authored-by: Knut Olav Løite --- .../workflows/unmanaged_dependency_check.yaml | 2 +- .kokoro/presubmit/graalvm-native-17.cfg | 2 +- .kokoro/presubmit/graalvm-native.cfg | 2 +- pom.xml | 2 +- samples/quickperf/pom.xml | 2 +- samples/snippets/pom.xml | 2 +- .../jdbc/it/ITJdbcPreparedStatementTest.java | 27 +++++++++++++++++-- 7 files changed, 31 insertions(+), 8 deletions(-) diff --git a/.github/workflows/unmanaged_dependency_check.yaml b/.github/workflows/unmanaged_dependency_check.yaml index a48787484..7e8b94667 100644 --- a/.github/workflows/unmanaged_dependency_check.yaml +++ b/.github/workflows/unmanaged_dependency_check.yaml @@ -14,6 +14,6 @@ jobs: shell: bash run: .kokoro/build.sh - name: Unmanaged dependency check - uses: googleapis/sdk-platform-java/java-shared-dependencies/unmanaged-dependency-check@google-cloud-shared-dependencies/v3.43.0 + uses: googleapis/sdk-platform-java/java-shared-dependencies/unmanaged-dependency-check@google-cloud-shared-dependencies/v3.44.0 with: bom-path: pom.xml diff --git a/.kokoro/presubmit/graalvm-native-17.cfg b/.kokoro/presubmit/graalvm-native-17.cfg index 8d3f11dc4..728751d04 100644 --- a/.kokoro/presubmit/graalvm-native-17.cfg +++ b/.kokoro/presubmit/graalvm-native-17.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.43.0" + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.44.0" } env_vars: { diff --git a/.kokoro/presubmit/graalvm-native.cfg b/.kokoro/presubmit/graalvm-native.cfg index f78bafd26..39151469c 100644 --- a/.kokoro/presubmit/graalvm-native.cfg +++ b/.kokoro/presubmit/graalvm-native.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.43.0" + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.44.0" } env_vars: { diff --git a/pom.xml b/pom.xml index 1b87263cc..38792b7f5 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ com.google.cloud sdk-platform-java-config - 3.43.0 + 3.44.0 diff --git a/samples/quickperf/pom.xml b/samples/quickperf/pom.xml index 0dc69e62f..20eabefcf 100644 --- a/samples/quickperf/pom.xml +++ b/samples/quickperf/pom.xml @@ -12,7 +12,7 @@ com.google.cloud sdk-platform-java-config - 3.43.0 + 3.44.0 diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index a6778c65b..2135dd40e 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -9,7 +9,7 @@ com.google.cloud sdk-platform-java-config - 3.43.0 + 3.44.0 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 31a1a7f17..a26137b21 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 @@ -743,9 +743,21 @@ public void test04_Timestamps() throws SQLException { Timestamp inDefaultTZ = rs.getTimestamp(4); assertEquals(testTimestamp.getTime(), inDefaultTZ.getTime()); // Then get it in the test timezone. - if (testCalendar != null) { + if (testCalendar != null + && !System.getProperty("java.vm.name", "").toLowerCase().contains("graalvm") + && !System.getProperty("java.vendor", "").toLowerCase().contains("graalvm")) { Timestamp inOtherTZ = rs.getTimestamp(4, testCalendar); assertEquals( + "Timezone: " + + testCalendar + + ", rawOffset=" + + testCalendar.getTimeZone().getRawOffset() + + ", os=" + + System.getProperty("os.name") + + ", vm=" + + System.getProperty("java.vm.name") + + ", vendor=" + + System.getProperty("java.vendor"), testTimestamp.getTime() + testCalendar.getTimeZone().getRawOffset(), inOtherTZ.getTime()); } @@ -755,8 +767,19 @@ public void test04_Timestamps() throws SQLException { inDefaultTZ = rs.getTimestamp(5); if (testCalendar == null) { assertEquals(testTimestamp.getTime(), inDefaultTZ.getTime()); - } else { + } else if (!System.getProperty("java.vm.name", "").toLowerCase().contains("graalvm") + && !System.getProperty("java.vendor", "").toLowerCase().contains("graalvm")) { assertEquals( + "Timezone: " + + testCalendar + + ", rawOffset=" + + testCalendar.getTimeZone().getRawOffset() + + ", os=" + + System.getProperty("os.name") + + ", vm=" + + System.getProperty("java.vm.name") + + ", vendor=" + + System.getProperty("java.vendor"), testTimestamp.getTime() - testCalendar.getTimeZone().getRawOffset(), inDefaultTZ.getTime()); } From 3c23e90b7a7dee52169db8041523f38a7ceeb6ad Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 28 Feb 2025 09:44:55 +0100 Subject: [PATCH 12/13] deps: update dependency com.google.cloud:google-cloud-spanner-bom to v6.88.0 (#1939) --- pom.xml | 2 +- samples/spring-data-jdbc/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 38792b7f5..0251608b1 100644 --- a/pom.xml +++ b/pom.xml @@ -61,7 +61,7 @@ com.google.cloud google-cloud-spanner-bom - 6.87.0 + 6.88.0 pom import diff --git a/samples/spring-data-jdbc/pom.xml b/samples/spring-data-jdbc/pom.xml index b9d7379df..2242e3d78 100644 --- a/samples/spring-data-jdbc/pom.xml +++ b/samples/spring-data-jdbc/pom.xml @@ -30,7 +30,7 @@ com.google.cloud google-cloud-spanner-bom - 6.87.0 + 6.88.0 import pom From 40d6521ded77d4fed132f142d86c387470efb9fe Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Fri, 28 Feb 2025 10:23:18 +0100 Subject: [PATCH 13/13] chore(main): release 2.27.1 (#1936) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- CHANGELOG.md | 20 ++++++++++++++++++++ README.md | 6 +++--- pom.xml | 2 +- samples/snapshot/pom.xml | 2 +- versions.txt | 2 +- 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a20633643..b0b5090c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## [2.27.1](https://github.com/googleapis/java-spanner-jdbc/compare/v2.27.0...v2.27.1) (2025-02-28) + + +### Bug Fixes + +* Include COLUMN_DEFAULT in the returned metadata ([#1937](https://github.com/googleapis/java-spanner-jdbc/issues/1937)) ([98eb542](https://github.com/googleapis/java-spanner-jdbc/commit/98eb542201330188570ef995e38fa2a690e1160f)) + + +### Dependencies + +* Update dependency com.google.api.grpc:proto-google-cloud-trace-v1 to v2.59.0 ([#1938](https://github.com/googleapis/java-spanner-jdbc/issues/1938)) ([5458023](https://github.com/googleapis/java-spanner-jdbc/commit/54580230f61584f0691730693497171ff9bfc734)) +* Update dependency com.google.cloud:google-cloud-spanner-bom to v6.88.0 ([#1939](https://github.com/googleapis/java-spanner-jdbc/issues/1939)) ([3c23e90](https://github.com/googleapis/java-spanner-jdbc/commit/3c23e90b7a7dee52169db8041523f38a7ceeb6ad)) +* Update dependency com.google.cloud:google-cloud-trace to v2.59.0 ([#1940](https://github.com/googleapis/java-spanner-jdbc/issues/1940)) ([b31dd6e](https://github.com/googleapis/java-spanner-jdbc/commit/b31dd6e78b5f9b529b7cc7a9a34ea176231e22dc)) +* Update dependency com.google.cloud:sdk-platform-java-config to v3.44.0 ([#1931](https://github.com/googleapis/java-spanner-jdbc/issues/1931)) ([568a464](https://github.com/googleapis/java-spanner-jdbc/commit/568a464f29055383b7930deb42505bedad506339)) + + +### Documentation + +* Add defaultSequenceKind connection property documentation ([#1935](https://github.com/googleapis/java-spanner-jdbc/issues/1935)) ([c30b09a](https://github.com/googleapis/java-spanner-jdbc/commit/c30b09ab554d57adccaee72c36969407bbb1d4dd)) + ## [2.27.0](https://github.com/googleapis/java-spanner-jdbc/compare/v2.26.1...v2.27.0) (2025-02-21) diff --git a/README.md b/README.md index 85576faed..a2fda612e 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ If you are using Maven, add this to your pom.xml file: com.google.cloud google-cloud-spanner-jdbc - 2.27.0 + 2.27.1 ``` @@ -30,7 +30,7 @@ If you are using Gradle without BOM, add this to your dependencies ```Groovy -implementation 'com.google.cloud:google-cloud-spanner-jdbc:2.27.0' +implementation 'com.google.cloud:google-cloud-spanner-jdbc:2.27.1' ``` @@ -38,7 +38,7 @@ If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-spanner-jdbc" % "2.27.0" +libraryDependencies += "com.google.cloud" % "google-cloud-spanner-jdbc" % "2.27.1" ``` diff --git a/pom.xml b/pom.xml index 0251608b1..a201ba9ba 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.27.1-SNAPSHOT + 2.27.1 jar Google Cloud Spanner JDBC https://github.com/googleapis/java-spanner-jdbc diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index acab38c1c..821d6dd7f 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -29,7 +29,7 @@ com.google.cloud google-cloud-spanner-jdbc - 2.27.1-SNAPSHOT + 2.27.1 diff --git a/versions.txt b/versions.txt index e675c53a8..4623cc481 100644 --- a/versions.txt +++ b/versions.txt @@ -1,4 +1,4 @@ # Format: # module:released-version:current-version -google-cloud-spanner-jdbc:2.27.0:2.27.1-SNAPSHOT +google-cloud-spanner-jdbc:2.27.1:2.27.1