Repository: GoogleCloudPlatform/pgadapter
Pull request #2750 (2025-01-14 15:23:29)

build(deps): bump org.postgresql:postgresql from 42.7.4 to 42.7.5
Bumps [org.postgresql:postgresql](https://github.com/pgjdbc/pgjdbc) from 42.7.4 to 42.7.5.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md">org.postgresql:postgresql's changelog</a>.</em></p>
<blockquote>
<h2>[42.7.5] (2025-01-14 08:00:00 -0400)</h2>
<h3>Added</h3>
<ul>
<li>ci: Test with Java 23  [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3381">#3381</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3381">pgjdbc/pgjdbc#3381</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>regression: revert change in fc60537 [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3476">#3476</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3476">pgjdbc/pgjdbc#3476</a>)</li>
<li>fix: PgDatabaseMetaData implementation of catalog as param and return value [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3390">#3390</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3390">pgjdbc/pgjdbc#3390</a>)</li>
<li>fix: Support default GSS credentials in the Java Postgres client [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3451">#3451</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3451">pgjdbc/pgjdbc#3451</a>)</li>
<li>fix: return only the transactions accessible by the current_user in XAResource.recover [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3450">#3450</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3450">pgjdbc/pgjdbc#3450</a>)</li>
<li>feat: don't force send extra_float_digits for PostgreSQL &gt;= 12 fix [Issue <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3432">#3432</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3432">pgjdbc/pgjdbc#3432</a>)  [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3446">#3446</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3446">pgjdbc/pgjdbc#3446</a>)</li>
<li>fix: exclude &quot;include columns&quot; from the list of primary keys [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3434">#3434</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3434">pgjdbc/pgjdbc#3434</a>)</li>
<li>perf: Enhance the meta query performance by specifying the oid. [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3427">#3427</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3427">pgjdbc/pgjdbc#3427</a>)</li>
<li>feat: support getObject(int, byte[].class) for bytea [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3274">#3274</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3274">pgjdbc/pgjdbc#3274</a>)</li>
<li>docs: document infinity and some minor edits [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3407">#3407</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3407">pgjdbc/pgjdbc#3407</a>)</li>
<li>fix: Added way to check for major server version, fixed check for RULE [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3402">#3402</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3402">pgjdbc/pgjdbc#3402</a>)</li>
<li>docs: fixed remaining paragraphs [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3398">#3398</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3398">pgjdbc/pgjdbc#3398</a>)</li>
<li>docs: fixed paragraphs in javadoc comments  [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3397">#3397</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3397">pgjdbc/pgjdbc#3397</a>)</li>
<li>fix: Reuse buffers and reduce allocations in GSSInputStream addresses [Issue <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3251">#3251</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3251">pgjdbc/pgjdbc#3251</a>) [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3255">#3255</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3255">pgjdbc/pgjdbc#3255</a>)</li>
<li>chore: Update Gradle to 8.10.2 [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3388">#3388</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3388">pgjdbc/pgjdbc#3388</a>)</li>
<li>fix: getSchemas() [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3386">#3386</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3386">pgjdbc/pgjdbc#3386</a>)</li>
<li>fix: Update rpm postgresql-jdbc.spec.tpl with scram-client [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3324">#3324</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3324">pgjdbc/pgjdbc#3324</a>)</li>
<li>fix: Clearing thisRow and rowBuffer on close() of ResultSet [Issue <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3383">#3383</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3383">pgjdbc/pgjdbc#3383</a>) [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3384">#3384</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3384">pgjdbc/pgjdbc#3384</a>)</li>
<li>fix: Package was renamed to maven-bundle-plugin [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3382">#3382</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3382">pgjdbc/pgjdbc#3382</a>)</li>
<li>fix: As of version 18 the RULE privilege has been removed [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3378">#3378</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3378">pgjdbc/pgjdbc#3378</a>)</li>
<li>fix: use buffered inputstream to create GSSInputStream [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3373">#3373</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3373">pgjdbc/pgjdbc#3373</a>)</li>
<li>test: get rid of 8.4, 9.0 pg versions and use &gt;= jdk version 17 [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3372">#3372</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3372">pgjdbc/pgjdbc#3372</a>)</li>
<li>Changed docker-compose version and renamed script file in instructions to match the real file name [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3363">#3363</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3363">pgjdbc/pgjdbc#3363</a>)</li>
<li>test:Do not assume &quot;test&quot; database in DatabaseMetaDataTransactionIsolationTest [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3364">#3364</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3364">pgjdbc/pgjdbc#3364</a>)</li>
<li>try to categorize dependencies [PR <a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3362">#3362</a>](<a href="https://redirect.github.com/pgjdbc/pgjdbc/pull/3362">pgjdbc/pgjdbc#3362</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/pgjdbc/pgjdbc/commit/94a1693a61d612dcdbb9c4d01c1e217326a0c044"><code>94a1693</code></a> update changelogs and increment version in gradle.properties for release (<a href="https://redirect.github.com/pgjdbc/pgjdbc/issues/3478">#3478</a>)</li>
<li><a href="https://github.com/pgjdbc/pgjdbc/commit/ce54dfdee80cf307ead81881565e4c358e7ae1ec"><code>ce54dfd</code></a> chore: replace deprecated kotlinOptions with a replacement API</li>
<li><a href="https://github.com/pgjdbc/pgjdbc/commit/398029efe9ea1cd39b805a4e70537f6bb59c1505"><code>398029e</code></a> chore: avoid failure in osgi-test/onlyIf if -PjdkBuildVersion is missing at t...</li>
<li><a href="https://github.com/pgjdbc/pgjdbc/commit/7245443f163efbc1a0d09c87143a2d4521fa6105"><code>7245443</code></a> test: skip :pgjdbc-osgi-test:test when runnning tests with Java 8</li>
<li><a href="https://github.com/pgjdbc/pgjdbc/commit/77475279046c52cd946e577c38b5ddfa5096a292"><code>7747527</code></a> chore(deps): update dependency gradle to v8.12</li>
<li><a href="https://github.com/pgjdbc/pgjdbc/commit/bb07a4bd0111cd212b9f54bc36034ee7bdbd4378"><code>bb07a4b</code></a> chore(deps): update codecov/codecov-action digest to adfacf2</li>
<li><a href="https://github.com/pgjdbc/pgjdbc/commit/f545514893809633d28b77c9d3732e9ce8815d52"><code>f545514</code></a> chore(deps): update dependency sbt/sbt to v1.10.7</li>
<li><a href="https://github.com/pgjdbc/pgjdbc/commit/45df56c7bc90fcecd184db4a9653319227c5facb"><code>45df56c</code></a> fix(deps): update dependency org.ops4j.pax.url:pax-url-aether to v2.6.15</li>
<li><a href="https://github.com/pgjdbc/pgjdbc/commit/b87e106d55b334efa3f61ccaba808e405f5190d4"><code>b87e106</code></a> fix(deps): update junit5 monorepo to v5.11.4</li>
<li><a href="https://github.com/pgjdbc/pgjdbc/commit/560347762cec21516a5fd864be3ad27e31113cb0"><code>5603477</code></a> fix(deps): update dependency com.github.spotbugs:com.github.spotbugs.gradle.p...</li>
<li>Additional commits viewable in <a href="https://github.com/pgjdbc/pgjdbc/compare/REL42.7.4...REL42.7.5">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.postgresql:postgresql&package-manager=maven&previous-version=42.7.4&new-version=42.7.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>

olavloite: @dependabot rebase
dependabot[bot]: Looks like this PR has been edited by someone other than Dependabot. That means Dependabot can't rebase it - sorry!

If you're happy for Dependabot to recreate it from scratch, overwriting any edits, you can request `@dependabot recreate`.


Patch:
diff --git a/pom.xml b/pom.xml
index 2ebb6371..f7d7de91 100644
--- a/pom.xml
+++ b/pom.xml
@@ -165,7 +165,7 @@
     <dependency>
       <groupId>org.postgresql</groupId>
       <artifactId>postgresql</artifactId>
-      <version>42.7.4</version>
+      <version>42.7.5</version>
     </dependency>
     <dependency>
       <groupId>com.kohlschutter.junixsocket</groupId>
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/JdbcMetadataStatementHelper.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/JdbcMetadataStatementHelper.java
index db846800..a4317a7e 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/JdbcMetadataStatementHelper.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/JdbcMetadataStatementHelper.java
@@ -45,10 +45,18 @@ class JdbcMetadataStatementHelper {
     // with Spangres-compatible queries.
     if (sql.startsWith(PgJdbcCatalog.PG_JDBC_EXPORTED_IMPORTED_KEYS_PREFIX)
         || sql.startsWith(PgJdbcCatalog.PG_JDBC_EXPORTED_IMPORTED_KEYS_42_0_PREFIX)) {
-      return replaceImportedExportedKeysQuery(sql);
+      return replaceImportedExportedKeysQuery(
+          sql, PgJdbcCatalog.PG_JDBC_EXPORTED_IMPORTED_KEYS_REPLACEMENT, "KEY_SEQ");
+    }
+    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_EXPORTED_IMPORTED_KEYS_PREFIX_V42_7_5)) {
+      return replaceImportedExportedKeysQuery(
+          sql, PgJdbcCatalog.PG_JDBC_EXPORTED_IMPORTED_KEYS_REPLACEMENT_UPPER_CASE, "\"KEY_SEQ\"");
     }
     if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_SCHEMAS_PREFIX)) {
-      return replaceGetSchemasQuery(sql);
+      return replaceGetSchemasQuery(sql, PgJdbcCatalog.PG_JDBC_GET_SCHEMAS_REPLACEMENT);
+    }
+    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_SCHEMAS_PREFIX_V42_7_5)) {
+      return replaceGetSchemasQuery(sql, PgJdbcCatalog.PG_JDBC_GET_SCHEMAS_REPLACEMENT_UPPER_CASE);
     }
     if (sql.contains(LiquibaseStatementHelper.TAG_STATEMENT_PART)) {
       return LiquibaseStatementHelper.replaceTagStatement(sql);
@@ -65,10 +73,16 @@ class JdbcMetadataStatementHelper {
         || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLES_PREFIX_5)
         || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLES_PREFIX_6)
         || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLES_PREFIX_7)
-        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLES_PREFIX_8)) {
-      return replaceGetTablesQuery(sql);
+        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLES_PREFIX_8)
+        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLES_PREFIX_9)) {
+      if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLES_PREFIX_9)) {
+        return replaceGetTablesQuery(sql, PgJdbcCatalog.PG_JDBC_GET_TABLES_REPLACEMENT_UPPER_CASE);
+      } else {
+        return replaceGetTablesQuery(sql, PgJdbcCatalog.PG_JDBC_GET_TABLES_REPLACEMENT);
+      }
     }
-    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMNS_PREFIX_1)
+    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMNS_PREFIX_V42_7_5)
+        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMNS_PREFIX_1)
         || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMNS_PREFIX_2)
         || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMNS_PREFIX_3)
         || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMNS_PREFIX_4)
@@ -78,22 +92,26 @@ class JdbcMetadataStatementHelper {
         || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMNS_PREFIX_4_1)) {
       return replaceGetColumnsQuery(sql);
     }
-    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_INDEXES_PREFIX_1)
+    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_INDEXES_PREFIX_V42_7_5)
+        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_INDEXES_PREFIX_1)
         || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_INDEXES_PREFIX_2)
         || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_INDEXES_PREFIX_3)
         || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_INDEXES_PREFIX_1_1)) {
       return replaceGetIndexInfoQuery(sql);
     }
     if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_PRIMARY_KEY_PREFIX_1)
-        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_PRIMARY_KEY_PREFIX_2)) {
+        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_PRIMARY_KEY_PREFIX_2)
+        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_PRIMARY_KEY_PREFIX_V42_7_5)) {
       return replaceGetPrimaryKeyQuery(sql);
     }
     if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLE_PRIVILEGES_PREFIX_1)
-        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLE_PRIVILEGES_PREFIX_2)) {
+        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLE_PRIVILEGES_PREFIX_2)
+        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLE_PRIVILEGES_PREFIX_3)) {
       return PgJdbcCatalog.PG_JDBC_GET_TABLE_PRIVILEGES_REPLACEMENT;
     }
     if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMN_PRIVILEGES_PREFIX_1)
-        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMN_PRIVILEGES_PREFIX_1_1)) {
+        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMN_PRIVILEGES_PREFIX_1_1)
+        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMN_PRIVILEGES_PREFIX_V42_7_5)) {
       return PgJdbcCatalog.PG_JDBC_GET_TABLE_PRIVILEGES_REPLACEMENT;
     }
     if (sql.startsWith(PgJdbcCatalog.PG_JDBC_BEST_ROW_IDENTIFIER_PREFIX)) {
@@ -101,16 +119,22 @@ class JdbcMetadataStatementHelper {
     }
 
     if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_FUNCTIONS_WITH_FUNC_TYPE_PREFIX)
-        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_FUNCTIONS_WITHOUT_FUNC_TYPE_PREFIX)) {
+        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_FUNCTIONS_WITHOUT_FUNC_TYPE_PREFIX)
+        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_FUNCTIONS_UPPER_CASE_PREFIX)) {
       return PgJdbcCatalog.PG_JDBC_GET_FUNCTIONS_REPLACEMENT;
     }
-    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_FUNCTION_COLUMNS_PREFIX)) {
+    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_FUNCTION_COLUMNS_PREFIX)
+        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_FUNCTION_COLUMNS_PREFIX_V42_7_5)) {
       return PgJdbcCatalog.PG_JDBC_GET_FUNCTION_COLUMNS_REPLACEMENT;
     }
     if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_PROCEDURES_PREFIX)) {
       return PgJdbcCatalog.PG_JDBC_GET_PROCEDURES_REPLACEMENT;
     }
-    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_UDTS_PREFIX)) {
+    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_PROCEDURES_PREFIX_V42_7_5)) {
+      return PgJdbcCatalog.PG_JDBC_GET_PROCEDURES_REPLACEMENT;
+    }
+    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_UDTS_PREFIX)
+        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_UDTS_PREFIX_V42_7_5)) {
       return PgJdbcCatalog.PG_JDBC_GET_UDTS_REPLACEMENT;
     }
     if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_MAX_NAME_LENGTH_PREFIX)) {
@@ -204,8 +228,7 @@ class JdbcMetadataStatementHelper {
     return replacedSql + whereClause + " ORDER BY ct.relname, pk_name, key_seq";
   }
 
-  private static String replaceGetSchemasQuery(String sql) {
-    String replacedSql = PgJdbcCatalog.PG_JDBC_GET_SCHEMAS_REPLACEMENT;
+  private static String replaceGetSchemasQuery(String sql, String replacedSql) {
     int startIndex;
     if (sql.contains(" AND nspname LIKE ")) {
       startIndex = sql.indexOf(" AND nspname LIKE ");
@@ -218,8 +241,7 @@ class JdbcMetadataStatementHelper {
         .replace(" ORDER BY TABLE_SCHEM", " ORDER BY schema_name");
   }
 
-  private static String replaceGetTablesQuery(String sql) {
-    String replacedSql = PgJdbcCatalog.PG_JDBC_GET_TABLES_REPLACEMENT;
+  private static String replaceGetTablesQuery(String sql, String replacedSql) {
     int startIndex;
     String wherePrefix = "WHERE c.relnamespace = n.oid";
     if (sql.contains(wherePrefix)) {
@@ -344,6 +366,9 @@ class JdbcMetadataStatementHelper {
         .replace(" AND n.nspname = ", " AND IDX.TABLE_SCHEMA = ")
         .replace(" AND ct.relname = ", " AND IDX.TABLE_NAME = ")
         .replace(" AND i.indisunique ", " AND IDX.IS_UNIQUE='YES' ")
+        .replace(
+            ") AS tmp ORDER BY \"NON_UNIQUE\", \"TYPE\", \"INDEX_NAME\", \"ORDINAL_POSITION\"",
+            " ORDER BY IDX.TABLE_NAME, IS_UNIQUE DESC, IDX.INDEX_NAME, CASE WHEN ORDINAL_POSITION IS NULL THEN 0 ELSE ORDINAL_POSITION END")
         .replace(
             ") AS tmp ORDER BY NON_UNIQUE, TYPE, INDEX_NAME, ORDINAL_POSITION",
             " ORDER BY IDX.TABLE_NAME, IS_UNIQUE DESC, IDX.INDEX_NAME, CASE WHEN ORDINAL_POSITION IS NULL THEN 0 ELSE ORDINAL_POSITION END")
@@ -364,6 +389,7 @@ class JdbcMetadataStatementHelper {
     replacedSql += " WHERE TRUE " + sql.substring(startIndex);
     return replacedSql
         .replace(") result where  result.A_ATTNUM = (result.KEYS).x", "")
+        .replace("AND result.KEY_SEQ <= KEY_COUNT", "")
         .replace(" AND n.nspname = ", " AND IDX.TABLE_SCHEMA = ")
         .replace(" AND ct.relname = ", " AND IDX.TABLE_NAME = ")
         .replace(" AND i.indisprimary ", " AND IDX.INDEX_TYPE='PRIMARY_KEY' ")
@@ -375,8 +401,8 @@ class JdbcMetadataStatementHelper {
             "ORDER BY COLS.TABLE_NAME, IDX.INDEX_NAME, COLS.ORDINAL_POSITION");
   }
 
-  private static String replaceImportedExportedKeysQuery(String sql) {
-    String replacedSql = PgJdbcCatalog.PG_JDBC_EXPORTED_IMPORTED_KEYS_REPLACEMENT;
+  private static String replaceImportedExportedKeysQuery(
+      String sql, String replacedSql, String keySeq) {
     int startIndex;
     if (sql.contains(" AND pkn.nspname = ")) {
       startIndex = sql.indexOf(" AND pkn.nspname = ");
@@ -397,9 +423,9 @@ class JdbcMetadataStatementHelper {
         .replace(" AND fkc.relname = ", " AND CHILD.TABLE_NAME = ")
         .replace(
             " ORDER BY fkn.nspname,fkc.relname,con.conname,pos.n",
-            " ORDER BY CHILD.TABLE_CATALOG, CHILD.TABLE_SCHEMA, CHILD.TABLE_NAME, KEY_SEQ")
+            " ORDER BY CHILD.TABLE_CATALOG, CHILD.TABLE_SCHEMA, CHILD.TABLE_NAME, " + keySeq)
         .replace(
             " ORDER BY pkn.nspname,pkc.relname, con.conname,pos.n",
-            " ORDER BY PARENT.TABLE_CATALOG, PARENT.TABLE_SCHEMA, PARENT.TABLE_NAME, KEY_SEQ");
+            " ORDER BY PARENT.TABLE_CATALOG, PARENT.TABLE_SCHEMA, PARENT.TABLE_NAME, " + keySeq);
   }
 }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/utils/ClientAutoDetector.java b/src/main/java/com/google/cloud/spanner/pgadapter/utils/ClientAutoDetector.java
index d4d267fc..dea38054 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/utils/ClientAutoDetector.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/utils/ClientAutoDetector.java
@@ -46,7 +46,9 @@ import java.time.Duration;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.regex.Pattern;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -71,6 +73,11 @@ public class ClientAutoDetector {
   public static final String PGBENCH_USAGE_HINT =
       "See https://github.com/GoogleCloudPlatform/pgadapter/blob/-/docs/pgbench.md for how to use pgbench with PGAdapter";
 
+  /** Force the detector to return this client. This should only be used for testing. */
+  @VisibleForTesting
+  public static final AtomicReference<WellKnownClient> FORCE_DETECT_CLIENT =
+      new AtomicReference<>();
+
   public enum WellKnownClient {
     PSQL {
 
@@ -665,6 +672,9 @@ public class ClientAutoDetector {
   public static @Nonnull WellKnownClient detectClient(
       List<String> orderParameterKeys, Map<String, String> parameters) {
     for (WellKnownClient client : WellKnownClient.values()) {
+      if (Objects.equals(client, FORCE_DETECT_CLIENT.get())) {
+        return client;
+      }
       if (client.isClient(orderParameterKeys, parameters)) {
         return client;
       }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/utils/PgJdbcCatalog.java b/src/main/java/com/google/cloud/spanner/pgadapter/utils/PgJdbcCatalog.java
index b0881e52..50fa7972 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/utils/PgJdbcCatalog.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/utils/PgJdbcCatalog.java
@@ -75,6 +75,8 @@ public class PgJdbcCatalog {
           + "FROM pg_catalog.pg_proc p "
           + "INNER JOIN pg_catalog.pg_namespace n ON p.pronamespace=n.oid "
           + "LEFT JOIN pg_catalog.pg_description d ON p.oid=d.objoid ";
+  public static final String PG_JDBC_GET_FUNCTIONS_UPPER_CASE_PREFIX =
+      "SELECT current_database() AS \"FUNCTION_CAT\",  n.nspname AS \"FUNCTION_SCHEM\", p.proname AS \"FUNCTION_NAME\",  d.description AS \"REMARKS\",";
   public static final String PG_JDBC_GET_FUNCTIONS_REPLACEMENT =
       "select * from (\n"
           + "\tselect ''::varchar as FUNCTION_CAT, ''::varchar as FUNCTION_SCHEM, ''::varchar as FUNCTION_NAME, ''::varchar as REMARKS, 0::bigint as FUNCTION_TYPE, ''::varchar as SPECIFIC_NAME\n"
@@ -91,6 +93,8 @@ public class PgJdbcCatalog {
           + " LEFT JOIN pg_catalog.pg_class c ON (d.classoid=c.oid AND c.relname='pg_proc') "
           + " LEFT JOIN pg_catalog.pg_namespace pn ON (c.relnamespace=pn.oid AND pn.nspname='pg_catalog') "
           + " WHERE p.pronamespace=n.oid ";
+  public static final String PG_JDBC_GET_PROCEDURES_PREFIX_V42_7_5 =
+      "SELECT current_database() AS \"PROCEDURE_CAT\",  n.nspname AS \"PROCEDURE_SCHEM\", p.proname AS \"PROCEDURE_NAME\", NULL, NULL, NULL, d.description AS \"REMARKS\", 2 AS \"PROCEDURE_TYPE\",";
   public static final String PG_JDBC_GET_PROCEDURES_REPLACEMENT =
       "select * from (\n"
           + "\tselect ''::varchar as PROCEDURE_CAT, ''::varchar as PROCEDURE_SCHEM, ''::varchar as PROCEDURE_NAME, ''::varchar as REMARKS, 0::bigint as PROCEDURE_TYPE, ''::varchar as SPECIFIC_NAME\n"
@@ -106,6 +110,8 @@ public class PgJdbcCatalog {
           + java.sql.Types.DISTINCT
           + " end as data_type, pg_catalog.obj_description(t.oid, 'pg_type')  "
           + "as remarks, CASE WHEN t.typtype = 'd' then  (select CASE";
+  public static final String PG_JDBC_GET_UDTS_PREFIX_V42_7_5 =
+      "select current_database() as \"TYPE_CAT\", n.nspname as \"TYPE_SCHEM\", t.typname as \"TYPE_NAME\", null as \"CLASS_NAME\", ";
   public static final String PG_JDBC_GET_UDTS_REPLACEMENT =
       "select * from (\n"
           + "\tselect ''::varchar as TYPE_CAT, ''::varchar as TYPE_SCHEM, ''::varchar as TYPE_NAME, ''::varchar as CLASS_NAME, 0::bigint as DATA_TYPE, ''::varchar as REMARKS, 0::bigint as BASE_TYPE\n"
@@ -117,6 +123,9 @@ public class PgJdbcCatalog {
           + " p.proargnames, p.proargmodes, p.proallargtypes, p.oid "
           + " FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n, pg_catalog.pg_type t "
           + " WHERE p.pronamespace=n.oid AND p.prorettype=t.oid ";
+  public static final String PG_JDBC_GET_FUNCTION_COLUMNS_PREFIX_V42_7_5 =
+      "SELECT current_database(), n.nspname,p.proname,p.prorettype,p.proargtypes, t.typtype,t.typrelid, "
+          + " p.proargnames, p.proargmodes, p.proallargtypes, p.oid ";
   public static final String PG_JDBC_GET_FUNCTION_COLUMNS_REPLACEMENT =
       "select * from (\n"
           + "\tselect ''::varchar as FUNCTION_CAT, ''::varchar as FUNCTION_SCHEM, ''::varchar as FUNCTION_NAME, ''::varchar as COLUMN_NAME, 0::bigint as COLUMN_TYPE,\n"
@@ -130,8 +139,15 @@ public class PgJdbcCatalog {
           + " WHERE nspname <> 'pg_toast' AND (nspname !~ '^pg_temp_' "
           + " OR nspname = (pg_catalog.current_schemas(true))[1]) AND (nspname !~ '^pg_toast_temp_' "
           + " OR nspname = replace((pg_catalog.current_schemas(true))[1], 'pg_temp_', 'pg_toast_temp_')) ";
+  public static final String PG_JDBC_GET_SCHEMAS_PREFIX_V42_7_5 =
+      "SELECT nspname AS \"TABLE_SCHEM\", current_database() AS \"TABLE_CATALOG\" FROM pg_catalog.pg_namespace "
+          + " WHERE nspname <> 'pg_toast' AND (nspname !~ '^pg_temp_' "
+          + " OR nspname = (pg_catalog.current_schemas(true))[1]) AND (nspname !~ '^pg_toast_temp_' "
+          + " OR nspname = replace((pg_catalog.current_schemas(true))[1], 'pg_temp_', 'pg_toast_temp_')) ";
   public static final String PG_JDBC_GET_SCHEMAS_REPLACEMENT =
       "select schema_name as TABLE_SCHEM, catalog_name AS TABLE_CATALOG from information_schema.schemata WHERE true ";
+  public static final String PG_JDBC_GET_SCHEMAS_REPLACEMENT_UPPER_CASE =
+      "select schema_name as \"TABLE_SCHEM\", catalog_name AS \"TABLE_CATALOG\" from information_schema.schemata WHERE true ";
 
   public static final String PG_JDBC_GET_TABLES_PREFIX_1 =
       "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, c.relname AS TABLE_NAME,  CASE n.nspname ~ '^pg_' OR n.nspname = 'information_schema'  WHEN true THEN CASE  WHEN n.nspname = 'pg_catalog' OR n.nspname = 'information_schema' THEN CASE c.relkind   WHEN 'r' THEN 'SYSTEM TABLE'   WHEN 'v' THEN 'SYSTEM VIEW'   WHEN 'i' THEN 'SYSTEM INDEX'   ELSE NULL   END  WHEN n.nspname = 'pg_toast' THEN CASE c.relkind   WHEN 'r' THEN 'SYSTEM TOAST TABLE'   WHEN 'i' THEN 'SYSTEM TOAST INDEX'   ELSE NULL   END  ELSE CASE c.relkind   WHEN 'r' THEN 'TEMPORARY TABLE'   WHEN 'p' THEN 'TEMPORARY TABLE'   WHEN 'i' THEN 'TEMPORARY INDEX'   WHEN 'S' THEN 'TEMPORARY SEQUENCE'   WHEN 'v' THEN 'TEMPORARY VIEW'   ELSE NULL   END  END  WHEN false THEN CASE c.relkind  WHEN 'r' THEN 'TABLE'  WHEN 'p' THEN 'PARTITIONED TABLE'  WHEN 'i' THEN 'INDEX'  WHEN 'P' then 'PARTITIONED INDEX'  WHEN 'S' THEN 'SEQUENCE'  WHEN 'v' THEN 'VIEW'  WHEN 'c' THEN 'TYPE'  WHEN 'f' THEN 'FOREIGN TABLE'  WHEN 'm' THEN 'MATERIALIZED VIEW'  ELSE NULL  END  ELSE NULL  END  AS TABLE_TYPE, d.description AS REMARKS,  '' as TYPE_CAT, '' as TYPE_SCHEM, '' as TYPE_NAME, '' AS SELF_REFERENCING_COL_NAME, '' AS REF_GENERATION  FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c  LEFT JOIN (select * from (select 0 as objoid, 0 as classoid, 0 as objsubid, '' as description) pg_description where false) d ON (c.oid = d.objoid AND d.objsubid = 0  and d.classoid = 0)  WHERE c.relnamespace = n.oid";
@@ -149,14 +165,25 @@ public class PgJdbcCatalog {
       "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, c.relname AS TABLE_NAME,  CASE n.nspname ~ '^pg_' OR n.nspname = 'information_schema'  WHEN true THEN CASE  WHEN n.nspname = 'pg_catalog' OR n.nspname = 'information_schema' THEN CASE c.relkind   WHEN 'r' THEN 'SYSTEM TABLE'   WHEN 'v' THEN 'SYSTEM VIEW'   WHEN 'i' THEN 'SYSTEM INDEX'   ELSE NULL   END  WHEN n.nspname = 'pg_toast' THEN CASE c.relkind   WHEN 'r' THEN 'SYSTEM TOAST TABLE'   WHEN 'i' THEN 'SYSTEM TOAST INDEX'   ELSE NULL   END  ELSE CASE c.relkind   WHEN 'r' THEN 'TEMPORARY TABLE'   WHEN 'p' THEN 'TEMPORARY TABLE'   WHEN 'i' THEN 'TEMPORARY INDEX'   WHEN 'S' THEN 'TEMPORARY SEQUENCE'   WHEN 'v' THEN 'TEMPORARY VIEW'   ELSE NULL   END  END  WHEN false THEN CASE c.relkind  WHEN 'r' THEN 'TABLE'  WHEN 'p' THEN 'TABLE'  WHEN 'i' THEN 'INDEX'  WHEN 'S' THEN 'SEQUENCE'  WHEN 'v' THEN 'VIEW'  WHEN 'c' THEN 'TYPE'  WHEN 'f' THEN 'FOREIGN TABLE'  WHEN 'm' THEN 'MATERIALIZED VIEW'  ELSE NULL  END  ELSE NULL  END  AS TABLE_TYPE, d.description AS REMARKS  FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c  LEFT JOIN pg_catalog.pg_description d ON (c.oid = d.objoid AND d.objsubid = 0)  LEFT JOIN pg_catalog.pg_class dc ON (d.classoid=dc.oid AND dc.relname='pg_class')  LEFT JOIN pg_catalog.pg_namespace dn ON (dn.oid=dc.relnamespace AND dn.nspname='pg_catalog')  WHERE c.relnamespace = n.oid  ";
   public static final String PG_JDBC_GET_TABLES_PREFIX_8 =
       "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, c.relname AS TABLE_NAME,  CASE n.nspname ~ '^pg_' OR n.nspname = 'information_schema'  WHEN true THEN CASE  WHEN n.nspname = 'pg_catalog' OR n.nspname = 'information_schema' THEN CASE c.relkind   WHEN 'r' THEN 'SYSTEM TABLE'   WHEN 'v' THEN 'SYSTEM VIEW'   WHEN 'i' THEN 'SYSTEM INDEX'   ELSE NULL   END  WHEN n.nspname = 'pg_toast' THEN CASE c.relkind   WHEN 'r' THEN 'SYSTEM TOAST TABLE'   WHEN 'i' THEN 'SYSTEM TOAST INDEX'   ELSE NULL   END  ELSE CASE c.relkind   WHEN 'r' THEN 'TEMPORARY TABLE'   WHEN 'i' THEN 'TEMPORARY INDEX'   WHEN 'S' THEN 'TEMPORARY SEQUENCE'   WHEN 'v' THEN 'TEMPORARY VIEW'   ELSE NULL   END  END  WHEN false THEN CASE c.relkind  WHEN 'r' THEN 'TABLE'  WHEN 'i' THEN 'INDEX'  WHEN 'S' THEN 'SEQUENCE'  WHEN 'v' THEN 'VIEW'  WHEN 'c' THEN 'TYPE'  WHEN 'f' THEN 'FOREIGN TABLE'  WHEN 'm' THEN 'MATERIALIZED VIEW'  ELSE NULL  END  ELSE NULL  END  AS TABLE_TYPE, d.description AS REMARKS  FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c  LEFT JOIN pg_catalog.pg_description d ON (c.oid = d.objoid AND d.objsubid = 0)  LEFT JOIN pg_catalog.pg_class dc ON (d.classoid=dc.oid AND dc.relname='pg_class')  LEFT JOIN pg_catalog.pg_namespace dn ON (dn.oid=dc.relnamespace AND dn.nspname='pg_catalog')  WHERE c.relnamespace = n.oid  ";
+  public static final String PG_JDBC_GET_TABLES_PREFIX_9 =
+      "SELECT current_database() AS \"TABLE_CAT\", n.nspname AS \"TABLE_SCHEM\", c.relname AS \"TABLE_NAME\",  CASE n.nspname ~ '^pg_' OR n.nspname = 'information_schema'  WHEN true THEN CASE  WHEN n.nspname = 'pg_catalog' OR n.nspname = 'information_schema' THEN CASE c.relkind   WHEN 'r' THEN 'SYSTEM TABLE'   WHEN 'v' THEN 'SYSTEM VIEW'   WHEN 'i' THEN 'SYSTEM INDEX'   ELSE NULL   END  WHEN n.nspname = 'pg_toast' THEN CASE c.relkind   WHEN 'r' THEN 'SYSTEM TOAST TABLE'   WHEN 'i' THEN 'SYSTEM TOAST INDEX'   ELSE NULL   END  ELSE CASE c.relkind   WHEN 'r' THEN 'TEMPORARY TABLE'   WHEN 'p' THEN 'TEMPORARY TABLE'   WHEN 'i' THEN 'TEMPORARY INDEX'   WHEN 'S' THEN 'TEMPORARY SEQUENCE'   WHEN 'v' THEN 'TEMPORARY VIEW'   ELSE NULL   END  END  WHEN false THEN CASE c.relkind  WHEN 'r' THEN 'TABLE'  WHEN 'p' THEN 'PARTITIONED TABLE'  WHEN 'i' THEN 'INDEX'  WHEN 'P' then 'PARTITIONED INDEX'  WHEN 'S' THEN 'SEQUENCE'  WHEN 'v' THEN 'VIEW'  WHEN 'c' THEN 'TYPE'  WHEN 'f' THEN 'FOREIGN TABLE'  WHEN 'm' THEN 'MATERIALIZED VIEW'  ELSE NULL  END  ELSE NULL  END  AS \"TABLE_TYPE\", d.description AS \"REMARKS\",  '' as \"TYPE_CAT\", '' as \"TYPE_SCHEM\", '' as \"TYPE_NAME\", '' AS \"SELF_REFERENCING_COL_NAME\", '' AS \"REF_GENERATION\"";
   public static final String PG_JDBC_GET_TABLES_REPLACEMENT =
       "SELECT TABLE_CATALOG AS TABLE_CAT, TABLE_SCHEMA AS TABLE_SCHEM, TABLE_NAME AS TABLE_NAME,\n"
           + "       CASE WHEN TABLE_TYPE = 'BASE TABLE' THEN 'TABLE' ELSE TABLE_TYPE END AS TABLE_TYPE,\n"
           + "       NULL AS REMARKS, NULL AS TYPE_CAT, NULL AS TYPE_SCHEM, NULL AS TYPE_NAME,\n"
           + "       NULL AS SELF_REFERENCING_COL_NAME, NULL AS REF_GENERATION\n"
           + "FROM INFORMATION_SCHEMA.TABLES AS T\n";
+  public static final String PG_JDBC_GET_TABLES_REPLACEMENT_UPPER_CASE =
+      "SELECT TABLE_CATALOG AS \"TABLE_CAT\", TABLE_SCHEMA AS \"TABLE_SCHEM\", TABLE_NAME AS \"TABLE_NAME\",\n"
+          + "       CASE WHEN TABLE_TYPE = 'BASE TABLE' THEN 'TABLE' ELSE TABLE_TYPE END AS \"TABLE_TYPE\",\n"
+          + "       NULL AS \"REMARKS\", NULL AS \"TYPE_CAT\", NULL AS \"TYPE_SCHEM\", NULL AS \"TYPE_NAME\",\n"
+          + "       NULL AS \"SELF_REFERENCING_COL_NAME\", NULL AS \"REF_GENERATION\"\n"
+          + "FROM INFORMATION_SCHEMA.TABLES AS T\n";
 
-  // This prefix is used for versions [42.3.2, ...).
+  // This prefix is used for versions [42.7.5, ...).
+  public static final String PG_JDBC_GET_COLUMNS_PREFIX_V42_7_5 =
+      "SELECT * FROM (SELECT current_database(), n.nspname,c.relname,a.attname,a.atttypid,a.attnotnull  OR (t.typtype = 'd' AND t.typnotnull) AS attnotnull,a.atttypmod,a.attlen,t.typtypmod,row_number() OVER (PARTITION BY a.attrelid ORDER BY a.attnum) AS attnum, nullif(a.attidentity, '') as attidentity,nullif(a.attgenerated, '') as attgenerated,pg_catalog.pg_get_expr(def.adbin, def.adrelid) AS adsrc,dsc.description,t.typbasetype,t.typtype  FROM pg_catalog.pg_namespace n  JOIN pg_catalog.pg_class c ON (c.relnamespace = n.oid)  JOIN pg_catalog.pg_attribute a ON (a.attrelid=c.oid)  JOIN pg_catalog.pg_type t ON (a.atttypid = t.oid)  LEFT JOIN pg_catalog.pg_attrdef def ON (a.attrelid=def.adrelid AND a.attnum = def.adnum)  LEFT JOIN pg_catalog.pg_description dsc ON (c.oid=dsc.objoid AND a.attnum = dsc.objsubid)  LEFT JOIN pg_catalog.pg_class dc ON (dc.oid=dsc.classoid AND dc.relname='pg_class')  LEFT JOIN pg_catalog.pg_namespace dn ON (dc.relnamespace=dn.oid AND dn.nspname='pg_catalog')";
+  // This prefix is used for versions [42.3.2, 42.7.4].
   public static final String PG_JDBC_GET_COLUMNS_PREFIX_1 =
       "SELECT * FROM (SELECT n.nspname,c.relname,a.attname,a.atttypid,a.attnotnull OR (t.typtype = 'd' AND t.typnotnull) AS attnotnull,a.atttypmod,a.attlen,t.typtypmod,row_number() OVER (PARTITION BY a.attrelid ORDER BY a.attnum) AS attnum, nullif(a.attidentity, '') as attidentity,nullif(a.attgenerated, '') as attgenerated,pg_catalog.pg_get_expr(def.adbin, def.adrelid) AS adsrc,dsc.description,t.typbasetype,t.typtype  FROM pg_catalog.pg_namespace n  JOIN pg_catalog.pg_class c ON (c.relnamespace = n.oid)  JOIN pg_catalog.pg_attribute a ON (a.attrelid=c.oid)  JOIN pg_catalog.pg_type t ON (a.atttypid = t.oid)  LEFT JOIN pg_catalog.pg_attrdef def ON (a.attrelid=def.adrelid AND a.attnum = def.adnum)  LEFT JOIN pg_catalog.pg_description dsc ON (c.oid=dsc.objoid AND a.attnum = dsc.objsubid)  LEFT JOIN pg_catalog.pg_class dc ON (dc.oid=dsc.classoid AND dc.relname='pg_class')  LEFT JOIN pg_catalog.pg_namespace dn ON (dc.relnamespace=dn.oid AND dn.nspname='pg_catalog')";
   // This prefix is used for versions [42.2.9, 42.3.1].
@@ -211,7 +238,7 @@ public class PgJdbcCatalog {
       "SELECT n.nspname,c.relname,a.attname,a.atttypid,a.attnotnull OR (t.typtype = 'd' AND t.typnotnull) AS attnotnull,a.atttypmod,a.attlen,a.attnum,pg_catalog.pg_get_expr(def.adbin, def.adrelid) AS adsrc,dsc.description,t.typbasetype,t.typtype  FROM pg_catalog.pg_namespace n  JOIN pg_catalog.pg_class c ON (c.relnamespace = n.oid)  JOIN pg_catalog.pg_attribute a ON (a.attrelid=c.oid)  JOIN pg_catalog.pg_type t ON (a.atttypid = t.oid)  LEFT JOIN pg_catalog.pg_attrdef def ON (a.attrelid=def.adrelid AND a.attnum = def.adnum)  LEFT JOIN pg_catalog.pg_description dsc ON (c.oid=dsc.objoid AND a.attnum = dsc.objsubid)  LEFT JOIN pg_catalog.pg_class dc ON (dc.oid=dsc.classoid AND dc.relname='pg_class')  LEFT JOIN pg_catalog.pg_namespace dn ON (dc.relnamespace=dn.oid AND dn.nspname='pg_catalog')";
 
   public static final String PG_JDBC_GET_COLUMNS_REPLACEMENT =
-      "SELECT TABLE_CATALOG AS \"TABLE_CAT\", TABLE_SCHEMA AS nspname, TABLE_NAME AS relname, COLUMN_NAME AS attname, '' as typtype,\n"
+      "SELECT TABLE_CATALOG as current_database, TABLE_CATALOG AS \"TABLE_CAT\", TABLE_SCHEMA AS nspname, TABLE_NAME AS relname, COLUMN_NAME AS attname, '' as typtype,\n"
           + "       CASE\n"
           + "           WHEN SPANNER_TYPE = 'boolean' THEN 16\n"
           + "           WHEN SPANNER_TYPE = 'boolean[]' THEN 1000\n"
@@ -288,6 +315,28 @@ public class PgJdbcCatalog {
           + "        END AS \"IS_GENERATEDCOLUMN\"\n"
           + "FROM INFORMATION_SCHEMA.COLUMNS C\n";
 
+  public static final String PG_JDBC_GET_INDEXES_PREFIX_V42_7_5 =
+      "SELECT"
+          + "     tmp.TABLE_CAT AS \"TABLE_CAT\","
+          + "     tmp.TABLE_SCHEM AS \"TABLE_SCHEM\","
+          + "     tmp.TABLE_NAME AS \"TABLE_NAME\","
+          + "     tmp.NON_UNIQUE AS \"NON_UNIQUE\","
+          + "     tmp.INDEX_QUALIFIER AS \"INDEX_QUALIFIER\","
+          + "     tmp.INDEX_NAME AS \"INDEX_NAME\","
+          + "     tmp.TYPE AS \"TYPE\","
+          + "     tmp.ORDINAL_POSITION AS \"ORDINAL_POSITION\","
+          + "     trim(both '\"' from pg_catalog.pg_get_indexdef(tmp.CI_OID, tmp.ORDINAL_POSITION, false)) AS \"COLUMN_NAME\","
+          + "   CASE tmp.AM_NAME"
+          + "     WHEN 'btree' THEN CASE tmp.I_INDOPTION[tmp.ORDINAL_POSITION - 1] & 1::smallint"
+          + "       WHEN 1 THEN 'D'"
+          + "       ELSE 'A'"
+          + "     END"
+          + "     ELSE NULL"
+          + "   END AS \"ASC_OR_DESC\","
+          + "     tmp.CARDINALITY AS \"CARDINALITY\","
+          + "     tmp.PAGES AS \"PAGES\","
+          + "     tmp.FILTER_CONDITION AS \"FILTER_CONDITION\""
+          + "FROM (";
   public static final String PG_JDBC_GET_INDEXES_PREFIX_1 =
       "SELECT "
           + "    tmp.TABLE_CAT, "
@@ -386,6 +435,8 @@ public class PgJdbcCatalog {
           + "                AND IDX.TABLE_NAME=COL.TABLE_NAME\n"
           + "                AND IDX.INDEX_NAME=COL.INDEX_NAME\n";
 
+  public static final String PG_JDBC_GET_PRIMARY_KEY_PREFIX_V42_7_5 =
+      "SELECT        result.TABLE_CAT AS \"TABLE_CAT\",        result.TABLE_SCHEM AS \"TABLE_SCHEM\",        result.TABLE_NAME AS \"TABLE_NAME\",        result.COLUMN_NAME AS \"COLUMN_NAME\",        result.KEY_SEQ AS \"KEY_SEQ\",        result.PK_NAME AS \"PK_NAME\"";
   public static final String PG_JDBC_GET_PRIMARY_KEY_PREFIX_1 =
       "SELECT        result.TABLE_CAT,        result.TABLE_SCHEM,        result.TABLE_NAME,        result.COLUMN_NAME,        result.KEY_SEQ,        result.PK_NAME FROM      (SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM,   ct.relname AS TABLE_NAME, a.attname AS COLUMN_NAME,   (information_schema._pg_expandarray(i.indkey)).n AS KEY_SEQ, ci.relname AS PK_NAME,   information_schema._pg_expandarray(i.indkey) AS KEYS, a.attnum AS A_ATTNUM FROM pg_catalog.pg_class ct   JOIN pg_catalog.pg_attribute a ON (ct.oid = a.attrelid)   JOIN pg_catalog.pg_namespace n ON (ct.relnamespace = n.oid)   JOIN pg_catalog.pg_index i ON ( a.attrelid = i.indrelid)   JOIN pg_catalog.pg_class ci ON (ci.oid = i.indexrelid)";
   public static final String PG_JDBC_GET_PRIMARY_KEY_PREFIX_2 =
@@ -404,12 +455,16 @@ public class PgJdbcCatalog {
       "SELECT n.nspname,c.relname,r.rolname,c.relacl  FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c, pg_catalog.pg_roles r  WHERE c.relnamespace = n.oid  AND c.relowner = r.oid  AND c.relkind IN ('r','p'";
   public static final String PG_JDBC_GET_TABLE_PRIVILEGES_PREFIX_2 =
       "SELECT n.nspname,c.relname,r.rolname,c.relacl  FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c, pg_catalog.pg_roles r  WHERE c.relnamespace = n.oid  AND c.relowner = r.oid  AND c.relkind = 'r'";
+  public static final String PG_JDBC_GET_TABLE_PRIVILEGES_PREFIX_3 =
+      "SELECT current_database(), n.nspname,c.relname,r.rolname,c.relacl  FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c, pg_catalog.pg_roles r ";
   public static final String PG_JDBC_GET_TABLE_PRIVILEGES_REPLACEMENT =
-      "select '' as nspname, '' as relname, '' as rolname, '' as relacl from (select 1) t where false";
+      "select '' as current_database, '' as nspname, '' as relname, '' as rolname, '' as relacl from (select 1) t where false";
   public static final String PG_JDBC_GET_COLUMN_PRIVILEGES_PREFIX_1 =
       "SELECT n.nspname,c.relname,r.rolname,c.relacl, a.attacl,  a.attname  FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c,  pg_catalog.pg_roles r, pg_catalog.pg_attribute a  WHERE c.relnamespace = n.oid  AND c.relowner = r.oid  AND c.oid = a.attrelid  AND c.relkind = 'r'  AND a.attnum > 0 AND NOT a.attisdropped";
   public static final String PG_JDBC_GET_COLUMN_PRIVILEGES_PREFIX_1_1 =
       "SELECT n.nspname,c.relname,r.rolname,c.relacl,  a.attname  FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c,  pg_catalog.pg_roles r, pg_catalog.pg_attribute a  WHERE c.relnamespace = n.oid  AND c.relowner = r.oid  AND c.oid = a.attrelid  AND c.relkind = 'r'  AND a.attnum > 0 AND NOT a.attisdropped";
+  public static final String PG_JDBC_GET_COLUMN_PRIVILEGES_PREFIX_V42_7_5 =
+      "SELECT current_database(), n.nspname,c.relname,r.rolname,c.relacl, a.attacl,  a.attname  FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c,  pg_catalog.pg_roles r, pg_catalog.pg_attribute a";
   public static final String PG_JDBC_GET_BEST_ROW_IDENTIFIER_REPLACEMENT =
       "select '' as attname, 0 as atttypid, -1 as atttypmod from (select 1) t where false";
 
@@ -562,6 +617,9 @@ public class PgJdbcCatalog {
           + " pg_catalog.pg_constraint con, "
           + " pg_catalog.generate_series(1, 32) pos(n), "
           + " pg_catalog.pg_class pkic";
+  public static final String PG_JDBC_EXPORTED_IMPORTED_KEYS_PREFIX_V42_7_5 =
+      "SELECT current_database() AS \"PKTABLE_CAT\", pkn.nspname AS \"PKTABLE_SCHEM\", pkc.relname AS \"PKTABLE_NAME\", pka.attname AS \"PKCOLUMN_NAME\", "
+          + "current_database() AS \"FKTABLE_CAT\", fkn.nspname AS \"FKTABLE_SCHEM\", fkc.relname AS \"FKTABLE_NAME\", fka.attname AS \"FKCOLUMN_NAME\", ";
   public static final String PG_JDBC_EXPORTED_IMPORTED_KEYS_REPLACEMENT =
       "SELECT PARENT.TABLE_CATALOG AS PKTABLE_CAT, PARENT.TABLE_SCHEMA AS PKTABLE_SCHEM, PARENT.TABLE_NAME AS PKTABLE_NAME,\n"
           + "       PARENT.COLUMN_NAME AS PKCOLUMN_NAME, CHILD.TABLE_CATALOG AS FKTABLE_CAT, CHILD.TABLE_SCHEMA AS FKTABLE_SCHEM,\n"
@@ -575,6 +633,19 @@ public class PgJdbcCatalog {
           + "INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CHILD  ON COALESCE(CONSTRAINTS.CONSTRAINT_CATALOG, '')=COALESCE(CHILD.CONSTRAINT_CATALOG, '') AND CONSTRAINTS.CONSTRAINT_SCHEMA= CHILD.CONSTRAINT_SCHEMA AND CONSTRAINTS.CONSTRAINT_NAME= CHILD.CONSTRAINT_NAME\n"
           + "INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE PARENT ON COALESCE(CONSTRAINTS.UNIQUE_CONSTRAINT_CATALOG, '')=COALESCE(PARENT.CONSTRAINT_CATALOG, '') AND CONSTRAINTS.UNIQUE_CONSTRAINT_SCHEMA=PARENT.CONSTRAINT_SCHEMA AND CONSTRAINTS.UNIQUE_CONSTRAINT_NAME=PARENT.CONSTRAINT_NAME AND PARENT.ORDINAL_POSITION=CHILD.POSITION_IN_UNIQUE_CONSTRAINT\n"
           + "WHERE TRUE\n";
+  public static final String PG_JDBC_EXPORTED_IMPORTED_KEYS_REPLACEMENT_UPPER_CASE =
+      "SELECT PARENT.TABLE_CATALOG AS \"PKTABLE_CAT\", PARENT.TABLE_SCHEMA AS \"PKTABLE_SCHEM\", PARENT.TABLE_NAME AS \"PKTABLE_NAME\",\n"
+          + "       PARENT.COLUMN_NAME AS \"PKCOLUMN_NAME\", CHILD.TABLE_CATALOG AS \"FKTABLE_CAT\", CHILD.TABLE_SCHEMA AS \"FKTABLE_SCHEM\",\n"
+          + "       CHILD.TABLE_NAME AS \"FKTABLE_NAME\", CHILD.COLUMN_NAME AS \"FKCOLUMN_NAME\",\n"
+          + "       CHILD.ORDINAL_POSITION AS \"KEY_SEQ\",\n"
+          + "       1 AS \"UPDATE_RULE\", -- 1 = importedKeyRestrict\n"
+          + "       1 AS \"DELETE_RULE\", -- 1 = importedKeyRestrict\n"
+          + "       CONSTRAINTS.CONSTRAINT_NAME AS \"FK_NAME\", CONSTRAINTS.UNIQUE_CONSTRAINT_NAME AS \"PK_NAME\",\n"
+          + "       7 AS \"DEFERRABILITY\" -- 7 = importedKeyNotDeferrable\n"
+          + "FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS CONSTRAINTS\n"
+          + "INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CHILD  ON COALESCE(CONSTRAINTS.CONSTRAINT_CATALOG, '')=COALESCE(CHILD.CONSTRAINT_CATALOG, '') AND CONSTRAINTS.CONSTRAINT_SCHEMA= CHILD.CONSTRAINT_SCHEMA AND CONSTRAINTS.CONSTRAINT_NAME= CHILD.CONSTRAINT_NAME\n"
+          + "INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE PARENT ON COALESCE(CONSTRAINTS.UNIQUE_CONSTRAINT_CATALOG, '')=COALESCE(PARENT.CONSTRAINT_CATALOG, '') AND CONSTRAINTS.UNIQUE_CONSTRAINT_SCHEMA=PARENT.CONSTRAINT_SCHEMA AND CONSTRAINTS.UNIQUE_CONSTRAINT_NAME=PARENT.CONSTRAINT_NAME AND PARENT.ORDINAL_POSITION=CHILD.POSITION_IN_UNIQUE_CONSTRAINT\n"
+          + "WHERE TRUE\n";
 
   public static final String PG_DESCRIPTION =
       "select * from (select 0 as objoid, 0 as classoid, 0 as objsubid, '' as description) pg_description where false";


Test patch:
diff --git a/src/test/java/com/google/cloud/spanner/pgadapter/AbortedMockServerTest.java b/src/test/java/com/google/cloud/spanner/pgadapter/AbortedMockServerTest.java
index fd706cc3..d25d89d7 100644
--- a/src/test/java/com/google/cloud/spanner/pgadapter/AbortedMockServerTest.java
+++ b/src/test/java/com/google/cloud/spanner/pgadapter/AbortedMockServerTest.java
@@ -1129,7 +1129,7 @@ public class AbortedMockServerTest extends AbstractMockServerTest {
       try (ResultSet resultSet =
           connection.createStatement().executeQuery("show application_name ")) {
         assertTrue(resultSet.next());
-        assertEquals(getExpectedInitialApplicationName(), resultSet.getString(1));
+        assertNull(resultSet.getString(1));
         assertFalse(resultSet.next());
       }
     }
@@ -1422,7 +1422,7 @@ public class AbortedMockServerTest extends AbstractMockServerTest {
 
       connection.createStatement().execute("reset all");
 
-      verifySettingValue(connection, "application_name", getExpectedInitialApplicationName());
+      verifySettingIsNull(connection, "application_name");
       verifySettingValue(connection, "search_path", "public");
     }
   }
@@ -1438,7 +1438,7 @@ public class AbortedMockServerTest extends AbstractMockServerTest {
       connection.createStatement().execute("set application_name to default");
       connection.createStatement().execute("set search_path to default");
 
-      verifySettingValue(connection, "application_name", getExpectedInitialApplicationName());
+      verifySettingIsNull(connection, "application_name");
       verifySettingValue(connection, "search_path", "public");
     }
   }
diff --git a/src/test/java/com/google/cloud/spanner/pgadapter/EmulatedPgbenchMockServerTest.java b/src/test/java/com/google/cloud/spanner/pgadapter/EmulatedPgbenchMockServerTest.java
index 9e477b2d..925aef50 100644
--- a/src/test/java/com/google/cloud/spanner/pgadapter/EmulatedPgbenchMockServerTest.java
+++ b/src/test/java/com/google/cloud/spanner/pgadapter/EmulatedPgbenchMockServerTest.java
@@ -31,11 +31,11 @@ import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.SQLException;
 import java.sql.SQLWarning;
+import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
-import org.postgresql.PGProperty;
 import org.postgresql.util.PSQLException;
 import org.postgresql.util.PSQLWarning;
 
@@ -48,17 +48,23 @@ public class EmulatedPgbenchMockServerTest extends AbstractMockServerTest {
     Class.forName("org.postgresql.Driver");
   }
 
+  @BeforeClass
+  public static void setDetectClient() {
+    ClientAutoDetector.FORCE_DETECT_CLIENT.set(WellKnownClient.PGBENCH);
+  }
+
+  @AfterClass
+  public static void clearDetectClient() {
+    ClientAutoDetector.FORCE_DETECT_CLIENT.set(null);
+  }
+
   /**
    * Creates a JDBC connection string that instructs the PG JDBC driver to use the default simple
-   * mode. It also adds 'pgbench' as the application name, which will make PGAdapter automatically
-   * recognize the connection as a pgbench connection.
+   * mode.
    */
   private String createUrl() {
     return String.format(
-        "jdbc:postgresql://localhost:%d/db?preferQueryMode=simple&%s=pgbench&%s=090000",
-        pgServer.getLocalPort(),
-        PGProperty.APPLICATION_NAME.getName(),
-        PGProperty.ASSUME_MIN_SERVER_VERSION.getName());
+        "jdbc:postgresql://localhost:%d/db?preferQueryMode=simple", pgServer.getLocalPort());
   }
 
   @Test
diff --git a/src/test/java/com/google/cloud/spanner/pgadapter/EmulatedPsqlMockServerTest.java b/src/test/java/com/google/cloud/spanner/pgadapter/EmulatedPsqlMockServerTest.java
index 5ec2f0c1..4b6d2c8a 100644
--- a/src/test/java/com/google/cloud/spanner/pgadapter/EmulatedPsqlMockServerTest.java
+++ b/src/test/java/com/google/cloud/spanner/pgadapter/EmulatedPsqlMockServerTest.java
@@ -26,6 +26,8 @@ import com.google.cloud.spanner.MockSpannerServiceImpl.StatementResult;
 import com.google.cloud.spanner.Statement;
 import com.google.cloud.spanner.pgadapter.error.PGException;
 import com.google.cloud.spanner.pgadapter.statements.IntermediateStatement;
+import com.google.cloud.spanner.pgadapter.utils.ClientAutoDetector;
+import com.google.cloud.spanner.pgadapter.utils.ClientAutoDetector.WellKnownClient;
 import com.google.common.collect.ImmutableList;
 import com.google.protobuf.ListValue;
 import com.google.protobuf.Value;
@@ -57,12 +59,12 @@ import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.List;
 import org.junit.After;
+import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
-import org.postgresql.PGProperty;
 import org.postgresql.util.PSQLException;
 
 @RunWith(JUnit4.class)
@@ -77,6 +79,16 @@ public class EmulatedPsqlMockServerTest extends AbstractMockServerTest {
     Class.forName("org.postgresql.Driver");
   }
 
+  @BeforeClass
+  public static void setDetectClient() {
+    ClientAutoDetector.FORCE_DETECT_CLIENT.set(WellKnownClient.PSQL);
+  }
+
+  @AfterClass
+  public static void clearDetectClient() {
+    ClientAutoDetector.FORCE_DETECT_CLIENT.set(null);
+  }
+
   @BeforeClass
   public static void startMockSpannerAndPgAdapterServers() throws Exception {
     // Start PGAdapter without a default database.
@@ -95,21 +107,12 @@ public class EmulatedPsqlMockServerTest extends AbstractMockServerTest {
   /**
    * Creates a JDBC connection string that instructs the PG JDBC driver to use the default simple
    * mode for queries and DML statements. This makes the JDBC driver behave in (much) the same way
-   * as psql. It also adds 'psql' as the application name, which will make PGAdapter automatically
-   * recognize the connection as a psql connection.
+   * as psql.
    */
   private String createUrl(String database) {
-    return createUrl(database, "psql");
-  }
-
-  private String createUrl(String database, String applicationName) {
     return String.format(
-        "jdbc:postgresql://localhost:%d/%s?preferQueryMode=simple&%s=%s&%s=090000",
-        pgServer.getLocalPort(),
-        database,
-        PGProperty.APPLICATION_NAME.getName(),
-        applicationName,
-        PGProperty.ASSUME_MIN_SERVER_VERSION.getName());
+        "jdbc:postgresql://localhost:%d/%s?preferQueryMode=simple",
+        pgServer.getLocalPort(), database);
   }
 
   @Test
@@ -201,22 +204,15 @@ public class EmulatedPsqlMockServerTest extends AbstractMockServerTest {
     }
   }
 
-  @Test
-  public void testShowApplicationName() throws SQLException {
-    try (Connection connection = DriverManager.getConnection(createUrl("my-db"))) {
-      try (ResultSet resultSet =
-          connection.createStatement().executeQuery("show application_name")) {
-        assertTrue(resultSet.next());
-        assertEquals("psql", resultSet.getString(1));
-        assertFalse(resultSet.next());
-      }
-    }
-  }
-
   @Test
   public void testConnectToNonExistingInstance() {
-    for (String appName : new String[] {"psql", "other-app"}) {
+    for (boolean isPsql : new boolean[] {true, false}) {
       try {
+        if (isPsql) {
+          setDetectClient();
+        } else {
+          clearDetectClient();
+        }
         mockSpanner.setExecuteStreamingSqlExecutionTime(
             SimulatedExecutionTime.ofStickyException(
                 newStatusResourceNotFoundException(
@@ -241,10 +237,9 @@ public class EmulatedPsqlMockServerTest extends AbstractMockServerTest {
         SQLException exception =
             assertThrows(
                 SQLException.class,
-                () -> DriverManager.getConnection(createUrl("non-existing-db", appName)));
+                () -> DriverManager.getConnection(createUrl("non-existing-db")));
         assertTrue(exception.getMessage(), exception.getMessage().contains("NOT_FOUND"));
 
-        boolean isPsql = "psql".equals(appName);
         assertEquals(
             exception.getMessage(),
             isPsql,
@@ -255,6 +250,7 @@ public class EmulatedPsqlMockServerTest extends AbstractMockServerTest {
             exception.getMessage().contains("\tprojects/p/instances/i\n"));
       } finally {
         closeSpannerPool(true);
+        setDetectClient();
       }
     }
   }
diff --git a/src/test/java/com/google/cloud/spanner/pgadapter/ITJdbcMetadataTest.java b/src/test/java/com/google/cloud/spanner/pgadapter/ITJdbcMetadataTest.java
index daefa5a6..fa0ee6a2 100644
--- a/src/test/java/com/google/cloud/spanner/pgadapter/ITJdbcMetadataTest.java
+++ b/src/test/java/com/google/cloud/spanner/pgadapter/ITJdbcMetadataTest.java
@@ -53,13 +53,12 @@ import org.junit.runners.JUnit4;
 public class ITJdbcMetadataTest implements IntegrationTest {
   private static final String[] VERSIONS =
       new String[] {
-        "42.7.4", "42.7.3", "42.7.2", "42.7.1", "42.7.0", "42.6.0", "42.5.4", "42.5.3", "42.5.2",
-        "42.5.1", "42.5.0", "42.4.2", "42.4.1", "42.4.0", "42.3.6", "42.3.5", "42.3.4", "42.3.3",
-        "42.3.2", "42.3.1", "42.3.0", "42.2.25", "42.2.24", "42.2.23", "42.2.22", "42.2.21",
-        "42.2.20", "42.2.19", "42.2.18", "42.2.17", "42.2.16", "42.2.15", "42.2.14", "42.2.13",
-        "42.2.12", "42.2.11", "42.2.10", "42.2.9", "42.2.8", "42.2.7", "42.2.6", "42.2.5", "42.2.4",
-        "42.2.3", "42.2.2", "42.2.1", "42.2.0", "42.1.4",
-        /* "42.1.3", "42.1.2", "42.1.1", "42.1.0", "42.0.0" */
+        "42.7.5", "42.7.4", "42.7.3", "42.7.2", "42.7.1", "42.7.0", "42.6.0", "42.5.4", "42.5.3",
+        "42.5.2", "42.5.1", "42.5.0", "42.4.2", "42.4.1", "42.4.0", "42.3.6", "42.3.5", "42.3.4",
+        "42.3.3", "42.3.2", "42.3.1", "42.3.0", "42.2.25", "42.2.24", "42.2.23", "42.2.22",
+        "42.2.21", "42.2.20", "42.2.19", "42.2.18", "42.2.17", "42.2.16", "42.2.15", "42.2.14",
+        "42.2.13", "42.2.12", "42.2.11", "42.2.10", "42.2.9", "42.2.8", "42.2.7", "42.2.6",
+        "42.2.5", "42.2.4", "42.2.3", "42.2.2", "42.2.1", "42.2.0", "42.1.4"
       };
 
   private static final PgAdapterTestEnv testEnv = new PgAdapterTestEnv();
diff --git a/src/test/java/com/google/cloud/spanner/pgadapter/JdbcMockServerTest.java b/src/test/java/com/google/cloud/spanner/pgadapter/JdbcMockServerTest.java
index 89fd118d..d050fdec 100644
--- a/src/test/java/com/google/cloud/spanner/pgadapter/JdbcMockServerTest.java
+++ b/src/test/java/com/google/cloud/spanner/pgadapter/JdbcMockServerTest.java
@@ -122,7 +122,9 @@ public class JdbcMockServerTest extends AbstractMockServerTest {
   private static final Statement SELECT_RANDOM = Statement.of("select * from random_table");
   private static final ImmutableList<String> JDBC_STARTUP_STATEMENTS =
       ImmutableList.of(
-          "SET extra_float_digits = 3", "SET application_name = 'PostgreSQL JDBC Driver'");
+          "SET extra_float_digits = 2",
+          "SET extra_float_digits = 3",
+          "SET application_name = 'PostgreSQL JDBC Driver'");
 
   @Parameter public String pgVersion;
 
@@ -403,7 +405,7 @@ public class JdbcMockServerTest extends AbstractMockServerTest {
   }
 
   private String getExpectedInitialApplicationName() {
-    return "PostgreSQL JDBC Driver";
+    return pgVersion.equals("1.0") ? "jdbc" : "PostgreSQL JDBC Driver";
   }
 
   @Test
@@ -522,7 +524,7 @@ public class JdbcMockServerTest extends AbstractMockServerTest {
                     + "  /* Preferably, this should use information_schema.information_schema_catalog_name, but that does not exist on the emulator. */\n"
                     + "  from (select distinct catalog_name from information_schema.schemata) catalogs\n"
                     + ")\n"
-                    + "SELECT datname AS TABLE_CAT FROM pg_database WHERE datallowconn = true ORDER BY datname"),
+                    + "SELECT datname AS \"TABLE_CAT\" FROM pg_database WHERE datallowconn = true ORDER BY datname"),
             com.google.spanner.v1.ResultSet.newBuilder()
                 .setMetadata(
                     ResultSetMetadata.newBuilder()
@@ -3863,7 +3865,7 @@ public class JdbcMockServerTest extends AbstractMockServerTest {
       try (ResultSet resultSet =
           connection.createStatement().executeQuery("show application_name ")) {
         assertTrue(resultSet.next());
-        assertEquals(getExpectedInitialApplicationName(), resultSet.getString(1));
+        assertNull(resultSet.getString(1));
         assertFalse(resultSet.next());
       }
     }
@@ -4162,7 +4164,7 @@ public class JdbcMockServerTest extends AbstractMockServerTest {
 
       connection.createStatement().execute("reset all");
 
-      verifySettingValue(connection, "application_name", getExpectedInitialApplicationName());
+      verifySettingIsNull(connection, "application_name");
       verifySettingValue(connection, "search_path", "public");
       verifySettingValue(connection, "spanner.autocommit_dml_mode", "TRANSACTIONAL");
     }
@@ -4171,6 +4173,8 @@ public class JdbcMockServerTest extends AbstractMockServerTest {
   @Test
   public void testSetToDefault() throws SQLException {
     try (Connection connection = DriverManager.getConnection(createUrl())) {
+      verifySettingValue(connection, "application_name", getExpectedInitialApplicationName());
+
       connection.createStatement().execute("set application_name to 'my-app'");
       connection.createStatement().execute("set search_path to 'my_schema'");
       verifySettingValue(connection, "application_name", "my-app");
@@ -4179,7 +4183,7 @@ public class JdbcMockServerTest extends AbstractMockServerTest {
       connection.createStatement().execute("set application_name to default");
       connection.createStatement().execute("set search_path to default");
 
-      verifySettingValue(connection, "application_name", getExpectedInitialApplicationName());
+      verifySettingIsNull(connection, "application_name");
       verifySettingValue(connection, "search_path", "public");
     }
   }
diff --git a/src/test/java/com/google/cloud/spanner/pgadapter/ruby/ActiveRecordMockServerTest.java b/src/test/java/com/google/cloud/spanner/pgadapter/ruby/ActiveRecordMockServerTest.java
index a28362b6..b206ea23 100644
--- a/src/test/java/com/google/cloud/spanner/pgadapter/ruby/ActiveRecordMockServerTest.java
+++ b/src/test/java/com/google/cloud/spanner/pgadapter/ruby/ActiveRecordMockServerTest.java
@@ -25,6 +25,8 @@ import com.google.cloud.Date;
 import com.google.cloud.Timestamp;
 import com.google.cloud.spanner.MockSpannerServiceImpl.StatementResult;
 import com.google.cloud.spanner.Statement;
+import com.google.cloud.spanner.pgadapter.utils.ClientAutoDetector;
+import com.google.cloud.spanner.pgadapter.utils.ClientAutoDetector.WellKnownClient;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.protobuf.ListValue;
@@ -200,6 +202,7 @@ public class ActiveRecordMockServerTest extends AbstractRubyMockServerTest {
   @Test
   public void testErrorHints() throws SQLException {
     // Emulate an ActiveRecord connection.
+    ClientAutoDetector.FORCE_DETECT_CLIENT.set(WellKnownClient.RAILS);
     String url =
         String.format(
             "jdbc:postgresql://localhost:%d/db?%s=rails&%s=090000",
@@ -250,6 +253,8 @@ public class ActiveRecordMockServerTest extends AbstractRubyMockServerTest {
           exception.getServerErrorMessage().getMessage(),
           "Table foo not found - Statement: 'SELECT * FROM foo'");
       assertNull(exception.getServerErrorMessage().getHint());
+    } finally {
+      ClientAutoDetector.FORCE_DETECT_CLIENT.set(null);
     }
   }
 
diff --git a/src/test/ruby/activerecord/config/database.yml b/src/test/ruby/activerecord/config/database.yml
index 64cf5297..901a6ac7 100644
--- a/src/test/ruby/activerecord/config/database.yml
+++ b/src/test/ruby/activerecord/config/database.yml
@@ -1,6 +1,8 @@
 development:
   adapter: postgresql
   pool: 5
+  # Schema dumping uses pg_catalog tables and functions that are not supported by Spanner.
+  schema_dump: false
   # Advisory locks are not supported by PGAdapter
   advisory_locks: false
   # These settings ensure that migrations and schema inspections work.
diff --git a/src/test/ruby/activerecord/db/schema.rb b/src/test/ruby/activerecord/db/schema.rb
deleted file mode 100644
index 6ca4a69b..00000000
--- a/src/test/ruby/activerecord/db/schema.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-# This file is auto-generated from the current state of the database. Instead
-# of editing this file, please use the migrations feature of Active Record to
-# incrementally modify your database, and then regenerate this schema definition.
-#
-# This file is the source Rails uses to define your schema when running `bin/rails
-# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
-# be faster and is potentially less error prone than running all of your
-# migrations from scratch. Old migrations may fail to apply correctly if those
-# migrations use external dependencies or application code.
-#
-# It's strongly recommended that you check this file into your version control system.
-
-ActiveRecord::Schema[7.0].define(version: 1) do
-  create_table "albums", primary_key: "album_id", id: { type: :string, limit: 36 }, comment: "", force: :cascade do |t|
-    t.string "title"
-    t.decimal "marketing_budget"
-    t.date "release_date"
-    t.binary "cover_picture"
-    t.string "singer_id", limit: 36
-    t.datetime "created_at", precision: nil
-    t.datetime "updated_at", precision: nil
-    t.bigint "lock_version", null: false
-    t.index [], name: "IDX_albums_singer_id_N_90CD66D06B92DBCF"
-  end
-
-  create_table "concerts", primary_key: "concert_id", id: { type: :string, limit: 36 }, comment: "", force: :cascade do |t|
-    t.string "venue_id", limit: 36
-    t.string "singer_id", limit: 36
-    t.string "name"
-    t.datetime "start_time", precision: nil, null: false
-    t.datetime "end_time", precision: nil, null: false
-    t.datetime "created_at", precision: nil
-    t.datetime "updated_at", precision: nil
-    t.bigint "lock_version", null: false
-    t.index [], name: "IDX_concerts_singer_id_N_E92CCCE963BE681C"
-    t.index [], name: "IDX_concerts_venue_id_N_F08F98ABB662E6D5"
-    t.check_constraint nil, name: "chk_end_time_after_start_time"
-  end
-
-  create_table "singers", primary_key: "singer_id", id: { type: :string, limit: 36 }, comment: "", force: :cascade do |t|
-    t.string "first_name", limit: 100
-    t.string "last_name", limit: 200, null: false
-    t.virtual "full_name", type: :string, as: "COALESCE(concat(first_name, ' '::character varying, last_name), last_name)", stored: true
-    t.boolean "active"
-    t.datetime "created_at", precision: nil
-    t.datetime "updated_at", precision: nil
-    t.bigint "lock_version", null: false
-  end
-
-  create_table "tracks", primary_key: ["album_id", "track_number"], comment: "", force: :cascade do |t|
-    t.string "album_id", limit: 36, null: false
-    t.bigint "track_number", null: false
-    t.string "title", null: false
-    t.float "sample_rate", null: false
-    t.datetime "created_at", precision: nil
-    t.datetime "updated_at", precision: nil
-    t.bigint "lock_version", null: false
-  end
-
-  create_table "venues", primary_key: "venue_id", id: { type: :string, limit: 36 }, comment: "", force: :cascade do |t|
-    t.string "name"
-    t.jsonb "description"
-    t.datetime "created_at", precision: nil
-    t.datetime "updated_at", precision: nil
-    t.bigint "lock_version", null: false
-  end
-
-  add_foreign_key "albums", "singers", primary_key: "singer_id"
-  add_foreign_key "concerts", "singers", primary_key: "singer_id"
-  add_foreign_key "concerts", "venues", primary_key: "venue_id"
-end