Repository: googleapis/java-spanner-jdbc
Pull request #1565 (2024-04-15 10:04:35)

deps: update dependency com.google.cloud:google-cloud-spanner-bom to v6.64.0
[![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-bom](https://togithub.com/googleapis/java-spanner) | `6.63.0` -> `6.64.0` | [![age](https://developer.mend.io/api/mc/badges/age/maven/com.google.cloud:google-cloud-spanner-bom/6.64.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/com.google.cloud:google-cloud-spanner-bom/6.64.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/com.google.cloud:google-cloud-spanner-bom/6.63.0/6.64.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/com.google.cloud:google-cloud-spanner-bom/6.63.0/6.64.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

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

### [`v6.64.0`](https://togithub.com/googleapis/java-spanner/blob/HEAD/CHANGELOG.md#6640-2024-04-12)

[Compare Source](https://togithub.com/googleapis/java-spanner/compare/v6.63.0...v6.64.0)

##### Features

-   Add endpoint connection URL property ([#&#8203;2969](https://togithub.com/googleapis/java-spanner/issues/2969)) ([c9be29c](https://togithub.com/googleapis/java-spanner/commit/c9be29c717924d7f4c5acd8fe09ee371d0101642))
-   Add PG OID support ([#&#8203;2736](https://togithub.com/googleapis/java-spanner/issues/2736)) ([ba2a4af](https://togithub.com/googleapis/java-spanner/commit/ba2a4afa5c1d64c932e9687d52b15c28d9dd7d91))
-   Add SessionPoolOptions, SpannerOptions protos in executor protos ([#&#8203;2932](https://togithub.com/googleapis/java-spanner/issues/2932)) ([1673fd7](https://togithub.com/googleapis/java-spanner/commit/1673fd70df4ebfaa4b5fa07112d152119427699a))
-   Support max_commit_delay in Connection API ([#&#8203;2954](https://togithub.com/googleapis/java-spanner/issues/2954)) ([a8f1852](https://togithub.com/googleapis/java-spanner/commit/a8f185261c812e7d6c92cb61ecc1f9c78ba3c4d9))

##### Bug Fixes

-   Executor framework changes skipped in clirr checks, and added exception for partition methods in admin class ([#&#8203;3000](https://togithub.com/googleapis/java-spanner/issues/3000)) ([c2d8e95](https://togithub.com/googleapis/java-spanner/commit/c2d8e955abddb0117f1b3b94c2d9650d2cf4fdfd))

##### Dependencies

-   Update actions/checkout action to v4 ([#&#8203;3006](https://togithub.com/googleapis/java-spanner/issues/3006)) ([368a9f3](https://togithub.com/googleapis/java-spanner/commit/368a9f33758961d8e3fd387ec94d380e7c6460cc))
-   Update actions/github-script action to v7 ([#&#8203;3007](https://togithub.com/googleapis/java-spanner/issues/3007)) ([b0cfea6](https://togithub.com/googleapis/java-spanner/commit/b0cfea6e73b7293f564357e8d1c8c6bb2e0cf855))
-   Update actions/setup-java action to v4 ([#&#8203;3008](https://togithub.com/googleapis/java-spanner/issues/3008)) ([d337080](https://togithub.com/googleapis/java-spanner/commit/d337080089dbd58cb4bf94f2cb5925f627435d39))
-   Update dependency com.google.cloud:google-cloud-monitoring to v3.42.0 ([#&#8203;2997](https://togithub.com/googleapis/java-spanner/issues/2997)) ([0615beb](https://togithub.com/googleapis/java-spanner/commit/0615beb806ef62dbbfcc6bbffd082adc9c62372c))
-   Update dependency com.google.cloud:google-cloud-trace to v2.41.0 ([#&#8203;2998](https://togithub.com/googleapis/java-spanner/issues/2998)) ([f50cd04](https://togithub.com/googleapis/java-spanner/commit/f50cd04660f480c62ddbd6c8a9e892cd95ec16b0))
-   Update dependency commons-io:commons-io to v2.16.1 ([#&#8203;3020](https://togithub.com/googleapis/java-spanner/issues/3020)) ([aafd5b9](https://togithub.com/googleapis/java-spanner/commit/aafd5b9514c14a0dbfd0bf2616990f3c347ac0c6))
-   Update opentelemetry.version to v1.37.0 ([#&#8203;3021](https://togithub.com/googleapis/java-spanner/issues/3021)) ([8f1ed2a](https://togithub.com/googleapis/java-spanner/commit/8f1ed2ac20896fb413749bb18652764096f1fb2d))
-   Update stcarolas/setup-maven action to v5 ([#&#8203;3009](https://togithub.com/googleapis/java-spanner/issues/3009)) ([541acd2](https://togithub.com/googleapis/java-spanner/commit/541acd23aaf2c9336615406e30618fb65606e6c5))

</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:eyJjcmVhdGVkSW5WZXIiOiIzNy4yOTMuMCIsInVwZGF0ZWRJblZlciI6IjM3LjI5My4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->



Patch:
diff --git a/pom.xml b/pom.xml
index 2e94786..f4a9fc8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -62,7 +62,7 @@
       <dependency>
         <groupId>com.google.cloud</groupId>
         <artifactId>google-cloud-spanner-bom</artifactId>
-        <version>6.63.0</version>
+        <version>6.64.0</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
diff --git a/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcWrapper.java b/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcWrapper.java
index b06e599..aa65ee6 100644
--- a/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcWrapper.java
+++ b/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcWrapper.java
@@ -16,6 +16,8 @@
 
 package com.google.cloud.spanner.jdbc;
 
+import static com.google.cloud.spanner.jdbc.JdbcTypeConverter.getMainTypeCode;
+
 import com.google.cloud.spanner.Dialect;
 import com.google.cloud.spanner.Type;
 import com.google.cloud.spanner.Type.Code;
@@ -42,7 +44,7 @@ abstract class AbstractJdbcWrapper implements Wrapper {
    */
   static int extractColumnType(Type type) {
     Preconditions.checkNotNull(type);
-    switch (type.getCode()) {
+    switch (getMainTypeCode(type)) {
       case BOOL:
         return Types.BOOLEAN;
       case BYTES:
@@ -139,7 +141,7 @@ abstract class AbstractJdbcWrapper implements Wrapper {
    */
   static String getClassName(Type type) {
     Preconditions.checkNotNull(type);
-    switch (type.getCode()) {
+    switch (getMainTypeCode(type)) {
       case BOOL:
         return Boolean.class.getName();
       case BYTES:
@@ -162,7 +164,7 @@ abstract class AbstractJdbcWrapper implements Wrapper {
       case TIMESTAMP:
         return Timestamp.class.getName();
       case ARRAY:
-        switch (type.getArrayElementType().getCode()) {
+        switch (getMainTypeCode(type.getArrayElementType())) {
           case BOOL:
             return Boolean[].class.getName();
           case BYTES:
diff --git a/src/main/java/com/google/cloud/spanner/jdbc/JdbcResultSet.java b/src/main/java/com/google/cloud/spanner/jdbc/JdbcResultSet.java
index 91ec976..dcb2598 100644
--- a/src/main/java/com/google/cloud/spanner/jdbc/JdbcResultSet.java
+++ b/src/main/java/com/google/cloud/spanner/jdbc/JdbcResultSet.java
@@ -16,6 +16,8 @@
 
 package com.google.cloud.spanner.jdbc;
 
+import static com.google.cloud.spanner.jdbc.JdbcTypeConverter.getMainTypeCode;
+
 import com.google.cloud.spanner.ResultSets;
 import com.google.cloud.spanner.Struct;
 import com.google.cloud.spanner.Type;
@@ -195,7 +197,7 @@ class JdbcResultSet extends AbstractJdbcResultSet {
     checkClosedAndValidRow();
     boolean isNull = isNull(columnIndex);
     int spannerIndex = columnIndex - 1;
-    Code type = spanner.getColumnType(spannerIndex).getCode();
+    Code type = getMainTypeCode(spanner.getColumnType(spannerIndex));
     switch (type) {
       case BOOL:
         return isNull ? null : String.valueOf(spanner.getBoolean(spannerIndex));
@@ -233,7 +235,7 @@ class JdbcResultSet extends AbstractJdbcResultSet {
     checkClosedAndValidRow();
     boolean isNull = isNull(columnIndex);
     int spannerIndex = columnIndex - 1;
-    Code type = spanner.getColumnType(spannerIndex).getCode();
+    Code type = getMainTypeCode(spanner.getColumnType(spannerIndex));
     switch (type) {
       case BOOL:
         return !isNull && spanner.getBoolean(spannerIndex);
@@ -266,7 +268,7 @@ class JdbcResultSet extends AbstractJdbcResultSet {
     checkClosedAndValidRow();
     boolean isNull = isNull(columnIndex);
     int spannerIndex = columnIndex - 1;
-    Code type = spanner.getColumnType(spannerIndex).getCode();
+    Code type = getMainTypeCode(spanner.getColumnType(spannerIndex));
     switch (type) {
       case BOOL:
         return isNull ? (byte) 0 : (spanner.getBoolean(spannerIndex) ? (byte) 1 : 0);
@@ -305,7 +307,7 @@ class JdbcResultSet extends AbstractJdbcResultSet {
     checkClosedAndValidRow();
     boolean isNull = isNull(columnIndex);
     int spannerIndex = columnIndex - 1;
-    Code type = spanner.getColumnType(spannerIndex).getCode();
+    Code type = getMainTypeCode(spanner.getColumnType(spannerIndex));
     switch (type) {
       case BOOL:
         return isNull ? 0 : (spanner.getBoolean(spannerIndex) ? (short) 1 : 0);
@@ -344,7 +346,7 @@ class JdbcResultSet extends AbstractJdbcResultSet {
     checkClosedAndValidRow();
     boolean isNull = isNull(columnIndex);
     int spannerIndex = columnIndex - 1;
-    Code type = spanner.getColumnType(spannerIndex).getCode();
+    Code type = getMainTypeCode(spanner.getColumnType(spannerIndex));
     switch (type) {
       case BOOL:
         return isNull ? 0 : (spanner.getBoolean(spannerIndex) ? 1 : 0);
@@ -383,7 +385,7 @@ class JdbcResultSet extends AbstractJdbcResultSet {
     checkClosedAndValidRow();
     boolean isNull = isNull(columnIndex);
     int spannerIndex = columnIndex - 1;
-    Code type = spanner.getColumnType(spannerIndex).getCode();
+    Code type = getMainTypeCode(spanner.getColumnType(spannerIndex));
     switch (type) {
       case BOOL:
         return isNull ? 0L : (spanner.getBoolean(spannerIndex) ? 1L : 0L);
@@ -418,7 +420,7 @@ class JdbcResultSet extends AbstractJdbcResultSet {
     checkClosedAndValidRow();
     boolean isNull = isNull(columnIndex);
     int spannerIndex = columnIndex - 1;
-    Code type = spanner.getColumnType(spannerIndex).getCode();
+    Code type = getMainTypeCode(spanner.getColumnType(spannerIndex));
     switch (type) {
       case BOOL:
         return isNull ? 0 : (spanner.getBoolean(spannerIndex) ? (float) 1 : 0);
@@ -451,7 +453,7 @@ class JdbcResultSet extends AbstractJdbcResultSet {
     checkClosedAndValidRow();
     boolean isNull = isNull(columnIndex);
     int spannerIndex = columnIndex - 1;
-    Code type = spanner.getColumnType(spannerIndex).getCode();
+    Code type = getMainTypeCode(spanner.getColumnType(spannerIndex));
     switch (type) {
       case BOOL:
         return isNull ? 0 : (spanner.getBoolean(spannerIndex) ? (double) 1 : 0);
@@ -492,7 +494,7 @@ class JdbcResultSet extends AbstractJdbcResultSet {
     checkClosedAndValidRow();
     boolean isNull = isNull(columnIndex);
     int spannerIndex = columnIndex - 1;
-    Code type = spanner.getColumnType(spannerIndex).getCode();
+    Code type = getMainTypeCode(spanner.getColumnType(spannerIndex));
     switch (type) {
       case DATE:
         return isNull ? null : JdbcTypeConverter.toSqlDate(spanner.getDate(spannerIndex));
@@ -523,7 +525,7 @@ class JdbcResultSet extends AbstractJdbcResultSet {
     checkClosedAndValidRow();
     boolean isNull = isNull(columnIndex);
     int spannerIndex = columnIndex - 1;
-    Code type = spanner.getColumnType(spannerIndex).getCode();
+    Code type = getMainTypeCode(spanner.getColumnType(spannerIndex));
     switch (type) {
       case STRING:
         return isNull ? null : parseTime(spanner.getString(spannerIndex));
@@ -551,7 +553,7 @@ class JdbcResultSet extends AbstractJdbcResultSet {
     checkClosedAndValidRow();
     boolean isNull = isNull(columnIndex);
     int spannerIndex = columnIndex - 1;
-    Code type = spanner.getColumnType(spannerIndex).getCode();
+    Code type = getMainTypeCode(spanner.getColumnType(spannerIndex));
     switch (type) {
       case DATE:
         return isNull ? null : JdbcTypeConverter.toSqlTimestamp(spanner.getDate(spannerIndex));
@@ -716,6 +718,7 @@ class JdbcResultSet extends AbstractJdbcResultSet {
   }
 
   private Object getObject(Type type, int columnIndex) throws SQLException {
+    // TODO: Refactor to check based on type code.
     if (type == Type.bool()) return getBoolean(columnIndex);
     if (type == Type.bytes()) return getBytes(columnIndex);
     if (type == Type.date()) return getDate(columnIndex);
@@ -723,7 +726,9 @@ class JdbcResultSet extends AbstractJdbcResultSet {
       return getFloat(columnIndex);
     }
     if (type == Type.float64()) return getDouble(columnIndex);
-    if (type == Type.int64()) return getLong(columnIndex);
+    if (type == Type.int64() || type == Type.pgOid()) {
+      return getLong(columnIndex);
+    }
     if (type == Type.numeric()) return getBigDecimal(columnIndex);
     if (type == Type.pgNumeric()) {
       final String value = getString(columnIndex);
@@ -734,7 +739,9 @@ class JdbcResultSet extends AbstractJdbcResultSet {
       }
     }
     if (type == Type.string()) return getString(columnIndex);
-    if (type == Type.json()) return getString(columnIndex);
+    if (type == Type.json() || type == Type.pgJsonb()) {
+      return getString(columnIndex);
+    }
     if (type == Type.timestamp()) return getTimestamp(columnIndex);
     if (type.getCode() == Code.ARRAY) return getArray(columnIndex);
     throw JdbcSqlExceptionFactory.of("Unknown type: " + type, com.google.rpc.Code.INVALID_ARGUMENT);
@@ -792,7 +799,7 @@ class JdbcResultSet extends AbstractJdbcResultSet {
   private BigDecimal getBigDecimal(int columnIndex, boolean fixedScale, int scale)
       throws SQLException {
     int spannerIndex = columnIndex - 1;
-    Code type = spanner.getColumnType(spannerIndex).getCode();
+    Code type = getMainTypeCode(spanner.getColumnType(spannerIndex));
     boolean isNull = isNull(columnIndex);
     BigDecimal res;
     switch (type) {
@@ -888,7 +895,7 @@ class JdbcResultSet extends AbstractJdbcResultSet {
       throw JdbcSqlExceptionFactory.of(
           "Column with index " + columnIndex + " does not contain an array",
           com.google.rpc.Code.INVALID_ARGUMENT);
-    final Code elementCode = type.getArrayElementType().getCode();
+    final Code elementCode = getMainTypeCode(type.getArrayElementType());
     final JdbcDataType dataType = JdbcDataType.getType(elementCode);
     try {
       List<?> elements = dataType.getArrayElements(spanner, columnIndex - 1);
@@ -907,7 +914,7 @@ class JdbcResultSet extends AbstractJdbcResultSet {
       return null;
     }
     int spannerIndex = columnIndex - 1;
-    Code type = spanner.getColumnType(spannerIndex).getCode();
+    Code type = getMainTypeCode(spanner.getColumnType(spannerIndex));
     switch (type) {
       case DATE:
         return JdbcTypeConverter.toSqlDate(spanner.getDate(spannerIndex), cal);
@@ -941,7 +948,7 @@ class JdbcResultSet extends AbstractJdbcResultSet {
     checkClosedAndValidRow();
     boolean isNull = isNull(columnIndex);
     int spannerIndex = columnIndex - 1;
-    Code type = spanner.getColumnType(spannerIndex).getCode();
+    Code type = getMainTypeCode(spanner.getColumnType(spannerIndex));
     switch (type) {
       case STRING:
         return isNull ? null : parseTime(spanner.getString(spannerIndex), cal);
@@ -975,7 +982,7 @@ class JdbcResultSet extends AbstractJdbcResultSet {
       return null;
     }
     int spannerIndex = columnIndex - 1;
-    Code type = spanner.getColumnType(spannerIndex).getCode();
+    Code type = getMainTypeCode(spanner.getColumnType(spannerIndex));
     switch (type) {
       case DATE:
         return JdbcTypeConverter.toSqlTimestamp(spanner.getDate(spannerIndex), cal);
diff --git a/src/main/java/com/google/cloud/spanner/jdbc/JdbcTypeConverter.java b/src/main/java/com/google/cloud/spanner/jdbc/JdbcTypeConverter.java
index c6be0a8..1733302 100644
--- a/src/main/java/com/google/cloud/spanner/jdbc/JdbcTypeConverter.java
+++ b/src/main/java/com/google/cloud/spanner/jdbc/JdbcTypeConverter.java
@@ -22,6 +22,7 @@ import com.google.cloud.Timestamp;
 import com.google.cloud.spanner.Type;
 import com.google.cloud.spanner.Type.Code;
 import com.google.cloud.spanner.Value;
+import com.google.common.base.Preconditions;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.nio.charset.Charset;
@@ -46,6 +47,17 @@ class JdbcTypeConverter {
   private static final DateTimeFormatter TIMESTAMP_FORMAT = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
   private static final Charset UTF8 = StandardCharsets.UTF_8;
 
+  // TODO: Remove when this is supported in the Java client library.
+  static Code getMainTypeCode(Type type) {
+    Preconditions.checkNotNull(type);
+    switch (type.getCode()) {
+      case PG_OID:
+        return Code.INT64;
+      default:
+        return type.getCode();
+    }
+  }
+
   /**
    * Converts the given value from the Google {@link Type} to the Java {@link Class} type. The input
    * value and the {@link Type} must be consistent with each other.
@@ -205,6 +217,8 @@ class JdbcTypeConverter {
                 Arrays.asList((Double[]) ((java.sql.Array) value).getArray()));
           case INT64:
             return Value.int64Array(Arrays.asList((Long[]) ((java.sql.Array) value).getArray()));
+          case PG_OID:
+            return Value.pgOidArray(Arrays.asList((Long[]) ((java.sql.Array) value).getArray()));
           case NUMERIC:
             return Value.numericArray(
                 Arrays.asList((BigDecimal[]) ((java.sql.Array) value).getArray()));
@@ -238,6 +252,8 @@ class JdbcTypeConverter {
         return Value.float64((Double) value);
       case INT64:
         return Value.int64((Long) value);
+      case PG_OID:
+        return Value.pgOid((Long) value);
       case NUMERIC:
         return Value.numeric((BigDecimal) value);
       case PG_NUMERIC:


Test patch:
diff --git a/src/test/java/com/google/cloud/spanner/jdbc/AllTypesMockServerTest.java b/src/test/java/com/google/cloud/spanner/jdbc/AllTypesMockServerTest.java
index 4a1eb6a..cf4b7df 100644
--- a/src/test/java/com/google/cloud/spanner/jdbc/AllTypesMockServerTest.java
+++ b/src/test/java/com/google/cloud/spanner/jdbc/AllTypesMockServerTest.java
@@ -75,6 +75,9 @@ public class AllTypesMockServerTest
                 DATE_VALUE.getYear() - 1900, DATE_VALUE.getMonth() - 1, DATE_VALUE.getDayOfMonth()),
             resultSet.getDate(++col));
         assertEquals(TIMESTAMP_VALUE.toSqlTimestamp(), resultSet.getTimestamp(++col));
+        if (dialect == Dialect.POSTGRESQL) {
+          assertEquals(PG_OID_VALUE, resultSet.getLong(++col));
+        }
 
         assertEquals(
             BOOL_ARRAY_VALUE, Arrays.asList((Boolean[]) resultSet.getArray(++col).getArray()));
@@ -122,6 +125,10 @@ public class AllTypesMockServerTest
                 .map(timestamp -> timestamp == null ? null : timestamp.toSqlTimestamp())
                 .collect(Collectors.toList()),
             Arrays.asList((Timestamp[]) resultSet.getArray(++col).getArray()));
+        if (dialect == Dialect.POSTGRESQL) {
+          assertEquals(
+              PG_OID_ARRAY_VALUE, Arrays.asList((Long[]) resultSet.getArray(++col).getArray()));
+        }
 
         assertFalse(resultSet.next());
       }
@@ -140,7 +147,7 @@ public class AllTypesMockServerTest
           insertStatement
               .toBuilder()
               .replace(insertStatement.getSql().replaceAll("@p", "\\$"))
-              .bind("p15")
+              .bind("p16")
               .to(
                   com.google.cloud.spanner.Value.pgNumericArray(
                       NUMERIC_ARRAY_VALUE.stream()
@@ -179,6 +186,9 @@ public class AllTypesMockServerTest
                 DATE_VALUE.getMonth() - 1,
                 DATE_VALUE.getDayOfMonth()));
         statement.setTimestamp(++param, TIMESTAMP_VALUE.toSqlTimestamp());
+        if (dialect == Dialect.POSTGRESQL) {
+          statement.setLong(++param, PG_OID_VALUE);
+        }
 
         // TODO: Support PostgreSQL type names for creating arrays.
         statement.setArray(
@@ -241,6 +251,10 @@ public class AllTypesMockServerTest
                 TIMESTAMP_ARRAY_VALUE.stream()
                     .map(timestamp -> timestamp == null ? null : timestamp.toSqlTimestamp())
                     .toArray(Timestamp[]::new)));
+        if (dialect == Dialect.POSTGRESQL) {
+          statement.setArray(
+              ++param, connection.createArrayOf("INT64", PG_OID_ARRAY_VALUE.toArray(new Long[0])));
+        }
 
         assertEquals(1, statement.executeUpdate());
       }
@@ -249,8 +263,8 @@ public class AllTypesMockServerTest
       ExecuteSqlRequest request = mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).get(0);
       Map<String, Type> paramTypes = request.getParamTypesMap();
       Map<String, Value> params = request.getParams().getFieldsMap();
-      assertEquals(20, paramTypes.size());
-      assertEquals(20, params.size());
+      assertEquals(dialect == Dialect.POSTGRESQL ? 22 : 20, paramTypes.size());
+      assertEquals(dialect == Dialect.POSTGRESQL ? 22 : 20, params.size());
 
       // Verify param types.
       ImmutableList<TypeCode> expectedTypes =
@@ -265,6 +279,10 @@ public class AllTypesMockServerTest
               TypeCode.BYTES,
               TypeCode.DATE,
               TypeCode.TIMESTAMP);
+      if (dialect == Dialect.POSTGRESQL) {
+        expectedTypes =
+            ImmutableList.<TypeCode>builder().addAll(expectedTypes).add(TypeCode.INT64).build();
+      }
       for (int col = 0; col < expectedTypes.size(); col++) {
         assertEquals(expectedTypes.get(col), paramTypes.get("p" + (col + 1)).getCode());
         int arrayCol = col + expectedTypes.size();
@@ -290,6 +308,9 @@ public class AllTypesMockServerTest
           params.get("p" + ++col).getStringValue());
       assertEquals(DATE_VALUE.toString(), params.get("p" + ++col).getStringValue());
       assertEquals(TIMESTAMP_VALUE.toString(), params.get("p" + ++col).getStringValue());
+      if (dialect == Dialect.POSTGRESQL) {
+        assertEquals(String.valueOf(PG_OID_VALUE), params.get("p" + ++col).getStringValue());
+      }
 
       assertEquals(
           BOOL_ARRAY_VALUE,
@@ -365,6 +386,13 @@ public class AllTypesMockServerTest
                           ? null
                           : com.google.cloud.Timestamp.parseTimestamp(value.getStringValue()))
               .collect(Collectors.toList()));
+      if (dialect == Dialect.POSTGRESQL) {
+        assertEquals(
+            PG_OID_ARRAY_VALUE,
+            params.get("p" + ++col).getListValue().getValuesList().stream()
+                .map(value -> value.hasNullValue() ? null : Long.valueOf(value.getStringValue()))
+                .collect(Collectors.toList()));
+      }
     } catch (SQLException sqlException) {
       throw new RuntimeException(sqlException);
     }
diff --git a/src/test/java/com/google/cloud/spanner/jdbc/PartitionedQueryMockServerTest.java b/src/test/java/com/google/cloud/spanner/jdbc/PartitionedQueryMockServerTest.java
index 3184240..5b521b6 100644
--- a/src/test/java/com/google/cloud/spanner/jdbc/PartitionedQueryMockServerTest.java
+++ b/src/test/java/com/google/cloud/spanner/jdbc/PartitionedQueryMockServerTest.java
@@ -73,7 +73,8 @@ public class PartitionedQueryMockServerTest extends AbstractMockServerTest {
 
   private int getExpectedColumnCount(Dialect dialect) {
     // GoogleSQL also adds 4 PROTO columns.
-    return dialect == Dialect.GOOGLE_STANDARD_SQL ? 24 : 20;
+    // PostgreSQL adds 2 OID columns.
+    return dialect == Dialect.GOOGLE_STANDARD_SQL ? 24 : 22;
   }
 
   private String createUrl() {
diff --git a/src/test/java/com/google/cloud/spanner/jdbc/RandomResultSetTest.java b/src/test/java/com/google/cloud/spanner/jdbc/RandomResultSetTest.java
index 4d24068..e00907e 100644
--- a/src/test/java/com/google/cloud/spanner/jdbc/RandomResultSetTest.java
+++ b/src/test/java/com/google/cloud/spanner/jdbc/RandomResultSetTest.java
@@ -78,6 +78,9 @@ public class RandomResultSetTest extends AbstractMockServerTest {
         assertEquals(Types.BINARY, metadata.getColumnType(++col));
         assertEquals(Types.DATE, metadata.getColumnType(++col));
         assertEquals(Types.TIMESTAMP, metadata.getColumnType(++col));
+        if (dialect == Dialect.POSTGRESQL) {
+          assertEquals(Types.BIGINT, metadata.getColumnType(++col));
+        }
 
         assertEquals(Types.ARRAY, metadata.getColumnType(++col)); // boolean
         assertEquals(Types.ARRAY, metadata.getColumnType(++col)); // bigint
@@ -89,6 +92,9 @@ public class RandomResultSetTest extends AbstractMockServerTest {
         assertEquals(Types.ARRAY, metadata.getColumnType(++col)); // binary
         assertEquals(Types.ARRAY, metadata.getColumnType(++col)); // date
         assertEquals(Types.ARRAY, metadata.getColumnType(++col)); // timestamp
+        if (dialect == Dialect.POSTGRESQL) {
+          assertEquals(Types.ARRAY, metadata.getColumnType(++col)); // oid
+        }
 
         // GoogleSQL also includes proto columns.
         if (dialect == Dialect.GOOGLE_STANDARD_SQL) {
@@ -108,9 +114,7 @@ public class RandomResultSetTest extends AbstractMockServerTest {
           for (col = 1; col <= resultSet.getMetaData().getColumnCount(); col++) {
             if (dialect == Dialect.GOOGLE_STANDARD_SQL && col > 20) {
               // Proto columns are not yet supported, so skipping.
-            } else if (dialect == Dialect.POSTGRESQL && col == 7) {
-              // PG_JSONB is not yet recognized by the JDBC driver, so skipping.
-            } else if (dialect == Dialect.POSTGRESQL && col == 15) {
+            } else if (dialect == Dialect.POSTGRESQL && col == 16) {
               // getObject for ARRAY<PG_NUMERIC> tries to get the array as a List<BigDecimal>.
               // That fails if the array contains a NaN, so skipping.
             } else {
@@ -130,6 +134,9 @@ public class RandomResultSetTest extends AbstractMockServerTest {
           resultSet.getBytes(++col);
           resultSet.getDate(++col);
           resultSet.getTimestamp(++col);
+          if (dialect == Dialect.POSTGRESQL) {
+            resultSet.getLong(++col); // oid
+          }
 
           resultSet.getArray(++col);
           resultSet.getArray(++col);
@@ -147,6 +154,9 @@ public class RandomResultSetTest extends AbstractMockServerTest {
           resultSet.getArray(++col);
           resultSet.getArray(++col);
           resultSet.getArray(++col);
+          if (dialect == Dialect.POSTGRESQL) {
+            resultSet.getArray(++col); // oid[]
+          }
 
           // GoogleSQL also includes proto columns.
           if (dialect == Dialect.GOOGLE_STANDARD_SQL) {