Repository: googleapis/java-spanner-jdbc
Pull request #1374 (2023-09-27 16:36:50)

chore(deps): update dependency com.google.cloud:google-cloud-spanner-jdbc to v2.13.4
[![Mend 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.13.2` -> `2.13.4` | [![age](https://developer.mend.io/api/mc/badges/age/maven/com.google.cloud:google-cloud-spanner-jdbc/2.13.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/com.google.cloud:google-cloud-spanner-jdbc/2.13.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/com.google.cloud:google-cloud-spanner-jdbc/2.13.2/2.13.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/com.google.cloud:google-cloud-spanner-jdbc/2.13.2/2.13.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>googleapis/java-spanner-jdbc (com.google.cloud:google-cloud-spanner-jdbc)</summary>

### [`v2.13.4`](https://togithub.com/googleapis/java-spanner-jdbc/blob/HEAD/CHANGELOG.md#2134-2023-09-28)

[Compare Source](https://togithub.com/googleapis/java-spanner-jdbc/compare/v2.13.3...v2.13.4)

##### Dependencies

-   Update dependency com.google.cloud:google-cloud-spanner-bom to v6.49.0 ([#&#8203;1376](https://togithub.com/googleapis/java-spanner-jdbc/issues/1376)) ([cc28b44](https://togithub.com/googleapis/java-spanner-jdbc/commit/cc28b44595d9a3cb112a35081fda98200d529ebf))

### [`v2.13.3`](https://togithub.com/googleapis/java-spanner-jdbc/blob/HEAD/CHANGELOG.md#2133-2023-09-27)

[Compare Source](https://togithub.com/googleapis/java-spanner-jdbc/compare/v2.13.2...v2.13.3)

##### Dependencies

-   Remove specific JDBC version from samples ([#&#8203;1371](https://togithub.com/googleapis/java-spanner-jdbc/issues/1371)) ([b30e391](https://togithub.com/googleapis/java-spanner-jdbc/commit/b30e391792f2c2811038b35a065b35104bc614e7))
-   Update dependency com.google.cloud:google-cloud-spanner-bom to v6.48.0 ([#&#8203;1370](https://togithub.com/googleapis/java-spanner-jdbc/issues/1370)) ([376e1c3](https://togithub.com/googleapis/java-spanner-jdbc/commit/376e1c3ccdd71351a5d6151ce19b9f88df163776))
-   Update dependency com.spotify.fmt:fmt-maven-plugin to v2.21.1 ([#&#8203;1372](https://togithub.com/googleapis/java-spanner-jdbc/issues/1372)) ([bf64add](https://togithub.com/googleapis/java-spanner-jdbc/commit/bf64add3e9ce8148d2fc3ad010b8abd446208e4f))
-   Update dependency org.springframework.boot:spring-boot-starter-parent to v3.1.4 ([#&#8203;1366](https://togithub.com/googleapis/java-spanner-jdbc/issues/1366)) ([749d2c3](https://togithub.com/googleapis/java-spanner-jdbc/commit/749d2c3698c900560b6f85247b0a41a85cd55ac8))
-   Update dependency org.springframework.data:spring-data-bom to v2023.0.4 ([#&#8203;1367](https://togithub.com/googleapis/java-spanner-jdbc/issues/1367)) ([916ad4a](https://togithub.com/googleapis/java-spanner-jdbc/commit/916ad4a9e07b3afc15e53664f175db9e58f06376))

##### Documentation

-   Add sample for Spring Data MyBatis ([#&#8203;1352](https://togithub.com/googleapis/java-spanner-jdbc/issues/1352)) ([ce52d07](https://togithub.com/googleapis/java-spanner-jdbc/commit/ce52d07c308bcde0ed1b0c9f4d3556db2590f722))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - 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.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/googleapis/java-spanner-jdbc).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi4xMDcuMiIsInVwZGF0ZWRJblZlciI6IjM3LjAuMyIsInRhcmdldEJyYW5jaCI6Im1haW4ifQ==-->



Patch:
diff --git a/pom.xml b/pom.xml
index ee537da..66f8a9a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -420,7 +420,6 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-javadoc-plugin</artifactId>
-        <version>3.6.0</version>
         <reportSets>
           <reportSet>
             <id>html</id>
diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml
index 015e8b3..1bc1db9 100644
--- a/samples/install-without-bom/pom.xml
+++ b/samples/install-without-bom/pom.xml
@@ -29,7 +29,7 @@
     <dependency>
       <groupId>com.google.cloud</groupId>
       <artifactId>google-cloud-spanner-jdbc</artifactId>
-      <version>2.13.2</version>
+      <version>2.13.4</version>
     </dependency>
     <!-- [END spanner-jdbc_install_without_bom] -->
 
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 6031afe..9248dac 100644
--- a/src/main/java/com/google/cloud/spanner/jdbc/JdbcConnection.java
+++ b/src/main/java/com/google/cloud/spanner/jdbc/JdbcConnection.java
@@ -47,6 +47,7 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.function.BiConsumer;
 import java.util.function.Function;
+import javax.annotation.Nonnull;
 
 /** Jdbc Connection class for Google Cloud Spanner */
 class JdbcConnection extends AbstractJdbcConnection {
@@ -394,31 +395,66 @@ class JdbcConnection extends AbstractJdbcConnection {
   @Override
   public void setCatalog(String catalog) throws SQLException {
     // This method could be changed to allow the user to change to another database.
-    // For now we only support setting an empty string in order to support frameworks
+    // For now, we only support setting the default catalog in order to support frameworks
     // and applications that set this when no catalog has been specified in the connection
     // URL.
     checkClosed();
-    JdbcPreconditions.checkArgument("".equals(catalog), "Only catalog \"\" is supported");
+    checkValidCatalog(catalog);
+  }
+
+  void checkValidCatalog(String catalog) throws SQLException {
+    String defaultCatalog = getDefaultCatalog();
+    JdbcPreconditions.checkArgument(
+        defaultCatalog.equals(catalog),
+        String.format("Only catalog %s is supported", defaultCatalog));
   }
 
   @Override
   public String getCatalog() throws SQLException {
     checkClosed();
-    return "";
+    return getDefaultCatalog();
+  }
+
+  @Nonnull
+  String getDefaultCatalog() {
+    switch (getDialect()) {
+      case POSTGRESQL:
+        String database = getConnectionOptions().getDatabaseName();
+        // It should not be possible that database is null, but it's better to be safe than sorry.
+        return database == null ? "" : database;
+      case GOOGLE_STANDARD_SQL:
+      default:
+        return "";
+    }
   }
 
   @Override
   public void setSchema(String schema) throws SQLException {
     checkClosed();
-    // Cloud Spanner does not support schemas, but does contain a pseudo 'empty string' schema that
-    // might be set by frameworks and applications that read the database metadata.
-    JdbcPreconditions.checkArgument("".equals(schema), "Only schema \"\" is supported");
+    checkValidSchema(schema);
+  }
+
+  void checkValidSchema(String schema) throws SQLException {
+    String defaultSchema = getDefaultSchema();
+    JdbcPreconditions.checkArgument(
+        defaultSchema.equals(schema), String.format("Only schema %s is supported", defaultSchema));
   }
 
   @Override
   public String getSchema() throws SQLException {
     checkClosed();
-    return "";
+    return getDefaultSchema();
+  }
+
+  @Nonnull
+  String getDefaultSchema() {
+    switch (getDialect()) {
+      case POSTGRESQL:
+        return "public";
+      case GOOGLE_STANDARD_SQL:
+      default:
+        return "";
+    }
   }
 
   @Override
diff --git a/src/main/java/com/google/cloud/spanner/jdbc/JdbcDatabaseMetaData.java b/src/main/java/com/google/cloud/spanner/jdbc/JdbcDatabaseMetaData.java
index b9c7cb8..4463395 100644
--- a/src/main/java/com/google/cloud/spanner/jdbc/JdbcDatabaseMetaData.java
+++ b/src/main/java/com/google/cloud/spanner/jdbc/JdbcDatabaseMetaData.java
@@ -777,11 +777,12 @@ class JdbcDatabaseMetaData extends AbstractJdbcWrapper implements DatabaseMetaDa
   }
 
   @Override
-  public ResultSet getCatalogs() {
+  public ResultSet getCatalogs() throws SQLException {
     return JdbcResultSet.of(
         ResultSets.forRows(
             Type.struct(StructField.of("TABLE_CAT", Type.string())),
-            Collections.singletonList(Struct.newBuilder().set("TABLE_CAT").to("").build())));
+            Collections.singletonList(
+                Struct.newBuilder().set("TABLE_CAT").to(getConnection().getCatalog()).build())));
   }
 
   @Override
@@ -1524,9 +1525,10 @@ class JdbcDatabaseMetaData extends AbstractJdbcWrapper implements DatabaseMetaDa
   @Override
   public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException {
     String sql = readSqlFromFile("DatabaseMetaData_GetSchemas.sql", connection.getDialect());
-    JdbcPreparedStatement statement =
-        prepareStatementReplaceNullWithAnyString(sql, catalog, schemaPattern);
-    return statement.executeQueryWithOptions(InternalMetadataQuery.INSTANCE);
+    try (JdbcPreparedStatement statement =
+        prepareStatementReplaceNullWithAnyString(sql, catalog, schemaPattern)) {
+      return statement.executeQueryWithOptions(InternalMetadataQuery.INSTANCE);
+    }
   }
 
   @Override


Test patch:
diff --git a/src/test/java/com/google/cloud/spanner/jdbc/JdbcConnectionTest.java b/src/test/java/com/google/cloud/spanner/jdbc/JdbcConnectionTest.java
index 592d404..ff811f3 100644
--- a/src/test/java/com/google/cloud/spanner/jdbc/JdbcConnectionTest.java
+++ b/src/test/java/com/google/cloud/spanner/jdbc/JdbcConnectionTest.java
@@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 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 static org.mockito.Mockito.any;
@@ -700,34 +701,33 @@ public class JdbcConnectionTest {
     ConnectionOptions options = mockOptions();
     when(options.getDatabaseName()).thenReturn("test");
     try (JdbcConnection connection = createConnection(options)) {
-      // The connection should always return the empty string as the current catalog, as no other
+      // The connection should always return the default catalog as the current catalog, as no other
       // catalogs exist in the INFORMATION_SCHEMA.
-      assertThat(connection.getCatalog()).isEqualTo("");
+      // The default catalog is the empty string for GoogleSQL databases.
+      // The default catalog is the database name for PostgreSQL databases.
+      assertEquals(connection.getDefaultCatalog(), connection.getCatalog());
       // This should be allowed.
-      connection.setCatalog("");
-      try {
-        // This should cause an exception.
-        connection.setCatalog("other");
-        fail("missing expected exception");
-      } catch (JdbcSqlExceptionImpl e) {
-        assertThat(e.getCode()).isEqualTo(Code.INVALID_ARGUMENT);
-      }
+      connection.setCatalog(connection.getDefaultCatalog());
+      // This should cause an exception.
+      JdbcSqlExceptionImpl exception =
+          assertThrows(JdbcSqlExceptionImpl.class, () -> connection.setCatalog("other"));
+      assertEquals(Code.INVALID_ARGUMENT, exception.getCode());
     }
   }
 
   @Test
   public void testSchema() throws SQLException {
     try (JdbcConnection connection = createConnection(mockOptions())) {
-      assertThat(connection.getSchema()).isEqualTo("");
+      // The connection should always return the default schema as the current schema, as we
+      // currently do not support setting the connection to a different schema.
+      // The default schema is the empty string for GoogleSQL databases.
+      // The default schema is 'public' for PostgreSQL databases.
+      assertEquals(connection.getDefaultSchema(), connection.getSchema());
       // This should be allowed.
-      connection.setSchema("");
-      try {
-        // This should cause an exception.
-        connection.setSchema("other");
-        fail("missing expected exception");
-      } catch (JdbcSqlExceptionImpl e) {
-        assertThat(e.getCode()).isEqualTo(Code.INVALID_ARGUMENT);
-      }
+      connection.setSchema(connection.getDefaultSchema());
+      JdbcSqlExceptionImpl exception =
+          assertThrows(JdbcSqlExceptionImpl.class, () -> connection.setSchema("other"));
+      assertEquals(Code.INVALID_ARGUMENT, exception.getCode());
     }
   }
 
diff --git a/src/test/java/com/google/cloud/spanner/jdbc/JdbcDatabaseMetaDataTest.java b/src/test/java/com/google/cloud/spanner/jdbc/JdbcDatabaseMetaDataTest.java
index 6a2b0ca..9782e96 100644
--- a/src/test/java/com/google/cloud/spanner/jdbc/JdbcDatabaseMetaDataTest.java
+++ b/src/test/java/com/google/cloud/spanner/jdbc/JdbcDatabaseMetaDataTest.java
@@ -41,10 +41,19 @@ import java.sql.Types;
 import java.util.Objects;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
-@RunWith(JUnit4.class)
+@RunWith(Parameterized.class)
 public class JdbcDatabaseMetaDataTest {
+  @Parameter public Dialect dialect;
+
+  @Parameters(name = "dialect = {0}")
+  public static Object[] data() {
+    return Dialect.values();
+  }
+
   private static final String DEFAULT_CATALOG = "";
   private static final String DEFAULT_SCHEMA = "";
   private static final String TEST_TABLE = "FOO";
@@ -314,10 +323,12 @@ public class JdbcDatabaseMetaDataTest {
   @Test
   public void testGetCatalogs() throws SQLException {
     JdbcConnection connection = mock(JdbcConnection.class);
+    when(connection.getDialect()).thenReturn(dialect);
+    when(connection.getCatalog()).thenCallRealMethod();
     DatabaseMetaData meta = new JdbcDatabaseMetaData(connection);
     try (ResultSet rs = meta.getCatalogs()) {
       assertThat(rs.next(), is(true));
-      assertThat(rs.getString("TABLE_CAT"), is(equalTo("")));
+      assertThat(rs.getString("TABLE_CAT"), is(equalTo(connection.getDefaultCatalog())));
       assertThat(rs.next(), is(false));
       ResultSetMetaData rsmd = rs.getMetaData();
       assertThat(rsmd.getColumnCount(), is(equalTo(1)));
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 7e2481a..820bdfa 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
@@ -822,6 +822,7 @@ public class ITJdbcDatabaseMetaDataTest extends ITAbstractJdbcTest {
   @Test
   public void testGetSchemas() throws SQLException {
     try (Connection connection = createConnection(env, database)) {
+      assertEquals("", connection.getSchema());
       try (ResultSet rs = connection.getMetaData().getSchemas()) {
         assertThat(rs.next(), is(true));
         assertThat(rs.getString("TABLE_SCHEM"), is(equalTo(DEFAULT_SCHEMA)));
@@ -829,11 +830,22 @@ public class ITJdbcDatabaseMetaDataTest extends ITAbstractJdbcTest {
         assertThat(rs.next(), is(true));
         assertThat(rs.getString("TABLE_SCHEM"), is(equalTo("INFORMATION_SCHEMA")));
         assertThat(rs.getString("TABLE_CATALOG"), is(equalTo(DEFAULT_CATALOG)));
-        if (!EmulatorSpannerHelper.isUsingEmulator()) {
-          assertThat(rs.next(), is(true));
-          assertThat(rs.getString("TABLE_SCHEM"), is(equalTo("SPANNER_SYS")));
-          assertThat(rs.getString("TABLE_CATALOG"), is(equalTo(DEFAULT_CATALOG)));
-        }
+        assertThat(rs.next(), is(true));
+        assertThat(rs.getString("TABLE_SCHEM"), is(equalTo("SPANNER_SYS")));
+        assertThat(rs.getString("TABLE_CATALOG"), is(equalTo(DEFAULT_CATALOG)));
+        assertFalse(rs.next());
+      }
+    }
+  }
+
+  @Test
+  public void testGetCatalogs() throws SQLException {
+    try (Connection connection = createConnection(env, database)) {
+      assertEquals("", connection.getCatalog());
+      try (ResultSet rs = connection.getMetaData().getCatalogs()) {
+        assertTrue(rs.next());
+        assertEquals("", rs.getString("TABLE_CAT"));
+
         assertFalse(rs.next());
       }
     }
diff --git a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcPgDatabaseMetaDataTest.java b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcPgDatabaseMetaDataTest.java
index ff0bff7..56d75db 100644
--- a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcPgDatabaseMetaDataTest.java
+++ b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcPgDatabaseMetaDataTest.java
@@ -752,6 +752,7 @@ public class ITJdbcPgDatabaseMetaDataTest extends ITAbstractJdbcTest {
   @Test
   public void testGetSchemas() throws SQLException {
     try (Connection connection = createConnection(env, database)) {
+      assertEquals("public", connection.getSchema());
       try (ResultSet rs = connection.getMetaData().getSchemas()) {
         assertTrue(rs.next());
         assertEquals(getDefaultCatalog(database), rs.getString("TABLE_CATALOG"));
@@ -774,6 +775,19 @@ public class ITJdbcPgDatabaseMetaDataTest extends ITAbstractJdbcTest {
     }
   }
 
+  @Test
+  public void testGetCatalogs() throws SQLException {
+    try (Connection connection = createConnection(env, database)) {
+      assertEquals(database.getId().getDatabase(), connection.getCatalog());
+      try (ResultSet rs = connection.getMetaData().getCatalogs()) {
+        assertTrue(rs.next());
+        assertEquals(database.getId().getDatabase(), rs.getString("TABLE_CAT"));
+
+        assertFalse(rs.next());
+      }
+    }
+  }
+
   private static final class Table {
     private final String name;
     private final String type;