Repository: GoogleCloudPlatform/pgadapter
Pull request #3114 (2025-03-27 20:53:35)

deps: update dependency com.google.googlejavaformat:google-java-format to v1.26.0
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [com.google.googlejavaformat:google-java-format](https://redirect.github.com/google/google-java-format) | `1.7` -> `1.26.0` | [![age](https://developer.mend.io/api/mc/badges/age/maven/com.google.googlejavaformat:google-java-format/1.26.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/com.google.googlejavaformat:google-java-format/1.26.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/com.google.googlejavaformat:google-java-format/1.7/1.26.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/com.google.googlejavaformat:google-java-format/1.7/1.26.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>google/google-java-format (com.google.googlejavaformat:google-java-format)</summary>

### [`v1.26.0`](https://redirect.github.com/google/google-java-format/releases/tag/v1.26.0)

[Compare Source](https://redirect.github.com/google/google-java-format/compare/v1.25.2...v1.26.0)

Formatting changes:

-   Text blocks: don't automatically deindent long text blocks to start at column 0. For text blocks that are already deindented, the existing choice will be preserved, but it won't happen automatically.
-   Text blocks: for deindented text blocks, put the opening `"""` at column 0 instead of indenting it

Changes:

-   The published GraalVM native-image binaries now include a binary for Linux arm64

Full Changelog: https://github.com/google/google-java-format/compare/v1.25.2...v1.26.0

### [`v1.25.2`](https://redirect.github.com/google/google-java-format/releases/tag/v1.25.2)

[Compare Source](https://redirect.github.com/google/google-java-format/compare/v1.25.1...v1.25.2)

Changes:

-   Fix a crash formatting text blocks involving trailing whitespace before the close delimiter ([#&#8203;1205](https://redirect.github.com/google/google-java-format/issues/1205))

Full Changelog: https://github.com/google/google-java-format/compare/v1.25.1...v1.25.2

### [`v1.25.1`](https://redirect.github.com/google/google-java-format/releases/tag/v1.25.1)

[Compare Source](https://redirect.github.com/google/google-java-format/compare/v1.25.0...v1.25.1)

Changes:

-   Fix a crash in text block formatting ([#&#8203;1195](https://redirect.github.com/google/google-java-format/issues/1195))

Full Changelog: https://github.com/google/google-java-format/compare/v1.25.0...v1.25.1

### [`v1.25.0`](https://redirect.github.com/google/google-java-format/releases/tag/v1.25.0)

[Compare Source](https://redirect.github.com/google/google-java-format/compare/v1.24.0...v1.25.0)

The minimum support JDK version to run google-java-format is now JDK 17 ([#&#8203;1159](https://redirect.github.com/google/google-java-format/issues/1159)). Using google-java-format to format earlier versions of the language is still supported, but running the formatter itself on JDK 17 or newer is required.

Changes:

-   Various improvements to text block formatting
-   Improve formatting of `when` pattern guards

Full Changelog: https://github.com/google/google-java-format/compare/v1.24.0...v1.25.0

### [`v1.24.0`](https://redirect.github.com/google/google-java-format/releases/tag/v1.24.0)

[Compare Source](https://redirect.github.com/google/google-java-format/compare/v1.23.0...v1.24.0)

Changes:

-   Fix inconsistency in formatting of comments in switch statements ([https://github.com/google/google-java-format/issues/1127](https://redirect.github.com/google/google-java-format/issues/1127))
-   Fix different formatting of block line comments ([#&#8203;1153](https://redirect.github.com/google/google-java-format/issues/1153))
-   Print the problem line as context in error messages

Full Changelog: https://github.com/google/google-java-format/compare/v1.23.0...v1.24.0

### [`v1.23.0`](https://redirect.github.com/google/google-java-format/releases/tag/v1.23.0)

[Compare Source](https://redirect.github.com/google/google-java-format/compare/v1.22.0...v1.23.0)

Changes:

-   Adjust indentation of line comments inside expression switches ([#&#8203;876](https://redirect.github.com/google/google-java-format/issues/876))
-   Fix modifier order handling for `non-sealed` (https://github.com/google/google-java-format/commit/7fd9300499228717bcfee75ff4f836507df832ee)
-   Handle empty classes with no members that contain semi-colons (https://github.com/google/google-java-format/commit/b9b6730b80a16798da559f2d50112cec3d8538ad)
-   Support overlapping ranges in `--lines` (https://github.com/google/google-java-format/commit/c4b467d50bd6bb52935075b438f602ff902db167)
-   Remove support for the String Templates preview feature, see https://bugs.openjdk.org/browse/JDK-8329949 (https://github.com/google/google-java-format/commit/fdf4b29a6e1206f451bd96ed7967f4061921881a)
-   Improve compatibility with latest JDK early access builds (https://github.com/google/google-java-format/commit/0b384e32b39117a8da2829d8543e7474338ddebe)

Full Changelog: https://github.com/google/google-java-format/compare/v1.22.0...v1.23.0

### [`v1.22.0`](https://redirect.github.com/google/google-java-format/releases/tag/v1.22.0)

Changes:

-   Improve support for tokens that span multiple lines ([`9bdae02`](https://redirect.github.com/google/google-java-format/commit/9bdae025b7b023d45636e707c9225d0cdd66eb0b))
-   Fix an issue with text block formatting, when the text block is the receiver of a method call ([#&#8203;1081](https://redirect.github.com/google/google-java-format/issues/1081))
-   `google-java-format-diff.py` now parallelizes the calls to the formatter, for better performance ([`3ee6e2a`](https://redirect.github.com/google/google-java-format/commit/3ee6e2a34029bc5e68a5f733749e2732c2bf7940))

Full Changelog: https://github.com/google/google-java-format/compare/v1.21.0...v1.22.0

### [`v1.21.0`](https://redirect.github.com/google/google-java-format/releases/tag/v1.21.0)

Formatting changes:

-   Adjust indentation of text blocks ([`ce3cb59`](https://redirect.github.com/google/google-java-format/commit/ce3cb59a8d649359a8e6e7fcc5f2f21bb79b3df1))

Bug fixes:

-   Fix a crash with comments inside string templates ([`e946e82`](https://redirect.github.com/google/google-java-format/commit/e946e82801eb5bbd52bea00355ba20450bc0725c))
-   Native image `-version` reports `HEAD-SNAPSHOT` instead of the correct version ([#&#8203;1068](https://redirect.github.com/google/google-java-format/issues/1068))
-   Improve compatibility with older glibc versions ([#&#8203;1072](https://redirect.github.com/google/google-java-format/issues/1072))

Full Changelog: https://github.com/google/google-java-format/compare/v1.20.0...v1.21.0

### [`v1.20.0`](https://redirect.github.com/google/google-java-format/releases/tag/v1.20.0)

This release includes [GraalVM native-image](https://www.graalvm.org/22.0/reference-manual/native-image/) binaries for google-java-format for windows, linux, and mac. These binaries offer improved startup performance.

Changes:

-   Keep type-use annotation with type when wrapping ([`03efe44`](https://redirect.github.com/google/google-java-format/commit/03efe44d9affc989eee8623651fbdf1bcc7240dc))
-   Handle 'any' patterns ([#&#8203;1037](https://redirect.github.com/google/google-java-format/issues/1037))

Full Changelog: https://github.com/google/google-java-format/compare/v1.19.2...v1.20.0

### [`v1.19.2`](https://redirect.github.com/google/google-java-format/releases/tag/v1.19.2)

#### Changes

-   Improve support for string templates ([#&#8203;1010](https://redirect.github.com/google/google-java-format/issues/1010))
-   Handle `var` in record patterns ([#&#8203;1020](https://redirect.github.com/google/google-java-format/issues/1020))

**Full Changelog**: https://github.com/google/google-java-format/compare/v1.19.1...v1.19.2

### [`v1.19.1`](https://redirect.github.com/google/google-java-format/releases/tag/v1.19.1)

#### Changes

-   Fix support for Java 21 features by enabling JDK 21 for release builds ([#&#8203;1014](https://redirect.github.com/google/google-java-format/issues/1014)).

**Full Changelog**: https://github.com/google/google-java-format/compare/v1.19.0...v1.19.1

### [`v1.19.0`](https://redirect.github.com/google/google-java-format/releases/tag/v1.19.0)

#### Changes

This release adds initial support for more Java 21 features, including:

-   String templates ([#&#8203;981](https://redirect.github.com/google/google-java-format/issues/981))
-   Unnamed variables ([#&#8203;978](https://redirect.github.com/google/google-java-format/issues/978))
-   Pattern matching and guard clauses in switch expressions ([#&#8203;937](https://redirect.github.com/google/google-java-format/issues/937), [#&#8203;880](https://redirect.github.com/google/google-java-format/issues/880), [#&#8203;983](https://redirect.github.com/google/google-java-format/issues/983), [#&#8203;988](https://redirect.github.com/google/google-java-format/issues/988))

Other changes:

-   Handle type annotations on method reference qualifiers ([`53390d9`](https://redirect.github.com/google/google-java-format/commit/53390d99b56edae23cfab5adcafd7df28d9984c8))
-   Avoid reflowing text blocks ([#&#8203;976](https://redirect.github.com/google/google-java-format/issues/976))

**Full Changelog**: https://github.com/google/google-java-format/compare/v1.18.1...v1.19.0

### [`v1.18.1`](https://redirect.github.com/google/google-java-format/releases/tag/v1.18.1)

#### Changes

-   Fixed version number for Eclipse plugin ([#&#8203;744](https://redirect.github.com/google/google-java-format/issues/744))

**Full Changelog**: https://github.com/google/google-java-format/compare/v1.18.0...v1.18.1

### [`v1.18.0`](https://redirect.github.com/google/google-java-format/releases/tag/v1.18.0)

#### Changes

-   Update Guava version to resolve https://github.com/advisories/GHSA-7g45-4rm6-3mm3 ([#&#8203;950](https://redirect.github.com/google/google-java-format/issues/950))
-   Handle `final var` lambda variables ([#&#8203;959](https://redirect.github.com/google/google-java-format/issues/959))

**Full Changelog**: https://github.com/google/google-java-format/compare/v1.17.0...v1.18.0

### [`v1.17.0`](https://redirect.github.com/google/google-java-format/releases/tag/v1.17.0)

#### Changes

-   Fix compatibility with OpenJDK 21 early access builds ([#&#8203;898](https://redirect.github.com/google/google-java-format/issues/898))

**Full Changelog**: https://github.com/google/google-java-format/compare/v1.16.0...v1.17.0

### [`v1.16.0`](https://redirect.github.com/google/google-java-format/releases/tag/v1.16.0)

#### Changes

-   Format long exception lists one per line (https://github.com/google/google-java-format/commit/198fa4236724f0305f1d4fb9447ce0b48984746f)
-   Normalize parameter comments (https://github.com/google/google-java-format/commit/dda43216576c4cb84e2497424b9ca9246f2687e5)

#### Bug fixes

-   Return a non-zero exit code on error ([#&#8203;848](https://redirect.github.com/google/google-java-format/issues/848))
-   Formatter leaks threads and memory ([#&#8203;847](https://redirect.github.com/google/google-java-format/issues/847))

**Full Changelog**: https://github.com/google/google-java-format/compare/v1.15.0...v1.16.0

### [`v1.15.0`](https://redirect.github.com/google/google-java-format/releases/tag/v1.15.0)

#### What's Changed

-   Passing `--add-exports` flags on the command line is no longer necessary for JDK 17 and newer (https://github.com/google/google-java-format/commit/ee81afc93990493701a6f7a2801eff058ac57891)

**Full Changelog**: https://github.com/google/google-java-format/compare/v1.14.0...v1.15.0

### [`v1.14.0`](https://redirect.github.com/google/google-java-format/releases/tag/v1.14.0): 1.14.0

#### What's Changed

-   Handle modifiers that start with `non-` ([#&#8203;696](https://redirect.github.com/google/google-java-format/issues/696))
-   Treat single-character upper case identifiers as UpperCamelCase, to improve formatting of Android `R` classes ([`16e72a1`](https://redirect.github.com/google/google-java-format/commit/16e72a1a9bbf182fac6686807e54bc846a9543ed))
-   Don't format javadoc without a summary fragment as a single-line  ([`668f108`](https://redirect.github.com/google/google-java-format/commit/668f108de438db15158d33ed1a386bdbab3b4d09))

**Full Changelog**: https://github.com/google/google-java-format/compare/v1.13.0...v1.14.0

### [`v1.13.0`](https://redirect.github.com/google/google-java-format/releases/tag/v1.13.0): 1.13.0

#### What's Changed

-   Fix formatting of pattern matching in switch when running on Java 17 ([#&#8203;689](https://redirect.github.com/google/google-java-format/issues/689), [#&#8203;690](https://redirect.github.com/google/google-java-format/issues/690))

**Full Changelog**: https://github.com/google/google-java-format/compare/v1.12.0...v1.13.0

### [`v1.12.0`](https://redirect.github.com/google/google-java-format/releases/tag/v1.12.0): 1.12.0

#### What's Changed

-   Format type annotation as part of the type, not part of the modifiers list ([https://github.com/google/google-java-format/pull/653](https://redirect.github.com/google/google-java-format/pull/653))
-   Fix indentation of case statements on JDK 17 ([https://github.com/google/google-java-format/pull/654](https://redirect.github.com/google/google-java-format/pull/654))

**Full Changelog**: https://github.com/google/google-java-format/compare/v1.11.0...v1.12.0

### [`v1.11.0`](https://redirect.github.com/google/google-java-format/releases/tag/v1.11.0): 1.11.0

`google-java-format` now has improved support for running on JDK 17 early access builds.

Changes:

-   Handle `final` variables in `instanceof` patterns ([#&#8203;588](https://redirect.github.com/google/google-java-format/issues/588))
-   Fix handling of annotations in compact record constructors ([#&#8203;574](https://redirect.github.com/google/google-java-format/issues/574))
-   Fix a crash in `instanceof` pattern handling ([#&#8203;594](https://redirect.github.com/google/google-java-format/issues/594))
-   Wrap multiple values in switch expression case ([#&#8203;540](https://redirect.github.com/google/google-java-format/issues/540))
-   Fix formatting of module trees after [JDK-8255464](https://bugs.openjdk.java.net/browse/JDK-8255464)
-   Support `sealed` classes ([#&#8203;603](https://redirect.github.com/google/google-java-format/issues/603))

### [`v1.10.0`](https://redirect.github.com/google/google-java-format/releases/tag/v1.10.0): 1.10.0

`google-java-format` now supports running on JDK 16. The following flags are required when running on JDK 16, due to [JEP 396: Strongly Encapsulate JDK Internals by Default](https://openjdk.java.net/jeps/396):

    java \
      --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
      --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
      --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \
      --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
      --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \
      -jar google-java-format-1.10.0-all-deps.jar T...

Other changes:

-   Handle extra `;` in import lists (https://github.com/google/google-java-format/commit/b769e812a052d7cff4a2d86eff4981a5d358ee2d)
-   Add missing space between unary `-` and negative literals (https://github.com/google/google-java-format/commit/6da736d786ac71a134ed6cc43e9cd825c83de0fd)
-   Fix an off-by-one issue on the reflowing of string literals (https://github.com/google/google-java-format/commit/b9fd8d2242869ea7c9efd10cbbe7278c4b6611b1)

</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 was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/GoogleCloudPlatform/pgadapter).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMDcuMSIsInVwZGF0ZWRJblZlciI6IjM5LjIwNy4xIiwidGFyZ2V0QnJhbmNoIjoicG9zdGdyZXNxbC1kaWFsZWN0IiwibGFiZWxzIjpbXX0=-->



Patch:
diff --git a/benchmarks/latency-comparison/java/pom.xml b/benchmarks/latency-comparison/java/pom.xml
index 77e74b5e..b2893fb3 100644
--- a/benchmarks/latency-comparison/java/pom.xml
+++ b/benchmarks/latency-comparison/java/pom.xml
@@ -43,7 +43,7 @@
       <dependency>
         <groupId>com.google.cloud</groupId>
         <artifactId>libraries-bom</artifactId>
-        <version>26.57.0</version>
+        <version>26.58.0</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
diff --git a/benchmarks/tpcc/pom.xml b/benchmarks/tpcc/pom.xml
index b9374db9..5ebeb7c0 100644
--- a/benchmarks/tpcc/pom.xml
+++ b/benchmarks/tpcc/pom.xml
@@ -21,7 +21,7 @@
       <dependency>
         <groupId>com.google.cloud</groupId>
         <artifactId>libraries-bom</artifactId>
-        <version>26.57.0</version>
+        <version>26.58.0</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
diff --git a/pom.xml b/pom.xml
index 8ddc2aa6..644a5639 100644
--- a/pom.xml
+++ b/pom.xml
@@ -85,7 +85,7 @@
       <dependency>
         <groupId>com.google.cloud</groupId>
         <artifactId>libraries-bom</artifactId>
-        <version>26.57.0</version>
+        <version>26.58.0</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
@@ -383,6 +383,27 @@
         </plugins>
       </build>
     </profile>
+    <profile>
+      <id>format</id>
+      <activation>
+        <jdk>[11,)</jdk>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>com.coveo</groupId>
+            <artifactId>fmt-maven-plugin</artifactId>
+            <executions>
+              <execution>
+                <goals>
+                  <goal>format</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
   </profiles>
 
   <build>
@@ -409,17 +430,6 @@
         </configuration>
       </plugin>
 
-      <plugin>
-        <groupId>com.coveo</groupId>
-        <artifactId>fmt-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>format</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-plugin</artifactId>
diff --git a/samples/java/hibernate/pom.xml b/samples/java/hibernate/pom.xml
index b3d4af5c..a0874129 100644
--- a/samples/java/hibernate/pom.xml
+++ b/samples/java/hibernate/pom.xml
@@ -39,7 +39,7 @@
     <dependency>
       <groupId>org.hibernate.orm</groupId>
       <artifactId>hibernate-core</artifactId>
-      <version>6.6.11.Final</version>
+      <version>6.6.12.Final</version>
     </dependency>
     <!-- Postgresql JDBC driver dependency -->
     <dependency>
@@ -57,7 +57,7 @@
     <dependency>
       <groupId>io.hypersistence</groupId>
       <artifactId>hypersistence-utils-hibernate-63</artifactId>
-      <version>3.9.5</version>
+      <version>3.9.8</version>
     </dependency>
     <!-- Add testcontainers, so we can run a Docker container with PGAdapter+Spanner Emulator -->
     <dependency>
diff --git a/samples/java/spring-data-jpa/pom.xml b/samples/java/spring-data-jpa/pom.xml
index 0e055e40..355a3364 100644
--- a/samples/java/spring-data-jpa/pom.xml
+++ b/samples/java/spring-data-jpa/pom.xml
@@ -67,7 +67,7 @@
     <dependency>
       <groupId>io.hypersistence</groupId>
       <artifactId>hypersistence-utils-hibernate-63</artifactId>
-      <version>3.9.5</version>
+      <version>3.9.8</version>
     </dependency>
     <dependency>
       <groupId>org.springframework.boot</groupId>
diff --git a/samples/python/sqlalchemy2-sample/requirements.txt b/samples/python/sqlalchemy2-sample/requirements.txt
index ac519327..5dba3bf9 100644
--- a/samples/python/sqlalchemy2-sample/requirements.txt
+++ b/samples/python/sqlalchemy2-sample/requirements.txt
@@ -1,6 +1,6 @@
 psycopg[binary]==3.2.6
 pytz==2025.2
-sqlalchemy==2.0.39
+sqlalchemy==2.0.40
 google~=3.0.0
 google.auth~=2.38.0
 testcontainers~=4.9.0
diff --git a/samples/snippets/java-snippets/pom.xml b/samples/snippets/java-snippets/pom.xml
index 8d57fd23..3b3f11c8 100644
--- a/samples/snippets/java-snippets/pom.xml
+++ b/samples/snippets/java-snippets/pom.xml
@@ -54,6 +54,41 @@
       <scope>test</scope>
     </dependency>
   </dependencies>
+  <profiles>
+    <profile>
+      <id>format</id>
+      <activation>
+        <jdk>[17,)</jdk>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>com.spotify.fmt</groupId>
+            <artifactId>fmt-maven-plugin</artifactId>
+            <version>2.25</version>
+            <executions>
+              <execution>
+                <goals>
+                  <goal>format</goal>
+                </goals>
+              </execution>
+            </executions>
+            <configuration>
+              <style>google</style>
+              <verbose>true</verbose>
+            </configuration>
+            <dependencies>
+              <dependency>
+                <groupId>com.google.googlejavaformat</groupId>
+                <artifactId>google-java-format</artifactId>
+                <version>1.26.0</version>
+              </dependency>
+            </dependencies>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
   <build>
     <plugins>
       <plugin>
@@ -120,29 +155,6 @@
           <cleanupDaemonThreads>false</cleanupDaemonThreads>
         </configuration>
       </plugin>
-      <plugin>
-        <groupId>com.coveo</groupId>
-        <artifactId>fmt-maven-plugin</artifactId>
-        <version>2.9</version>
-        <executions>
-          <execution>
-            <goals>
-              <goal>format</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <style>google</style>
-          <verbose>true</verbose>
-        </configuration>
-        <dependencies>
-          <dependency>
-            <groupId>com.google.googlejavaformat</groupId>
-            <artifactId>google-java-format</artifactId>
-            <version>1.7</version>
-          </dependency>
-        </dependencies>
-      </plugin>
     </plugins>
   </build>
 </project>
diff --git a/samples/snippets/java-snippets/src/main/java/com/google/example/WriteDataWithDml.java b/samples/snippets/java-snippets/src/main/java/com/google/example/WriteDataWithDml.java
index ebfb0968..4e773eb4 100644
--- a/samples/snippets/java-snippets/src/main/java/com/google/example/WriteDataWithDml.java
+++ b/samples/snippets/java-snippets/src/main/java/com/google/example/WriteDataWithDml.java
@@ -50,10 +50,10 @@ class WriteDataWithDml {
 
         final List<Singer> singers =
             Arrays.asList(
-                new Singer(/* SingerId = */ 12L, "Melissa", "Garcia"),
-                new Singer(/* SingerId = */ 13L, "Russel", "Morales"),
-                new Singer(/* SingerId = */ 14L, "Jacqueline", "Long"),
-                new Singer(/* SingerId = */ 15L, "Dylan", "Shaw"));
+                new Singer(/* SingerId= */ 12L, "Melissa", "Garcia"),
+                new Singer(/* SingerId= */ 13L, "Russel", "Morales"),
+                new Singer(/* SingerId= */ 14L, "Jacqueline", "Long"),
+                new Singer(/* SingerId= */ 15L, "Dylan", "Shaw"));
 
         // Note that JDBC parameters start at index 1.
         int paramIndex = 0;
diff --git a/samples/snippets/java-snippets/src/main/java/com/google/example/WriteDataWithDmlBatch.java b/samples/snippets/java-snippets/src/main/java/com/google/example/WriteDataWithDmlBatch.java
index d6932c39..f6651530 100644
--- a/samples/snippets/java-snippets/src/main/java/com/google/example/WriteDataWithDmlBatch.java
+++ b/samples/snippets/java-snippets/src/main/java/com/google/example/WriteDataWithDmlBatch.java
@@ -45,9 +45,9 @@ class WriteDataWithDmlBatch {
               "INSERT INTO singers (singer_id, first_name, last_name) VALUES (?, ?, ?)")) {
         final List<Singer> singers =
             Arrays.asList(
-                new Singer(/* SingerId = */ 16L, "Sarah", "Wilson"),
-                new Singer(/* SingerId = */ 17L, "Ethan", "Miller"),
-                new Singer(/* SingerId = */ 18L, "Maya", "Patel"));
+                new Singer(/* SingerId= */ 16L, "Sarah", "Wilson"),
+                new Singer(/* SingerId= */ 17L, "Ethan", "Miller"),
+                new Singer(/* SingerId= */ 18L, "Maya", "Patel"));
 
         for (Singer singer : singers) {
           // Note that JDBC parameters start at index 1.
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/ConnectionHandler.java b/src/main/java/com/google/cloud/spanner/pgadapter/ConnectionHandler.java
index 96e3384f..a7000b1b 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/ConnectionHandler.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/ConnectionHandler.java
@@ -609,7 +609,8 @@ public class ConnectionHandler implements Runnable {
       new ErrorResponse(this, exception).send();
     } else {
       new ErrorResponse(this, exception).send();
-      new ReadyResponse(output, ReadyResponse.Status.IDLE).send();
+      ReadyResponse.sendIdleResponse(output);
+      output.flush();
     }
   }
 
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/parsers/BinaryParser.java b/src/main/java/com/google/cloud/spanner/pgadapter/parsers/BinaryParser.java
index e642e8aa..085319b4 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/parsers/BinaryParser.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/parsers/BinaryParser.java
@@ -16,6 +16,7 @@ package com.google.cloud.spanner.pgadapter.parsers;
 
 import com.google.api.core.InternalApi;
 import com.google.cloud.ByteArray;
+import com.google.cloud.spanner.ProtobufResultSet;
 import com.google.cloud.spanner.ResultSet;
 import com.google.cloud.spanner.SpannerExceptionFactory;
 import com.google.cloud.spanner.Statement;
@@ -108,7 +109,7 @@ public class BinaryParser extends Parser<ByteArray> {
       DataFormat format) {
     int bufferSize = sessionState.getBinaryConversionBufferSize();
     try {
-      String base64 = resultSet.getValue(position).getAsString();
+      String base64 = getBase64(resultSet, position);
       switch (format) {
         case SPANNER:
         case POSTGRESQL_BINARY:
@@ -128,7 +129,7 @@ public class BinaryParser extends Parser<ByteArray> {
           }
           return null;
         case POSTGRESQL_TEXT:
-          return bytesToHex(resultSet.getBytes(position).toByteArray());
+          return bytesToHex(Base64.getDecoder().decode(base64));
         default:
           throw new IllegalArgumentException("unknown data format: " + format);
       }
@@ -137,6 +138,14 @@ public class BinaryParser extends Parser<ByteArray> {
     }
   }
 
+  static String getBase64(ResultSet resultSet, int column) {
+    if (resultSet instanceof ProtobufResultSet
+        && ((ProtobufResultSet) resultSet).canGetProtobufValue(column)) {
+      return ((ProtobufResultSet) resultSet).getProtobufValue(column).getStringValue();
+    }
+    return resultSet.getValue(column).getAsString();
+  }
+
   static int copy(int length, InputStream from, DataOutputStream to, int bufferSize)
       throws IOException {
     byte[] buf = new byte[Math.min(length, bufferSize)];
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/parsers/DateParser.java b/src/main/java/com/google/cloud/spanner/pgadapter/parsers/DateParser.java
index 71bd8b30..b8d8b4a5 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/parsers/DateParser.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/parsers/DateParser.java
@@ -17,12 +17,15 @@ package com.google.cloud.spanner.pgadapter.parsers;
 import com.google.api.core.InternalApi;
 import com.google.cloud.Date;
 import com.google.cloud.spanner.ErrorCode;
+import com.google.cloud.spanner.ProtobufResultSet;
 import com.google.cloud.spanner.ResultSet;
 import com.google.cloud.spanner.SpannerExceptionFactory;
 import com.google.cloud.spanner.Statement;
 import com.google.cloud.spanner.pgadapter.ProxyServer.DataFormat;
 import com.google.cloud.spanner.pgadapter.error.PGExceptionFactory;
-import java.nio.charset.StandardCharsets;
+import com.google.cloud.spanner.pgadapter.session.SessionState;
+import java.io.DataOutputStream;
+import java.io.IOException;
 import java.time.LocalDate;
 import javax.annotation.Nonnull;
 import org.postgresql.util.ByteConverter;
@@ -118,18 +121,47 @@ public class DateParser extends Parser<Date> {
     return IntegerParser.binaryParse(daysAsInt);
   }
 
-  public static byte[] convertToPG(ResultSet resultSet, int position, DataFormat format) {
+  public static byte[] convertToPG(
+      SessionState sessionState,
+      DataOutputStream outputStream,
+      ResultSet resultSet,
+      int position,
+      DataFormat format)
+      throws IOException {
+    writeToPG(sessionState, outputStream, resultSet, position, format);
+    return null;
+  }
+
+  static void writeToPG(
+      SessionState sessionState,
+      DataOutputStream outputStream,
+      ResultSet resultSet,
+      int position,
+      DataFormat format)
+      throws IOException {
     switch (format) {
       case SPANNER:
       case POSTGRESQL_TEXT:
-        return toString(resultSet.getDate(position)).getBytes(StandardCharsets.UTF_8);
+        StringParser.writeToPG(sessionState, outputStream, getDateAsString(resultSet, position));
+        break;
       case POSTGRESQL_BINARY:
-        return convertToPG(resultSet.getDate(position));
+        byte[] value = convertToPG(resultSet.getDate(position));
+        outputStream.writeInt(value.length);
+        outputStream.write(value);
+        break;
       default:
         throw new IllegalArgumentException("unknown data format: " + format);
     }
   }
 
+  static String getDateAsString(ResultSet resultSet, int column) {
+    if (resultSet instanceof ProtobufResultSet
+        && ((ProtobufResultSet) resultSet).canGetProtobufValue(column)) {
+      return ((ProtobufResultSet) resultSet).getProtobufValue(column).getStringValue();
+    }
+    return toString(resultSet.getDate(column));
+  }
+
   /**
    * Dates are stored as long, but technically cannot be longer than int. Here we ensure that is the
    * case.
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/parsers/JsonbParser.java b/src/main/java/com/google/cloud/spanner/pgadapter/parsers/JsonbParser.java
index f6e6e913..8fed8bc1 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/parsers/JsonbParser.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/parsers/JsonbParser.java
@@ -15,6 +15,7 @@
 package com.google.cloud.spanner.pgadapter.parsers;
 
 import com.google.api.core.InternalApi;
+import com.google.cloud.spanner.ProtobufResultSet;
 import com.google.cloud.spanner.ResultSet;
 import com.google.cloud.spanner.Statement;
 import com.google.cloud.spanner.Value;
@@ -34,7 +35,7 @@ public class JsonbParser extends Parser<String> {
   private static final byte[] BINARY_HEADER = new byte[] {1};
 
   JsonbParser(ResultSet item, int position) {
-    this.item = item.getPgJsonb(position);
+    this.item = getJsonb(item, position);
   }
 
   JsonbParser(Object item) {
@@ -103,17 +104,28 @@ public class JsonbParser extends Parser<String> {
     switch (format) {
       case SPANNER:
       case POSTGRESQL_TEXT:
-        StringParser.writeToPG(sessionState, dataOutputStream, resultSet.getPgJsonb(position));
+        StringParser.writeToPG(sessionState, dataOutputStream, getJsonb(resultSet, position));
         return null;
       case POSTGRESQL_BINARY:
         StringParser.writeToPG(
-            sessionState, dataOutputStream, resultSet.getPgJsonb(position), BINARY_HEADER);
+            sessionState, dataOutputStream, getJsonb(resultSet, position), BINARY_HEADER);
         return null;
       default:
         throw new IllegalArgumentException("unknown data format: " + format);
     }
   }
 
+  /** Get the string from the result as efficiently as possible. */
+  static String getJsonb(ResultSet resultSet, int column) {
+    // If the result set is a ProtobufResultSet and the protobuf value is still present, then get
+    // the string directly from that.
+    if (resultSet instanceof ProtobufResultSet
+        && ((ProtobufResultSet) resultSet).canGetProtobufValue(column)) {
+      return ((ProtobufResultSet) resultSet).getProtobufValue(column).getStringValue();
+    }
+    return resultSet.getPgJsonb(column);
+  }
+
   @Override
   public void bind(Statement.Builder statementBuilder, String name) {
     statementBuilder.bind(name).to(Value.pgJsonb(this.item));
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/parsers/LongParser.java b/src/main/java/com/google/cloud/spanner/pgadapter/parsers/LongParser.java
index 45bcfe02..0d890c05 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/parsers/LongParser.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/parsers/LongParser.java
@@ -16,14 +16,17 @@ package com.google.cloud.spanner.pgadapter.parsers;
 
 import com.google.api.core.InternalApi;
 import com.google.cloud.spanner.ErrorCode;
+import com.google.cloud.spanner.ProtobufResultSet;
 import com.google.cloud.spanner.ResultSet;
 import com.google.cloud.spanner.SpannerExceptionFactory;
 import com.google.cloud.spanner.Statement;
 import com.google.cloud.spanner.pgadapter.ProxyServer.DataFormat;
 import com.google.cloud.spanner.pgadapter.error.PGExceptionFactory;
+import com.google.cloud.spanner.pgadapter.session.SessionState;
+import java.io.DataOutputStream;
+import java.io.IOException;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-import java.nio.charset.StandardCharsets;
 import javax.annotation.Nonnull;
 import org.postgresql.util.ByteConverter;
 
@@ -95,18 +98,47 @@ public class LongParser extends Parser<Long> {
     return result;
   }
 
-  public static byte[] convertToPG(ResultSet resultSet, int position, DataFormat format) {
+  public static byte[] convertToPG(
+      SessionState sessionState,
+      DataOutputStream outputStream,
+      ResultSet resultSet,
+      int position,
+      DataFormat format)
+      throws IOException {
+    writeToPG(sessionState, outputStream, resultSet, position, format);
+    return null;
+  }
+
+  static void writeToPG(
+      SessionState sessionState,
+      DataOutputStream outputStream,
+      ResultSet resultSet,
+      int position,
+      DataFormat format)
+      throws IOException {
     switch (format) {
       case SPANNER:
       case POSTGRESQL_TEXT:
-        return Long.toString(resultSet.getLong(position)).getBytes(StandardCharsets.UTF_8);
+        StringParser.writeToPG(sessionState, outputStream, getLongAsString(resultSet, position));
+        break;
       case POSTGRESQL_BINARY:
-        return convertToPG(resultSet.getLong(position));
+        byte[] value = convertToPG(resultSet.getLong(position));
+        outputStream.writeInt(value.length);
+        outputStream.write(value);
+        break;
       default:
         throw new IllegalArgumentException("unknown data format: " + format);
     }
   }
 
+  static String getLongAsString(ResultSet resultSet, int column) {
+    if (resultSet instanceof ProtobufResultSet
+        && ((ProtobufResultSet) resultSet).canGetProtobufValue(column)) {
+      return ((ProtobufResultSet) resultSet).getProtobufValue(column).getStringValue();
+    }
+    return Long.toString(resultSet.getLong(column));
+  }
+
   @Override
   public void bind(Statement.Builder statementBuilder, String name) {
     statementBuilder.bind(name).to(this.item);
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/parsers/StringParser.java b/src/main/java/com/google/cloud/spanner/pgadapter/parsers/StringParser.java
index eb918ccd..bdd729c8 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/parsers/StringParser.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/parsers/StringParser.java
@@ -15,6 +15,7 @@
 package com.google.cloud.spanner.pgadapter.parsers;
 
 import com.google.api.core.InternalApi;
+import com.google.cloud.spanner.ProtobufResultSet;
 import com.google.cloud.spanner.ResultSet;
 import com.google.cloud.spanner.SpannerExceptionFactory;
 import com.google.cloud.spanner.Statement;
@@ -32,14 +33,14 @@ public class StringParser extends Parser<String> {
   private static final byte[] HEADER = new byte[0];
 
   StringParser(ResultSet item, int position) {
-    this.item = item.getString(position);
+    this.item = getString(item, position);
   }
 
   StringParser(Object item) {
     this.item = (String) item;
   }
 
-  StringParser(byte[] item, FormatCode formatCode) {
+  StringParser(byte[] item, FormatCode ignore) {
     if (item != null) {
       this.item = toString(item);
     }
@@ -60,12 +61,24 @@ public class StringParser extends Parser<String> {
     return this.item == null ? null : this.item.getBytes(StandardCharsets.UTF_8);
   }
 
+  /** Get the string from the result as efficiently as possible. */
+  static String getString(ResultSet resultSet, int column) {
+    // If the result set is a ProtobufResultSet and the protobuf value is still present, then get
+    // the string directly from that.
+    if (resultSet instanceof ProtobufResultSet
+        && ((ProtobufResultSet) resultSet).canGetProtobufValue(column)) {
+      return ((ProtobufResultSet) resultSet).getProtobufValue(column).getStringValue();
+    } else {
+      return resultSet.getString(column);
+    }
+  }
+
   public static byte[] convertToPG(
       SessionState sessionState,
       DataOutputStream dataOutputStream,
       ResultSet resultSet,
       int position) {
-    writeToPG(sessionState, dataOutputStream, resultSet.getString(position));
+    writeToPG(sessionState, dataOutputStream, getString(resultSet, position));
     return null;
   }
 
@@ -77,13 +90,25 @@ public class StringParser extends Parser<String> {
   static void writeToPG(
       SessionState sessionState, DataOutputStream dataOutputStream, String value, byte[] header) {
     int bufferSize = sessionState.getStringConversionBufferSize();
-    int length = value.length();
+    // Skip getting the length if we don't need it.
+    int length = bufferSize <= 0 ? 0 : value.length();
     try {
       if (bufferSize <= 0 || length < bufferSize) {
-        byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
-        dataOutputStream.writeInt(bytes.length + header.length);
-        dataOutputStream.write(header);
-        dataOutputStream.write(bytes);
+        // Just use the writeUTF method of DataOutputStream if there is no header that needs to be
+        // written.
+        if (header.length == 0) {
+          // PG expects the length be 4 bytes.
+          // writeUTF writes the length as 2 bytes.
+          // So in order to get the correct length written to the stream, we first write 2 bytes
+          // containing all zeros.
+          dataOutputStream.writeShort(0);
+          dataOutputStream.writeUTF(value);
+        } else {
+          byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
+          dataOutputStream.writeInt(bytes.length + header.length);
+          dataOutputStream.write(header);
+          dataOutputStream.write(bytes);
+        }
       } else {
         try (OutputStreamWriter writer =
             new OutputStreamWriter(dataOutputStream, StandardCharsets.UTF_8)) {
@@ -101,12 +126,6 @@ public class StringParser extends Parser<String> {
     }
   }
 
-  public static byte[] binaryParse(ResultSet resultSet, int position) {
-    return resultSet.isNull(position)
-        ? null
-        : resultSet.getString(position).getBytes(StandardCharsets.UTF_8);
-  }
-
   @Override
   public void bind(Statement.Builder statementBuilder, String name) {
     statementBuilder.bind(name).to(this.item);
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/session/SessionState.java b/src/main/java/com/google/cloud/spanner/pgadapter/session/SessionState.java
index 7349e4e2..297d5ed5 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/session/SessionState.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/session/SessionState.java
@@ -43,6 +43,8 @@ import java.util.Map.Entry;
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import javax.annotation.Nullable;
 
@@ -113,6 +115,39 @@ public class SessionState {
     initCopySettings(this.settings);
   }
 
+  /**
+   * These fields contain cached values for settings that are used often and/or expensive to
+   * calculate.
+   */
+  private final AtomicReference<RemoveEscapeClauseEnum> cachedRemoveEscapeClause =
+      new AtomicReference<>();
+
+  private final AtomicReference<ZoneId> cachedZoneId = new AtomicReference<>();
+  private final AtomicReference<Boolean> cachedReplaceForUpdateClause = new AtomicReference<>();
+  private final AtomicReference<Boolean> cachedReplacePgCatalogTables = new AtomicReference<>();
+  private final AtomicReference<Boolean> cachedEmulatePgClassTables = new AtomicReference<>();
+  private final AtomicReference<Integer> cachedBinaryConversionBufferSize = new AtomicReference<>();
+  private final AtomicReference<Integer> cachedStringConversionBufferSize = new AtomicReference<>();
+
+  private void invalidateCache() {
+    cachedRemoveEscapeClause.set(null);
+    cachedZoneId.set(null);
+    cachedReplaceForUpdateClause.set(null);
+    cachedReplacePgCatalogTables.set(null);
+    cachedEmulatePgClassTables.set(null);
+    cachedBinaryConversionBufferSize.set(null);
+    cachedStringConversionBufferSize.set(null);
+  }
+
+  private <T> T getCachedValue(Supplier<T> supplier, AtomicReference<T> cachedValue) {
+    if (cachedValue.get() != null) {
+      return cachedValue.get();
+    }
+    T value = supplier.get();
+    cachedValue.set(value);
+    return value;
+  }
+
   @VisibleForTesting
   Map<String, PGSetting> getSettings() {
     return this.settings;
@@ -242,7 +277,7 @@ public class SessionState {
 
   private void internalSet(
       String extension, String name, String setting, Map<String, PGSetting> currentSettings) {
-    clearCachedValues();
+    invalidateCache();
     String key = toKey(extension, name);
     PGSetting newSetting = currentSettings.get(key);
     if (newSetting == null) {
@@ -264,10 +299,6 @@ public class SessionState {
     currentSettings.put(key, newSetting);
   }
 
-  private void clearCachedValues() {
-    cachedZoneId = null;
-  }
-
   /** Returns the current value of the specified setting. */
   public PGSetting get(String extension, String name) {
     return internalGet(toKey(extension, name), true);
@@ -459,20 +490,25 @@ public class SessionState {
    */
   // TODO: Remove in the next major version update.
   public boolean isReplaceForUpdateClause() {
-    return getBoolSetting("spanner", "replace_for_update", false);
+    return getCachedValue(
+        () -> getBoolSetting("spanner", "replace_for_update", false), cachedReplaceForUpdateClause);
   }
 
   /** Returns whether LIKE ... ESCAPE clauses are removed. */
   public RemoveEscapeClauseEnum getRemoveEscapeClause() {
-    PGSetting setting = internalGet(toKey("spanner", "remove_escape_clause"), false);
-    if (setting == null) {
-      return RemoveEscapeClauseEnum.DEFAULT;
-    }
-    return tryGetFirstNonNull(
-        RemoveEscapeClauseEnum.DEFAULT,
-        () -> RemoveEscapeClauseEnum.valueOf(upper(setting.getSetting())),
-        () -> RemoveEscapeClauseEnum.valueOf(upper(setting.getResetVal())),
-        () -> RemoveEscapeClauseEnum.valueOf(upper(setting.getBootVal())));
+    return getCachedValue(
+        () -> {
+          PGSetting setting = internalGet(toKey("spanner", "remove_escape_clause"), false);
+          if (setting == null) {
+            return RemoveEscapeClauseEnum.DEFAULT;
+          }
+          return tryGetFirstNonNull(
+              RemoveEscapeClauseEnum.DEFAULT,
+              () -> RemoveEscapeClauseEnum.valueOf(upper(setting.getSetting())),
+              () -> RemoveEscapeClauseEnum.valueOf(upper(setting.getResetVal())),
+              () -> RemoveEscapeClauseEnum.valueOf(upper(setting.getBootVal())));
+        },
+        cachedRemoveEscapeClause);
   }
 
   private static String upper(String s) {
@@ -481,15 +517,19 @@ public class SessionState {
 
   /** Returns the current setting for replacing pg_catalog tables with common table expressions. */
   public boolean isReplacePgCatalogTables() {
-    PGSetting setting = internalGet(toKey("spanner", "replace_pg_catalog_tables"), false);
-    if (setting == null) {
-      return true;
-    }
-    return tryGetFirstNonNull(
-        true,
-        () -> BooleanParser.toBoolean(setting.getSetting()),
-        () -> BooleanParser.toBoolean(setting.getResetVal()),
-        () -> BooleanParser.toBoolean(setting.getBootVal()));
+    return getCachedValue(
+        () -> {
+          PGSetting setting = internalGet(toKey("spanner", "replace_pg_catalog_tables"), false);
+          if (setting == null) {
+            return true;
+          }
+          return tryGetFirstNonNull(
+              true,
+              () -> BooleanParser.toBoolean(setting.getSetting()),
+              () -> BooleanParser.toBoolean(setting.getResetVal()),
+              () -> BooleanParser.toBoolean(setting.getBootVal()));
+        },
+        cachedReplacePgCatalogTables);
   }
 
   /**
@@ -497,15 +537,19 @@ public class SessionState {
    * use the object name as OID.
    */
   public boolean isEmulatePgClassTables() {
-    PGSetting setting = internalGet(toKey("spanner", "emulate_pg_class_tables"), false);
-    if (setting == null) {
-      return false;
-    }
-    return tryGetFirstNonNull(
-        true,
-        () -> BooleanParser.toBoolean(setting.getSetting()),
-        () -> BooleanParser.toBoolean(setting.getResetVal()),
-        () -> BooleanParser.toBoolean(setting.getBootVal()));
+    return getCachedValue(
+        () -> {
+          PGSetting setting = internalGet(toKey("spanner", "emulate_pg_class_tables"), false);
+          if (setting == null) {
+            return false;
+          }
+          return tryGetFirstNonNull(
+              true,
+              () -> BooleanParser.toBoolean(setting.getSetting()),
+              () -> BooleanParser.toBoolean(setting.getResetVal()),
+              () -> BooleanParser.toBoolean(setting.getBootVal()));
+        },
+        cachedEmulatePgClassTables);
   }
 
   /** Returns the {@link DdlTransactionMode} that is used for this connection at this time. */
@@ -539,7 +583,11 @@ public class SessionState {
    * the PostgreSQL wire-format. Zero means no buffer and instead convert it directly in all cases.
    */
   public int getBinaryConversionBufferSize() {
-    return getIntegerSetting("spanner", "binary_conversion_buffer_size", 0);
+    return getCachedValue(
+        () -> {
+          return getIntegerSetting("spanner", "binary_conversion_buffer_size", 0);
+        },
+        cachedBinaryConversionBufferSize);
   }
 
   /**
@@ -547,7 +595,9 @@ public class SessionState {
    * means no buffer and instead convert it directly in all cases.
    */
   public int getStringConversionBufferSize() {
-    return getIntegerSetting("spanner", "string_conversion_buffer_size", 0);
+    return getCachedValue(
+        () -> getIntegerSetting("spanner", "string_conversion_buffer_size", 0),
+        cachedStringConversionBufferSize);
   }
 
   /**
@@ -570,25 +620,23 @@ public class SessionState {
     return getIntegerSetting("spanner", "dml_batch_update_count", 0);
   }
 
-  private ZoneId cachedZoneId;
-
   /** Returns the {@link ZoneId} of the current timezone for this session. */
   public ZoneId getTimezone() {
-    if (cachedZoneId != null) {
-      return cachedZoneId;
-    }
-    PGSetting setting = internalGet(toKey(null, "timezone"), false);
-    if (setting == null) {
-      return ZoneId.systemDefault();
-    }
-    String id =
-        tryGetFirstNonNull(
-            ZoneId.systemDefault().getId(),
-            setting::getSetting,
-            setting::getResetVal,
-            setting::getBootVal);
-
-    return (cachedZoneId = zoneIdFromString(id));
+    return getCachedValue(
+        () -> {
+          PGSetting setting = internalGet(toKey(null, "timezone"), false);
+          if (setting == null) {
+            return ZoneId.systemDefault();
+          }
+          String id =
+              tryGetFirstNonNull(
+                  ZoneId.systemDefault().getId(),
+                  setting::getSetting,
+                  setting::getResetVal,
+                  setting::getBootVal);
+          return zoneIdFromString(id);
+        },
+        cachedZoneId);
   }
 
   private ZoneId zoneIdFromString(String value) {
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/AbstractFetchOrMoveStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/AbstractFetchOrMoveStatement.java
index cb1a4005..867e160c 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/AbstractFetchOrMoveStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/AbstractFetchOrMoveStatement.java
@@ -25,7 +25,6 @@ import com.google.cloud.spanner.pgadapter.statements.SimpleParser.TableOrIndexNa
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.Futures;
 import java.util.Arrays;
-import java.util.List;
 import java.util.concurrent.Future;
 
 abstract class AbstractFetchOrMoveStatement extends IntermediatePortalStatement {
@@ -129,8 +128,8 @@ abstract class AbstractFetchOrMoveStatement extends IntermediatePortalStatement
       String name,
       IntermediatePreparedStatement preparedStatement,
       byte[][] parameters,
-      List<Short> parameterFormatCodes,
-      List<Short> resultFormatCodes,
+      short[] parameterFormatCodes,
+      short[] resultFormatCodes,
       ParsedFetchOrMoveStatement fetchOrMoveStatement) {
     super(name, preparedStatement, parameters, parameterFormatCodes, resultFormatCodes);
     this.fetchOrMoveStatement = fetchOrMoveStatement;
@@ -186,10 +185,7 @@ abstract class AbstractFetchOrMoveStatement extends IntermediatePortalStatement
 
   @Override
   public IntermediatePortalStatement createPortal(
-      String name,
-      byte[][] parameters,
-      List<Short> parameterFormatCodes,
-      List<Short> resultFormatCodes) {
+      String name, byte[][] parameters, short[] parameterFormatCodes, short[] resultFormatCodes) {
     // FETCH and MOVE do not support binding any parameters, so we just return the same statement.
     return this;
   }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/CloseStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/CloseStatement.java
index 19c0b8dd..6ae537ba 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/CloseStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/CloseStatement.java
@@ -26,9 +26,7 @@ import com.google.cloud.spanner.pgadapter.metadata.OptionsMetadata;
 import com.google.cloud.spanner.pgadapter.statements.BackendConnection.NoResult;
 import com.google.cloud.spanner.pgadapter.statements.SimpleParser.TableOrIndexName;
 import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.Futures;
-import java.util.List;
 import java.util.concurrent.Future;
 
 public class CloseStatement extends IntermediatePortalStatement {
@@ -58,8 +56,8 @@ public class CloseStatement extends IntermediatePortalStatement {
             parsedStatement,
             originalStatement),
         NO_PARAMS,
-        ImmutableList.of(),
-        ImmutableList.of());
+        NO_FORMAT_CODES,
+        NO_FORMAT_CODES);
     this.closeStatement = parse(originalStatement.getSql());
   }
 
@@ -98,10 +96,7 @@ public class CloseStatement extends IntermediatePortalStatement {
 
   @Override
   public IntermediatePortalStatement createPortal(
-      String name,
-      byte[][] parameters,
-      List<Short> parameterFormatCodes,
-      List<Short> resultFormatCodes) {
+      String name, byte[][] parameters, short[] parameterFormatCodes, short[] resultFormatCodes) {
     // CLOSE does not support binding any parameters, so we just return the same statement.
     return this;
   }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/CopyStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/CopyStatement.java
index 453e994f..adf4532a 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/CopyStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/CopyStatement.java
@@ -129,8 +129,8 @@ public class CopyStatement extends IntermediatePortalStatement {
             parsedStatement,
             originalStatement),
         NO_PARAMS,
-        ImmutableList.of(),
-        ImmutableList.of());
+        NO_FORMAT_CODES,
+        NO_FORMAT_CODES);
     this.parsedCopyStatement = parsedCopyStatement;
   }
 
@@ -404,10 +404,7 @@ public class CopyStatement extends IntermediatePortalStatement {
 
   @Override
   public IntermediatePortalStatement createPortal(
-      String name,
-      byte[][] parameters,
-      List<Short> parameterFormatCodes,
-      List<Short> resultFormatCodes) {
+      String name, byte[][] parameters, short[] parameterFormatCodes, short[] resultFormatCodes) {
     // COPY does not support binding any parameters, so we just return the same statement.
     return this;
   }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/CopyToStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/CopyToStatement.java
index de2c852e..e63dc4da 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/CopyToStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/CopyToStatement.java
@@ -37,9 +37,7 @@ import com.google.cloud.spanner.pgadapter.wireoutput.CopyDoneResponse;
 import com.google.cloud.spanner.pgadapter.wireoutput.CopyOutResponse;
 import com.google.cloud.spanner.pgadapter.wireoutput.WireOutput;
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.Futures;
-import java.util.List;
 import java.util.concurrent.Future;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.stream.Collectors;
@@ -75,8 +73,8 @@ public class CopyToStatement extends IntermediatePortalStatement {
             createParsedStatement(parsedCopyStatement),
             createSelectStatement(parsedCopyStatement)),
         NO_PARAMS,
-        ImmutableList.of(),
-        ImmutableList.of());
+        NO_FORMAT_CODES,
+        NO_FORMAT_CODES);
     this.parsedCopyStatement = parsedCopyStatement;
     if (parsedCopyStatement.format == CopyStatement.Format.BINARY) {
       this.csvFormat = null;
@@ -215,10 +213,7 @@ public class CopyToStatement extends IntermediatePortalStatement {
 
   @Override
   public IntermediatePortalStatement createPortal(
-      String name,
-      byte[][] parameters,
-      List<Short> parameterFormatCodes,
-      List<Short> resultFormatCodes) {
+      String name, byte[][] parameters, short[] parameterFormatCodes, short[] resultFormatCodes) {
     // COPY does not support binding any parameters, so we just return the same statement.
     return this;
   }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/DeclareStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/DeclareStatement.java
index 32d4a1f3..127a55cf 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/DeclareStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/DeclareStatement.java
@@ -35,9 +35,7 @@ import com.google.cloud.spanner.pgadapter.wireprotocol.BindMessage;
 import com.google.cloud.spanner.pgadapter.wireprotocol.ControlMessage.ManuallyCreatedToken;
 import com.google.cloud.spanner.pgadapter.wireprotocol.ParseMessage;
 import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.Futures;
-import java.util.List;
 import java.util.concurrent.Future;
 
 @InternalApi
@@ -105,8 +103,8 @@ public class DeclareStatement extends IntermediatePortalStatement {
             parsedStatement,
             originalStatement),
         NO_PARAMS,
-        ImmutableList.of(),
-        ImmutableList.of());
+        NO_FORMAT_CODES,
+        NO_FORMAT_CODES);
     this.declareStatement = parse(originalStatement.getSql());
   }
 
@@ -176,10 +174,7 @@ public class DeclareStatement extends IntermediatePortalStatement {
 
   @Override
   public IntermediatePortalStatement createPortal(
-      String name,
-      byte[][] parameters,
-      List<Short> parameterFormatCodes,
-      List<Short> resultFormatCodes) {
+      String name, byte[][] parameters, short[] parameterFormatCodes, short[] resultFormatCodes) {
     // DECLARE does not support binding any parameters, so we just return the same statement.
     return this;
   }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/DiscardStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/DiscardStatement.java
index 3a95dddc..ee18d106 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/DiscardStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/DiscardStatement.java
@@ -26,9 +26,7 @@ import com.google.cloud.spanner.pgadapter.statements.BackendConnection.Connectio
 import com.google.cloud.spanner.pgadapter.statements.BackendConnection.NoResult;
 import com.google.cloud.spanner.pgadapter.statements.DiscardStatement.ParsedDiscardStatement.DiscardType;
 import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.Futures;
-import java.util.List;
 import java.util.concurrent.Future;
 
 public class DiscardStatement extends IntermediatePortalStatement {
@@ -65,8 +63,8 @@ public class DiscardStatement extends IntermediatePortalStatement {
             parsedStatement,
             originalStatement),
         NO_PARAMS,
-        ImmutableList.of(),
-        ImmutableList.of());
+        NO_FORMAT_CODES,
+        NO_FORMAT_CODES);
     this.discardStatement = parse(originalStatement.getSql());
   }
 
@@ -120,10 +118,7 @@ public class DiscardStatement extends IntermediatePortalStatement {
 
   @Override
   public IntermediatePortalStatement createPortal(
-      String name,
-      byte[][] parameters,
-      List<Short> parameterFormatCodes,
-      List<Short> resultFormatCodes) {
+      String name, byte[][] parameters, short[] parameterFormatCodes, short[] resultFormatCodes) {
     // DISCARD does not support binding any parameters, so we just return the same statement.
     return this;
   }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/ExtendedQueryProtocolHandler.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/ExtendedQueryProtocolHandler.java
index 06da673e..1e7b955a 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/ExtendedQueryProtocolHandler.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/ExtendedQueryProtocolHandler.java
@@ -138,9 +138,7 @@ public class ExtendedQueryProtocolHandler {
    * received.
    */
   public void buffer(AbstractQueryProtocolMessage message) {
-    addEvent(
-        "Received message: '" + message.getIdentifier() + "'",
-        Attributes.of(DB_STATEMENT, message.getSql()));
+    addEvent(message.receivedEventDescription(), Attributes.of(DB_STATEMENT, message.getSql()));
     messages.add(message);
   }
 
@@ -218,10 +216,9 @@ public class ExtendedQueryProtocolHandler {
         throw PGExceptionFactory.newQueryCancelledException();
       }
       if (includeReadyResponse) {
-        new ReadyResponse(
-                connectionHandler.getConnectionMetadata().getOutputStream(),
-                getBackendConnection().getConnectionState().getReadyResponseStatus())
-            .send(false);
+        ReadyResponse.send(
+            connectionHandler.getConnectionMetadata().getOutputStream(),
+            getBackendConnection().getConnectionState().getReadyResponseStatus());
       }
     } catch (Throwable exception) {
       recordException(exception);
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/FetchStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/FetchStatement.java
index 21bfec3e..9d18e7d5 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/FetchStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/FetchStatement.java
@@ -22,7 +22,6 @@ import com.google.cloud.spanner.pgadapter.wireprotocol.ControlMessage.ManuallyCr
 import com.google.cloud.spanner.pgadapter.wireprotocol.ControlMessage.PreparedType;
 import com.google.cloud.spanner.pgadapter.wireprotocol.DescribeMessage;
 import com.google.cloud.spanner.pgadapter.wireprotocol.ExecuteMessage;
-import com.google.common.collect.ImmutableList;
 
 public class FetchStatement extends AbstractFetchOrMoveStatement {
 
@@ -42,8 +41,8 @@ public class FetchStatement extends AbstractFetchOrMoveStatement {
             parsedStatement,
             originalStatement),
         NO_PARAMS,
-        ImmutableList.of(),
-        ImmutableList.of(),
+        NO_FORMAT_CODES,
+        NO_FORMAT_CODES,
         parse(originalStatement.getSql(), "fetch", ParsedFetchStatement.class));
   }
 
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/IntermediatePortalStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/IntermediatePortalStatement.java
index 42bceab7..e2a93416 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/IntermediatePortalStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/IntermediatePortalStatement.java
@@ -22,7 +22,6 @@ import com.google.cloud.spanner.pgadapter.parsers.Parser;
 import com.google.cloud.spanner.pgadapter.parsers.Parser.FormatCode;
 import com.google.cloud.spanner.pgadapter.statements.BackendConnection.NoResult;
 import com.google.common.util.concurrent.Futures;
-import java.util.List;
 import java.util.concurrent.Future;
 
 /**
@@ -32,18 +31,19 @@ import java.util.concurrent.Future;
 @InternalApi
 public class IntermediatePortalStatement extends IntermediatePreparedStatement {
   static final byte[][] NO_PARAMS = new byte[0][];
+  public static final short[] NO_FORMAT_CODES = new short[0];
 
   private final IntermediatePreparedStatement preparedStatement;
   private final byte[][] parameters;
-  protected final List<Short> parameterFormatCodes;
-  protected final List<Short> resultFormatCodes;
+  protected final short[] parameterFormatCodes;
+  protected final short[] resultFormatCodes;
 
   public IntermediatePortalStatement(
       String name,
       IntermediatePreparedStatement preparedStatement,
       byte[][] parameters,
-      List<Short> parameterFormatCodes,
-      List<Short> resultFormatCodes) {
+      short[] parameterFormatCodes,
+      short[] resultFormatCodes) {
     super(
         preparedStatement.connectionHandler,
         preparedStatement.options,
@@ -62,23 +62,23 @@ public class IntermediatePortalStatement extends IntermediatePreparedStatement {
   }
 
   public short getParameterFormatCode(int index) {
-    if (this.parameterFormatCodes.size() == 0) {
+    if (this.parameterFormatCodes.length == 0) {
       return 0;
-    } else if (index >= this.parameterFormatCodes.size()) {
-      return this.parameterFormatCodes.get(0);
+    } else if (index >= this.parameterFormatCodes.length) {
+      return this.parameterFormatCodes[0];
     } else {
-      return this.parameterFormatCodes.get(index);
+      return this.parameterFormatCodes[index];
     }
   }
 
   @Override
   public short getResultFormatCode(int index) {
-    if (this.resultFormatCodes == null || this.resultFormatCodes.isEmpty()) {
+    if (this.resultFormatCodes == null || this.resultFormatCodes.length == 0) {
       return super.getResultFormatCode(index);
-    } else if (this.resultFormatCodes.size() == 1) {
-      return this.resultFormatCodes.get(0);
+    } else if (this.resultFormatCodes.length == 1) {
+      return this.resultFormatCodes[0];
     } else {
-      return this.resultFormatCodes.get(index);
+      return this.resultFormatCodes[index];
     }
   }
 
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/IntermediatePreparedStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/IntermediatePreparedStatement.java
index d3746212..875157a1 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/IntermediatePreparedStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/IntermediatePreparedStatement.java
@@ -26,8 +26,6 @@ import com.google.cloud.spanner.pgadapter.metadata.OptionsMetadata;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.MoreExecutors;
-import java.util.Arrays;
-import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import org.postgresql.core.Oid;
@@ -39,7 +37,6 @@ import org.postgresql.core.Oid;
 public class IntermediatePreparedStatement extends IntermediateStatement {
   static final int[] NO_PARAMETER_TYPES = new int[0];
 
-  private final String name;
   protected final int[] givenParameterDataTypes;
   protected Statement statement;
   private Future<DescribeResult> describeResult;
@@ -47,12 +44,12 @@ public class IntermediatePreparedStatement extends IntermediateStatement {
   public IntermediatePreparedStatement(
       ConnectionHandler connectionHandler,
       OptionsMetadata options,
+      // TODO: Remove name argument
       String name,
       int[] givenParameterDataTypes,
       ParsedStatement parsedStatement,
       Statement originalStatement) {
     super(connectionHandler, options, parsedStatement, originalStatement);
-    this.name = name;
     this.givenParameterDataTypes = givenParameterDataTypes;
     this.statement = originalStatement;
   }
@@ -89,10 +86,7 @@ public class IntermediatePreparedStatement extends IntermediateStatement {
    * @return An Intermediate Portal Statement (or rather a bound version of this statement)
    */
   public IntermediatePortalStatement createPortal(
-      String name,
-      byte[][] parameters,
-      List<Short> parameterFormatCodes,
-      List<Short> resultFormatCodes) {
+      String name, byte[][] parameters, short[] parameterFormatCodes, short[] resultFormatCodes) {
     return new IntermediatePortalStatement(
         name, this, parameters, parameterFormatCodes, resultFormatCodes);
   }
@@ -147,8 +141,7 @@ public class IntermediatePreparedStatement extends IntermediateStatement {
         || hasOnlyNullValues(parameterValues)) {
       return;
     }
-    if (parameterValues.length != this.givenParameterDataTypes.length
-        || Arrays.stream(this.givenParameterDataTypes).anyMatch(p -> p == 0)) {
+    if (hasUnknownParams(parameterValues)) {
       // Note: We are only asking the backend to parse the types if there is at least one
       // parameter with unspecified type. Otherwise, we will rely on the types given in PARSE.
       // There is also no need to auto-describe if only null values are untyped.
@@ -179,6 +172,18 @@ public class IntermediatePreparedStatement extends IntermediateStatement {
     }
   }
 
+  private boolean hasUnknownParams(byte[][] parameterValues) {
+    if (parameterValues.length != this.givenParameterDataTypes.length) {
+      return true;
+    }
+    for (int givenParameterDataType : this.givenParameterDataTypes) {
+      if (givenParameterDataType == Oid.UNSPECIFIED) {
+        return true;
+      }
+    }
+    return false;
+  }
+
   boolean hasOnlyNullValues(byte[][] parameterValues) {
     for (byte[] parameterValue : parameterValues) {
       if (parameterValue != null) {
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/InvalidStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/InvalidStatement.java
index c3b12977..c0847765 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/InvalidStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/InvalidStatement.java
@@ -19,7 +19,6 @@ import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStateme
 import com.google.cloud.spanner.pgadapter.ConnectionHandler;
 import com.google.cloud.spanner.pgadapter.error.PGExceptionFactory;
 import com.google.cloud.spanner.pgadapter.metadata.OptionsMetadata;
-import com.google.common.collect.ImmutableList;
 
 public class InvalidStatement extends IntermediatePortalStatement {
 
@@ -40,8 +39,8 @@ public class InvalidStatement extends IntermediatePortalStatement {
             parsedStatement,
             originalStatement),
         NO_PARAMS,
-        ImmutableList.of(),
-        ImmutableList.of());
+        NO_FORMAT_CODES,
+        NO_FORMAT_CODES);
     setException(PGExceptionFactory.toPGException(exception));
   }
 }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/MoveStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/MoveStatement.java
index 28d5908c..a5a3abd1 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/MoveStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/MoveStatement.java
@@ -20,7 +20,6 @@ import com.google.cloud.spanner.pgadapter.ConnectionHandler;
 import com.google.cloud.spanner.pgadapter.metadata.OptionsMetadata;
 import com.google.cloud.spanner.pgadapter.wireprotocol.ControlMessage.ManuallyCreatedToken;
 import com.google.cloud.spanner.pgadapter.wireprotocol.ExecuteMessage;
-import com.google.common.collect.ImmutableList;
 
 /**
  * MOVE is the same as FETCH, except it just skips the results instead of actually sending the rows
@@ -45,8 +44,8 @@ public class MoveStatement extends AbstractFetchOrMoveStatement {
             parsedStatement,
             originalStatement),
         NO_PARAMS,
-        ImmutableList.of(),
-        ImmutableList.of(),
+        NO_FORMAT_CODES,
+        NO_FORMAT_CODES,
         parse(originalStatement.getSql(), "move", ParsedMoveStatement.class));
   }
 
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/PrepareStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/PrepareStatement.java
index b76bbd71..300391e9 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/PrepareStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/PrepareStatement.java
@@ -124,8 +124,8 @@ public class PrepareStatement extends IntermediatePortalStatement {
             parsedStatement,
             originalStatement),
         NO_PARAMS,
-        ImmutableList.of(),
-        ImmutableList.of());
+        NO_FORMAT_CODES,
+        NO_FORMAT_CODES);
     this.preparedStatement = parse(originalStatement.getSql());
   }
 
@@ -174,10 +174,7 @@ public class PrepareStatement extends IntermediatePortalStatement {
 
   @Override
   public IntermediatePortalStatement createPortal(
-      String name,
-      byte[][] parameters,
-      List<Short> parameterFormatCodes,
-      List<Short> resultFormatCodes) {
+      String name, byte[][] parameters, short[] parameterFormatCodes, short[] resultFormatCodes) {
     // PREPARE does not support binding any parameters, so we just return the same statement.
     return this;
   }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/ReleaseStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/ReleaseStatement.java
index 2d5ce642..144b5a9b 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/ReleaseStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/ReleaseStatement.java
@@ -26,9 +26,7 @@ import com.google.cloud.spanner.pgadapter.error.SQLState;
 import com.google.cloud.spanner.pgadapter.metadata.OptionsMetadata;
 import com.google.cloud.spanner.pgadapter.statements.SimpleParser.TableOrIndexName;
 import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.Futures;
-import java.util.List;
 import java.util.concurrent.Future;
 
 public class ReleaseStatement extends IntermediatePortalStatement {
@@ -58,8 +56,8 @@ public class ReleaseStatement extends IntermediatePortalStatement {
             parsedStatement,
             originalStatement),
         NO_PARAMS,
-        ImmutableList.of(),
-        ImmutableList.of());
+        NO_FORMAT_CODES,
+        NO_FORMAT_CODES);
     this.parsedReleaseStatement = parse(originalStatement.getSql());
   }
 
@@ -112,10 +110,7 @@ public class ReleaseStatement extends IntermediatePortalStatement {
 
   @Override
   public IntermediatePortalStatement createPortal(
-      String name,
-      byte[][] parameters,
-      List<Short> parameterFormatCodes,
-      List<Short> resultFormatCodes) {
+      String name, byte[][] parameters, short[] parameterFormatCodes, short[] resultFormatCodes) {
     // RELEASE does not support binding any parameters, so we just return the same statement.
     return this;
   }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/RollbackToStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/RollbackToStatement.java
index 45b1368b..9c76a41a 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/RollbackToStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/RollbackToStatement.java
@@ -26,9 +26,7 @@ import com.google.cloud.spanner.pgadapter.error.SQLState;
 import com.google.cloud.spanner.pgadapter.metadata.OptionsMetadata;
 import com.google.cloud.spanner.pgadapter.statements.SimpleParser.TableOrIndexName;
 import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.Futures;
-import java.util.List;
 import java.util.concurrent.Future;
 
 public class RollbackToStatement extends IntermediatePortalStatement {
@@ -58,8 +56,8 @@ public class RollbackToStatement extends IntermediatePortalStatement {
             parsedStatement,
             originalStatement),
         NO_PARAMS,
-        ImmutableList.of(),
-        ImmutableList.of());
+        NO_FORMAT_CODES,
+        NO_FORMAT_CODES);
     this.parsedRollbackToStatement = parse(originalStatement.getSql());
   }
 
@@ -123,10 +121,7 @@ public class RollbackToStatement extends IntermediatePortalStatement {
 
   @Override
   public IntermediatePortalStatement createPortal(
-      String name,
-      byte[][] parameters,
-      List<Short> parameterFormatCodes,
-      List<Short> resultFormatCodes) {
+      String name, byte[][] parameters, short[] parameterFormatCodes, short[] resultFormatCodes) {
     // ROLLBACK does not support binding any parameters, so we just return the same statement.
     return this;
   }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/SavepointStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/SavepointStatement.java
index a2f81e1a..a67c9fbe 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/SavepointStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/SavepointStatement.java
@@ -26,9 +26,7 @@ import com.google.cloud.spanner.pgadapter.error.SQLState;
 import com.google.cloud.spanner.pgadapter.metadata.OptionsMetadata;
 import com.google.cloud.spanner.pgadapter.statements.SimpleParser.TableOrIndexName;
 import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.Futures;
-import java.util.List;
 import java.util.concurrent.Future;
 
 public class SavepointStatement extends IntermediatePortalStatement {
@@ -58,8 +56,8 @@ public class SavepointStatement extends IntermediatePortalStatement {
             parsedStatement,
             originalStatement),
         NO_PARAMS,
-        ImmutableList.of(),
-        ImmutableList.of());
+        NO_FORMAT_CODES,
+        NO_FORMAT_CODES);
     this.parsedSavepointStatement = parse(originalStatement.getSql());
   }
 
@@ -111,10 +109,7 @@ public class SavepointStatement extends IntermediatePortalStatement {
 
   @Override
   public IntermediatePortalStatement createPortal(
-      String name,
-      byte[][] parameters,
-      List<Short> parameterFormatCodes,
-      List<Short> resultFormatCodes) {
+      String name, byte[][] parameters, short[] parameterFormatCodes, short[] resultFormatCodes) {
     // SAVEPOINT does not support binding any parameters, so we just return the same statement.
     return this;
   }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/SelectCurrentSettingStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/SelectCurrentSettingStatement.java
index 8b261baa..7c260269 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/SelectCurrentSettingStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/SelectCurrentSettingStatement.java
@@ -33,7 +33,6 @@ import com.google.cloud.spanner.pgadapter.statements.SimpleParser.TableOrIndexNa
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.Futures;
-import java.util.List;
 import java.util.Locale;
 import java.util.concurrent.Future;
 
@@ -60,8 +59,8 @@ public class SelectCurrentSettingStatement extends IntermediatePortalStatement {
             parsedStatement,
             originalStatement),
         NO_PARAMS,
-        ImmutableList.of(),
-        ImmutableList.of());
+        NO_FORMAT_CODES,
+        NO_FORMAT_CODES);
     this.showStatement = parse(originalStatement.getSql());
   }
 
@@ -128,10 +127,7 @@ public class SelectCurrentSettingStatement extends IntermediatePortalStatement {
 
   @Override
   public IntermediatePortalStatement createPortal(
-      String name,
-      byte[][] parameters,
-      List<Short> parameterFormatCodes,
-      List<Short> resultFormatCodes) {
+      String name, byte[][] parameters, short[] parameterFormatCodes, short[] resultFormatCodes) {
     return this;
   }
 }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/SelectSetConfigStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/SelectSetConfigStatement.java
index 0029560e..d295f60c 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/SelectSetConfigStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/SelectSetConfigStatement.java
@@ -34,7 +34,6 @@ import com.google.cloud.spanner.pgadapter.statements.SimpleParser.TableOrIndexNa
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.Futures;
-import java.util.List;
 import java.util.Locale;
 import java.util.concurrent.Future;
 
@@ -61,8 +60,8 @@ public class SelectSetConfigStatement extends IntermediatePortalStatement {
             parsedStatement,
             originalStatement),
         NO_PARAMS,
-        ImmutableList.of(),
-        ImmutableList.of());
+        NO_FORMAT_CODES,
+        NO_FORMAT_CODES);
     this.setStatement = parse(originalStatement.getSql());
   }
 
@@ -143,10 +142,7 @@ public class SelectSetConfigStatement extends IntermediatePortalStatement {
 
   @Override
   public IntermediatePortalStatement createPortal(
-      String name,
-      byte[][] parameters,
-      List<Short> parameterFormatCodes,
-      List<Short> resultFormatCodes) {
+      String name, byte[][] parameters, short[] parameterFormatCodes, short[] resultFormatCodes) {
     return this;
   }
 }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/ShowDatabaseDdlStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/ShowDatabaseDdlStatement.java
index 6886c937..4ceb7eb9 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/ShowDatabaseDdlStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/ShowDatabaseDdlStatement.java
@@ -70,8 +70,8 @@ public class ShowDatabaseDdlStatement extends IntermediatePortalStatement {
             parsedStatement,
             originalStatement),
         NO_PARAMS,
-        ImmutableList.of(),
-        ImmutableList.of());
+        NO_FORMAT_CODES,
+        NO_FORMAT_CODES);
     this.parsedShowDatabaseDdlStatement = parse(originalStatement.getSql());
   }
 
@@ -150,10 +150,7 @@ public class ShowDatabaseDdlStatement extends IntermediatePortalStatement {
 
   @Override
   public IntermediatePortalStatement createPortal(
-      String name,
-      byte[][] parameters,
-      List<Short> parameterFormatCodes,
-      List<Short> resultFormatCodes) {
+      String name, byte[][] parameters, short[] parameterFormatCodes, short[] resultFormatCodes) {
     // SHOW DATABASE DDL does not support binding any parameters, so we just return the same
     // statement.
     return this;
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/ShutdownStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/ShutdownStatement.java
index 329b3e25..109ea28e 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/ShutdownStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/ShutdownStatement.java
@@ -28,9 +28,7 @@ import com.google.cloud.spanner.pgadapter.metadata.OptionsMetadata;
 import com.google.cloud.spanner.pgadapter.statements.BackendConnection.NoResult;
 import com.google.cloud.spanner.pgadapter.statements.ShutdownStatement.ParsedShutdownStatement.Builder;
 import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.Futures;
-import java.util.List;
 import java.util.concurrent.Future;
 
 /**
@@ -76,8 +74,8 @@ public class ShutdownStatement extends IntermediatePortalStatement {
             parsedStatement,
             originalStatement),
         NO_PARAMS,
-        ImmutableList.of(),
-        ImmutableList.of());
+        NO_FORMAT_CODES,
+        NO_FORMAT_CODES);
     this.parsedShutdownStatement = parse(originalStatement.getSql(), connectionHandler.getServer());
   }
 
@@ -125,10 +123,7 @@ public class ShutdownStatement extends IntermediatePortalStatement {
 
   @Override
   public IntermediatePortalStatement createPortal(
-      String name,
-      byte[][] parameters,
-      List<Short> parameterFormatCodes,
-      List<Short> resultFormatCodes) {
+      String name, byte[][] parameters, short[] parameterFormatCodes, short[] resultFormatCodes) {
     // SHUTDOWN does not support binding any parameters, so we just return the same statement.
     return this;
   }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/VacuumStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/VacuumStatement.java
index 1c0d2ee5..7f0e037f 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/VacuumStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/VacuumStatement.java
@@ -110,8 +110,8 @@ public class VacuumStatement extends IntermediatePortalStatement {
             parsedStatement,
             originalStatement),
         NO_PARAMS,
-        ImmutableList.of(),
-        ImmutableList.of());
+        NO_FORMAT_CODES,
+        NO_FORMAT_CODES);
     this.parsedVacuumStatement = parse(originalStatement.getSql());
   }
 
@@ -148,10 +148,7 @@ public class VacuumStatement extends IntermediatePortalStatement {
 
   @Override
   public IntermediatePortalStatement createPortal(
-      String name,
-      byte[][] parameters,
-      List<Short> parameterFormatCodes,
-      List<Short> resultFormatCodes) {
+      String name, byte[][] parameters, short[] parameterFormatCodes, short[] resultFormatCodes) {
     // VACUUM does not support binding any parameters, so we just return the same statement.
     return this;
   }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/utils/Converter.java b/src/main/java/com/google/cloud/spanner/pgadapter/utils/Converter.java
index 82e7454e..1c156f49 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/utils/Converter.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/utils/Converter.java
@@ -120,6 +120,8 @@ public class Converter implements AutoCloseable {
                 : fixedFormat;
         byte[] column =
             Converter.convertToPG(outputStream, this.resultSet, column_index, format, sessionState);
+        // TODO: Remove this if statement and write statements once all data types are written
+        // directly to the output stream.
         if (column != null) {
           outputStream.writeInt(column.length);
           outputStream.write(column);
@@ -137,22 +139,24 @@ public class Converter implements AutoCloseable {
    * Return the data of the specified column of the {@link ResultSet} as a byte array. The column
    * may not contain a null value.
    *
+   * @param outputStream The output stream to write value to if the converter supports that.
    * @param result The {@link ResultSet} to read the data from.
    * @param position The column index.
    * @param format The {@link DataFormat} format to use to encode the data.
-   * @return a byte array containing the data in the specified format.
+   * @param sessionState The {@link SessionState} that should be used to determine how to format the
+   *     data (e.g. timezone).
+   * @return a byte array containing the data in the specified format or null if the data was
+   *     written directly to the output stream.
    */
-  public static byte[] convertToPG(
-      ResultSet result, int position, DataFormat format, SessionState sessionState) {
-    return convertToPG(null, result, position, format, sessionState);
-  }
-
+  // TODO: Rename this method to writeToPG and change return type to void once all data types write
+  // directly to the output stream.
   public static byte[] convertToPG(
       DataOutputStream outputStream,
       ResultSet result,
       int position,
       DataFormat format,
-      SessionState sessionState) {
+      SessionState sessionState)
+      throws IOException {
     Preconditions.checkArgument(!result.isNull(position), "Column may not contain a null value");
     Type type = result.getColumnType(position);
     switch (type.getCode()) {
@@ -161,14 +165,14 @@ public class Converter implements AutoCloseable {
       case BYTES:
         return BinaryParser.convertToPG(sessionState, outputStream, result, position, format);
       case DATE:
-        return DateParser.convertToPG(result, position, format);
+        return DateParser.convertToPG(sessionState, outputStream, result, position, format);
       case FLOAT32:
         return FloatParser.convertToPG(result, position, format);
       case FLOAT64:
         return DoubleParser.convertToPG(result, position, format);
       case INT64:
       case PG_OID:
-        return LongParser.convertToPG(result, position, format);
+        return LongParser.convertToPG(sessionState, outputStream, result, position, format);
       case PG_NUMERIC:
         return NumericParser.convertToPG(result, position, format);
       case STRING:
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/BindCompleteResponse.java b/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/BindCompleteResponse.java
index b368abf5..7f716670 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/BindCompleteResponse.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/BindCompleteResponse.java
@@ -22,6 +22,12 @@ import java.text.MessageFormat;
 /** Assures to the client that a statement got bound to a portal successfully. */
 @InternalApi
 public class BindCompleteResponse extends WireOutput {
+  private static final byte[] RESPONSE = new byte[] {'2', 0, 0, 0, 4};
+
+  /** Send a standard BindComplete response message. */
+  public static void send(DataOutputStream output) throws IOException {
+    output.write(RESPONSE);
+  }
 
   public BindCompleteResponse(DataOutputStream output) {
     super(output, 4);
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/CloseCompleteResponse.java b/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/CloseCompleteResponse.java
index 1edf8ef7..9a70a7bc 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/CloseCompleteResponse.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/CloseCompleteResponse.java
@@ -16,11 +16,18 @@ package com.google.cloud.spanner.pgadapter.wireoutput;
 
 import com.google.api.core.InternalApi;
 import java.io.DataOutputStream;
+import java.io.IOException;
 import java.text.MessageFormat;
 
 /** Assures to the client that a portal got closed successfully. */
 @InternalApi
 public class CloseCompleteResponse extends WireOutput {
+  private static final byte[] RESPONSE = new byte[] {'3', 0, 0, 0, 4};
+
+  /** Send a standard CloseResponse message. */
+  public static void send(DataOutputStream output) throws IOException {
+    output.write(RESPONSE);
+  }
 
   public CloseCompleteResponse(DataOutputStream output) {
     super(output, 4);
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/CommandCompleteResponse.java b/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/CommandCompleteResponse.java
index 2390c841..780b9177 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/CommandCompleteResponse.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/CommandCompleteResponse.java
@@ -17,22 +17,40 @@ package com.google.cloud.spanner.pgadapter.wireoutput;
 import com.google.api.core.InternalApi;
 import java.io.DataOutputStream;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.text.MessageFormat;
 
 /** Signals to a client that an issued query is complete. */
 @InternalApi
 public class CommandCompleteResponse extends WireOutput {
-
+  private static final byte IDENTIFIER = 'C';
   private static final int HEADER_LENGTH = 4;
   private static final int NULL_TERMINATOR_LENGTH = 1;
 
   private static final byte NULL_TERMINATOR = 0;
 
+  /** Send a CommandComplete response. */
+  public static void send(DataOutputStream output, String command) throws IOException {
+    byte[] commandBytes = command.getBytes(StandardCharsets.UTF_8);
+    output.writeByte(IDENTIFIER);
+    output.writeInt(calculateLength(commandBytes));
+    output.write(commandBytes);
+    output.write(NULL_TERMINATOR);
+  }
+
+  private static int calculateLength(byte[] command) {
+    return HEADER_LENGTH + command.length + NULL_TERMINATOR_LENGTH;
+  }
+
   private final byte[] command;
 
   public CommandCompleteResponse(DataOutputStream output, String command) {
-    super(output, HEADER_LENGTH + command.getBytes(UTF8).length + NULL_TERMINATOR_LENGTH);
-    this.command = command.getBytes(UTF8);
+    this(output, command.getBytes(UTF8));
+  }
+
+  private CommandCompleteResponse(DataOutputStream output, byte[] command) {
+    super(output, HEADER_LENGTH + command.length + NULL_TERMINATOR_LENGTH);
+    this.command = command;
   }
 
   @Override
@@ -43,7 +61,7 @@ public class CommandCompleteResponse extends WireOutput {
 
   @Override
   public byte getIdentifier() {
-    return 'C';
+    return IDENTIFIER;
   }
 
   @Override
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/ParseCompleteResponse.java b/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/ParseCompleteResponse.java
index dffe2ff4..0675e017 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/ParseCompleteResponse.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/ParseCompleteResponse.java
@@ -22,6 +22,12 @@ import java.text.MessageFormat;
 /** Signals the end of a parse transaction. */
 @InternalApi
 public class ParseCompleteResponse extends WireOutput {
+  private static final byte[] RESPONSE = new byte[] {'1', 0, 0, 0, 4};
+
+  /** Send a standard ParseComplete response. */
+  public static void send(DataOutputStream output) throws IOException {
+    output.write(RESPONSE);
+  }
 
   public ParseCompleteResponse(DataOutputStream output) {
     super(output, 4);
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/PortalSuspendedResponse.java b/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/PortalSuspendedResponse.java
index 9872870f..8a3e7aaf 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/PortalSuspendedResponse.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/PortalSuspendedResponse.java
@@ -16,11 +16,18 @@ package com.google.cloud.spanner.pgadapter.wireoutput;
 
 import com.google.api.core.InternalApi;
 import java.io.DataOutputStream;
+import java.io.IOException;
 import java.text.MessageFormat;
 
 /** Signals that there are more rows available. */
 @InternalApi
 public class PortalSuspendedResponse extends WireOutput {
+  private static final byte[] RESPONSE = new byte[] {'s', 0, 0, 0, 4};
+
+  /** Send a standard PortalSuspended response. */
+  public static void send(DataOutputStream output) throws IOException {
+    output.write(RESPONSE);
+  }
 
   public PortalSuspendedResponse(DataOutputStream output) {
     super(output, 4);
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/ReadyResponse.java b/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/ReadyResponse.java
index a3900b29..742caf86 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/ReadyResponse.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/ReadyResponse.java
@@ -21,10 +21,44 @@ import java.io.IOException;
 import java.text.MessageFormat;
 
 /**
- * Signals readiness status to receieve messages (here we only tend to send Idle, which means ready)
+ * Signals readiness status to receive messages (here we only tend to send Idle, which means ready)
  */
 @InternalApi
 public class ReadyResponse extends WireOutput {
+  private static final byte[] IDLE_RESPONSE = new byte[] {'Z', 0, 0, 0, 5, (byte) Status.IDLE.c};
+  private static final byte[] TRANSACTION_RESPONSE =
+      new byte[] {'Z', 0, 0, 0, 5, (byte) Status.TRANSACTION.c};
+  private static final byte[] FAILED_RESPONSE =
+      new byte[] {'Z', 0, 0, 0, 5, (byte) Status.FAILED.c};
+
+  /** Send a ReadyResponse with the given status. */
+  public static void send(DataOutputStream output, Status status) throws IOException {
+    switch (status) {
+      case IDLE:
+        sendIdleResponse(output);
+        break;
+      case TRANSACTION:
+        sendTransactionResponse(output);
+        break;
+      case FAILED:
+        sendFailedResponse(output);
+        break;
+      default:
+        throw new IllegalArgumentException();
+    }
+  }
+
+  public static void sendIdleResponse(DataOutputStream output) throws IOException {
+    output.write(IDLE_RESPONSE);
+  }
+
+  public static void sendTransactionResponse(DataOutputStream output) throws IOException {
+    output.write(TRANSACTION_RESPONSE);
+  }
+
+  public static void sendFailedResponse(DataOutputStream output) throws IOException {
+    output.write(FAILED_RESPONSE);
+  }
 
   private final Status status;
 
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/AbstractQueryProtocolMessage.java b/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/AbstractQueryProtocolMessage.java
index f827ca8c..1b288fb8 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/AbstractQueryProtocolMessage.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/AbstractQueryProtocolMessage.java
@@ -20,6 +20,8 @@ import com.google.cloud.spanner.pgadapter.ConnectionHandler.QueryMode;
 import com.google.cloud.spanner.pgadapter.statements.BackendConnection;
 import com.google.cloud.spanner.pgadapter.statements.ExtendedQueryProtocolHandler;
 import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * Abstract base class for extended query protocol messages. These can be buffered in memory locally
@@ -67,4 +69,16 @@ public abstract class AbstractQueryProtocolMessage extends ControlMessage {
     super.handleError(exception);
     this.returnedErrorResponse = true;
   }
+
+  private static final Map<Class<? extends AbstractQueryProtocolMessage>, String>
+      RECEIVED_EVENT_DESCRIPTIONS = new HashMap<>();
+
+  public String receivedEventDescription() {
+    String value = RECEIVED_EVENT_DESCRIPTIONS.get(getClass());
+    if (value == null) {
+      value = "Received message: '" + getIdentifier() + "'";
+      RECEIVED_EVENT_DESCRIPTIONS.put(getClass(), value);
+    }
+    return value;
+  }
 }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/BindMessage.java b/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/BindMessage.java
index 498b28c2..a1291671 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/BindMessage.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/BindMessage.java
@@ -14,6 +14,8 @@
 
 package com.google.cloud.spanner.pgadapter.wireprotocol;
 
+import static com.google.cloud.spanner.pgadapter.statements.IntermediatePortalStatement.NO_FORMAT_CODES;
+
 import com.google.api.core.InternalApi;
 import com.google.cloud.spanner.pgadapter.ConnectionHandler;
 import com.google.cloud.spanner.pgadapter.statements.BackendConnection;
@@ -21,10 +23,8 @@ import com.google.cloud.spanner.pgadapter.statements.IntermediatePortalStatement
 import com.google.cloud.spanner.pgadapter.statements.IntermediatePreparedStatement;
 import com.google.cloud.spanner.pgadapter.wireoutput.BindCompleteResponse;
 import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
 import java.text.MessageFormat;
 import java.util.Arrays;
-import java.util.List;
 
 /**
  * Message of type bind (meaning that it is a message called to a prepared statement to complete it
@@ -37,8 +37,8 @@ public class BindMessage extends AbstractQueryProtocolMessage {
 
   private final String portalName;
   private final String statementName;
-  private final List<Short> formatCodes;
-  private final List<Short> resultFormatCodes;
+  private final short[] formatCodes;
+  private final short[] resultFormatCodes;
   private final byte[][] parameters;
   private final IntermediatePortalStatement statement;
 
@@ -72,8 +72,8 @@ public class BindMessage extends AbstractQueryProtocolMessage {
     super(connection, 4, manuallyCreatedToken);
     this.portalName = portalName;
     this.statementName = statementName;
-    this.formatCodes = ImmutableList.of();
-    this.resultFormatCodes = ImmutableList.of();
+    this.formatCodes = NO_FORMAT_CODES;
+    this.resultFormatCodes = NO_FORMAT_CODES;
     this.parameters = Preconditions.checkNotNull(parameters);
     IntermediatePreparedStatement statement = connection.getStatement(statementName);
     this.statement =
@@ -107,7 +107,7 @@ public class BindMessage extends AbstractQueryProtocolMessage {
   public void flush() throws Exception {
     if (isExtendedProtocol()) {
       // The simple query protocol does not expect a BindComplete response.
-      new BindCompleteResponse(this.outputStream).send(false);
+      BindCompleteResponse.send(this.outputStream);
     }
   }
 
@@ -158,11 +158,11 @@ public class BindMessage extends AbstractQueryProtocolMessage {
     return this.parameters;
   }
 
-  public List<Short> getFormatCodes() {
+  public short[] getFormatCodes() {
     return this.formatCodes;
   }
 
-  public List<Short> getResultFormatCodes() {
+  public short[] getResultFormatCodes() {
     return this.resultFormatCodes;
   }
 }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/BootstrapMessage.java b/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/BootstrapMessage.java
index 68c7376d..85044f2b 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/BootstrapMessage.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/BootstrapMessage.java
@@ -22,7 +22,6 @@ import com.google.cloud.spanner.pgadapter.wireoutput.KeyDataResponse;
 import com.google.cloud.spanner.pgadapter.wireoutput.NoticeResponse;
 import com.google.cloud.spanner.pgadapter.wireoutput.ParameterStatusResponse;
 import com.google.cloud.spanner.pgadapter.wireoutput.ReadyResponse;
-import com.google.cloud.spanner.pgadapter.wireoutput.ReadyResponse.Status;
 import java.io.DataOutputStream;
 import java.nio.charset.StandardCharsets;
 import java.time.ZoneId;
@@ -171,6 +170,7 @@ public abstract class BootstrapMessage extends WireMessage {
     for (NoticeResponse noticeResponse : startupNotices) {
       noticeResponse.send(false);
     }
-    new ReadyResponse(output, Status.IDLE).send();
+    ReadyResponse.sendIdleResponse(output);
+    output.flush();
   }
 }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/CloseMessage.java b/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/CloseMessage.java
index d91094c6..d1c13f70 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/CloseMessage.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/CloseMessage.java
@@ -51,7 +51,7 @@ public class CloseMessage extends ControlMessage {
     this.statement = statement;
   }
 
-  /** Close the statement server-side and clean up by deleting their metdata locally. */
+  /** Close the statement server-side and clean up by deleting their metadata locally. */
   @Override
   protected void sendPayload() throws Exception {
     if (this.statement != null) {
@@ -62,7 +62,8 @@ public class CloseMessage extends ControlMessage {
         this.connection.closeStatement(this.name);
       }
     }
-    new CloseCompleteResponse(this.outputStream).send();
+    CloseCompleteResponse.send(this.outputStream);
+    this.outputStream.flush();
   }
 
   @Override
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/ControlMessage.java b/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/ControlMessage.java
index 1cfc71f0..a3a40fcc 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/ControlMessage.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/ControlMessage.java
@@ -15,6 +15,7 @@
 package com.google.cloud.spanner.pgadapter.wireprotocol;
 
 import static com.google.cloud.spanner.pgadapter.statements.BackendConnection.DB_STATEMENT;
+import static com.google.cloud.spanner.pgadapter.statements.IntermediatePortalStatement.NO_FORMAT_CODES;
 
 import com.google.api.core.InternalApi;
 import com.google.api.gax.grpc.GrpcCallContext;
@@ -207,11 +208,14 @@ public abstract class ControlMessage extends WireMessage {
    * @return A list of format codes.
    * @throws Exception If reading fails in any way.
    */
-  protected static List<Short> getFormatCodes(DataInputStream input) throws Exception {
-    List<Short> formatCodes = new ArrayList<>();
+  protected static short[] getFormatCodes(DataInputStream input) throws Exception {
     short numberOfFormatCodes = input.readShort();
+    if (numberOfFormatCodes == 0) {
+      return NO_FORMAT_CODES;
+    }
+    short[] formatCodes = new short[numberOfFormatCodes];
     for (int i = 0; i < numberOfFormatCodes; i++) {
-      formatCodes.add(input.readShort());
+      formatCodes[i] = input.readShort();
     }
     return formatCodes;
   }
@@ -266,11 +270,11 @@ public abstract class ControlMessage extends WireMessage {
       switch (statement.getStatementType()) {
         case DDL:
         case UNKNOWN:
-          new CommandCompleteResponse(this.outputStream, command).send(false);
+          CommandCompleteResponse.send(this.outputStream, command);
           break;
         case CLIENT_SIDE:
           if (statement.getStatementResult().getResultType() != ResultType.RESULT_SET) {
-            new CommandCompleteResponse(this.outputStream, command).send(false);
+            CommandCompleteResponse.send(this.outputStream, command);
             break;
           }
           // fallthrough to QUERY
@@ -280,13 +284,12 @@ public abstract class ControlMessage extends WireMessage {
             SendResultSetState state = sendResultSet(statement, mode, maxRows);
             statement.setHasMoreData(state.hasMoreRows());
             if (state.hasMoreRows() && mode == QueryMode.EXTENDED) {
-              new PortalSuspendedResponse(this.outputStream).send(false);
+              PortalSuspendedResponse.send(this.outputStream);
             } else {
               if (!state.hasMoreRows() && mode == QueryMode.EXTENDED) {
                 statement.close();
               }
-              new CommandCompleteResponse(this.outputStream, state.getCommandAndNumRows())
-                  .send(false);
+              CommandCompleteResponse.send(this.outputStream, state.getCommandAndNumRows());
             }
           } else {
             // For an INSERT command, the tag is INSERT oid rows, where rows is the number of rows
@@ -294,7 +297,7 @@ public abstract class ControlMessage extends WireMessage {
             // target table had OIDs, but OIDs system columns are not supported anymore; therefore
             // oid is always 0.
             command += ("INSERT".equals(command) ? " 0 " : " ") + statement.getUpdateCount();
-            new CommandCompleteResponse(this.outputStream, command).send(false);
+            CommandCompleteResponse.send(this.outputStream, command);
           }
           break;
         default:
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/FunctionCallMessage.java b/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/FunctionCallMessage.java
index cc05096d..bbdee289 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/FunctionCallMessage.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/FunctionCallMessage.java
@@ -17,7 +17,6 @@ package com.google.cloud.spanner.pgadapter.wireprotocol;
 import com.google.api.core.InternalApi;
 import com.google.cloud.spanner.pgadapter.ConnectionHandler;
 import java.text.MessageFormat;
-import java.util.List;
 
 /**
  * Normally used to send a function call the back-end. Spanner does not currently support this, so
@@ -31,7 +30,7 @@ public class FunctionCallMessage extends ControlMessage {
   protected static final char IDENTIFIER = 'F';
 
   private final int functionID;
-  private final List<Short> argumentFormatCodes;
+  private final short[] argumentFormatCodes;
   private final byte[][] arguments;
   private final Short resultFormatCode;
 
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/ParseMessage.java b/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/ParseMessage.java
index fcdc30a9..762e4251 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/ParseMessage.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/ParseMessage.java
@@ -297,7 +297,7 @@ public class ParseMessage extends AbstractQueryProtocolMessage {
       handleError(statement.getException());
     } else if (isExtendedProtocol()) {
       // The simple query protocol does not need the ParseComplete response.
-      new ParseCompleteResponse(this.outputStream).send(false);
+      ParseCompleteResponse.send(this.outputStream);
     }
   }
 
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/WireMessage.java b/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/WireMessage.java
index c6b83a25..7fb6060e 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/WireMessage.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/WireMessage.java
@@ -23,7 +23,6 @@ import java.io.DataOutputStream;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.text.MessageFormat;
-import java.util.Arrays;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -149,30 +148,47 @@ public abstract class WireMessage {
   }
 
   /**
-   * Reads a null-terminated string from a {@link DataInputStream}. Note that though existing
-   * solutions for this exist, they are either not keyed exactly for our use case, or would lead to
-   * a more combersome addition to this codebase. Also note the 128 byte length is chosen from
-   * profiling and determining that it exceeds the 90th percentile size for inbound messages.
+   * The max number of characters to read when scanning for a null-terminator. Null-terminated
+   * strings are used in the PG wire-protocol for names of prepared statements and portals, but also
+   * for the SQL string of a statement. We therefore need to read potentially very long strings.
+   */
+  private static final int MARK_READ_LIMIT = 100_000_000;
+
+  /**
+   * Reads a null-terminated string from a {@link DataInputStream}.
    *
    * @return the string.
    * @throws IOException if an error occurs while reading from the stream, or if no null-terminator
    *     is found before the end of the stream.
    */
   public String readString() throws IOException {
-    byte[] buffer = new byte[128];
+    this.inputStream.mark(MARK_READ_LIMIT);
     int index = 0;
-    while (true) {
+    while (index < MARK_READ_LIMIT) {
       byte b = this.inputStream.readByte();
       if (b == 0) {
         break;
       }
-      buffer[index] = b;
       index++;
-      if (index == buffer.length) {
-        buffer = Arrays.copyOf(buffer, buffer.length * 2);
+      if (index == MARK_READ_LIMIT) {
+        throw new IOException("No null terminator found");
       }
     }
-    return new String(buffer, 0, index, StandardCharsets.UTF_8);
+    // Reset the stream to the mark and read the name (if any).
+    this.inputStream.reset();
+    if (index == 0) {
+      // No name, but we still need to skip the null-terminator.
+      //noinspection StatementWithEmptyBody
+      while (this.inputStream.skip(1) < 1) {}
+      return "";
+    }
+
+    byte[] result = new byte[index];
+    this.inputStream.readFully(result);
+    // Skip the null-terminator.
+    //noinspection StatementWithEmptyBody
+    while (this.inputStream.skip(1) < 1) {}
+    return new String(result, StandardCharsets.UTF_8);
   }
 
   /**


Test patch:
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/DeallocateStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/DeallocateStatement.java
index 43041d18..7cfc30c6 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/DeallocateStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/DeallocateStatement.java
@@ -26,9 +26,7 @@ import com.google.cloud.spanner.pgadapter.metadata.OptionsMetadata;
 import com.google.cloud.spanner.pgadapter.statements.BackendConnection.NoResult;
 import com.google.cloud.spanner.pgadapter.statements.SimpleParser.TableOrIndexName;
 import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.Futures;
-import java.util.List;
 import java.util.concurrent.Future;
 
 public class DeallocateStatement extends IntermediatePortalStatement {
@@ -58,8 +56,8 @@ public class DeallocateStatement extends IntermediatePortalStatement {
             parsedStatement,
             originalStatement),
         NO_PARAMS,
-        ImmutableList.of(),
-        ImmutableList.of());
+        NO_FORMAT_CODES,
+        NO_FORMAT_CODES);
     this.deallocateStatement = parse(originalStatement.getSql());
   }
 
@@ -98,10 +96,7 @@ public class DeallocateStatement extends IntermediatePortalStatement {
 
   @Override
   public IntermediatePortalStatement createPortal(
-      String name,
-      byte[][] parameters,
-      List<Short> parameterFormatCodes,
-      List<Short> resultFormatCodes) {
+      String name, byte[][] parameters, short[] parameterFormatCodes, short[] resultFormatCodes) {
     // EXECUTE does not support binding any parameters, so we just return the same statement.
     return this;
   }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/ExecuteStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/ExecuteStatement.java
index e3dcdf01..479cb25a 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/ExecuteStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/ExecuteStatement.java
@@ -31,7 +31,6 @@ import com.google.cloud.spanner.pgadapter.wireprotocol.ControlMessage.PreparedTy
 import com.google.cloud.spanner.pgadapter.wireprotocol.DescribeMessage;
 import com.google.cloud.spanner.pgadapter.wireprotocol.ExecuteMessage;
 import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.Futures;
 import java.nio.charset.StandardCharsets;
 import java.util.Collections;
@@ -69,8 +68,8 @@ public class ExecuteStatement extends IntermediatePortalStatement {
             parsedStatement,
             originalStatement),
         NO_PARAMS,
-        ImmutableList.of(),
-        ImmutableList.of());
+        NO_FORMAT_CODES,
+        NO_FORMAT_CODES);
     this.executeStatement = parse(originalStatement.getSql());
   }
 
@@ -119,10 +118,7 @@ public class ExecuteStatement extends IntermediatePortalStatement {
 
   @Override
   public IntermediatePortalStatement createPortal(
-      String name,
-      byte[][] parameters,
-      List<Short> parameterFormatCodes,
-      List<Short> resultFormatCodes) {
+      String name, byte[][] parameters, short[] parameterFormatCodes, short[] resultFormatCodes) {
     // EXECUTE does not support binding any parameters, so we just return the same statement.
     return this;
   }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/TruncateStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/TruncateStatement.java
index 5dec5b54..75589035 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/TruncateStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/TruncateStatement.java
@@ -73,8 +73,8 @@ public class TruncateStatement extends IntermediatePortalStatement {
             parsedStatement,
             originalStatement),
         NO_PARAMS,
-        ImmutableList.of(),
-        ImmutableList.of());
+        NO_FORMAT_CODES,
+        NO_FORMAT_CODES);
     this.truncateStatement = parse(originalStatement.getSql());
   }
 
@@ -111,10 +111,7 @@ public class TruncateStatement extends IntermediatePortalStatement {
 
   @Override
   public IntermediatePortalStatement createPortal(
-      String name,
-      byte[][] parameters,
-      List<Short> parameterFormatCodes,
-      List<Short> resultFormatCodes) {
+      String name, byte[][] parameters, short[] parameterFormatCodes, short[] resultFormatCodes) {
     // TRUNCATE does not support binding any parameters, so we just return the same statement.
     return this;
   }
diff --git a/src/test/java/com/google/cloud/spanner/pgadapter/python/psycopg3/Psycopg3MockServerTest.java b/src/test/java/com/google/cloud/spanner/pgadapter/python/psycopg3/Psycopg3MockServerTest.java
index 0158a11f..159e667e 100644
--- a/src/test/java/com/google/cloud/spanner/pgadapter/python/psycopg3/Psycopg3MockServerTest.java
+++ b/src/test/java/com/google/cloud/spanner/pgadapter/python/psycopg3/Psycopg3MockServerTest.java
@@ -424,8 +424,8 @@ public class Psycopg3MockServerTest extends AbstractMockServerTest {
             .collect(Collectors.toList());
     assertEquals(1, bindMessages.size());
     BindMessage bindMessage = bindMessages.get(0);
-    assertEquals(1, bindMessage.getResultFormatCodes().size());
-    assertEquals(format.getCode(), bindMessage.getResultFormatCodes().get(0).shortValue());
+    assertEquals(1, bindMessage.getResultFormatCodes().length);
+    assertEquals(format.getCode(), bindMessage.getResultFormatCodes()[0]);
   }
 
   @Test
@@ -622,10 +622,8 @@ public class Psycopg3MockServerTest extends AbstractMockServerTest {
             .collect(Collectors.toList());
     assertEquals(1, bindMessages.size());
     BindMessage bindMessage = bindMessages.get(0);
-    assertEquals(11, bindMessage.getFormatCodes().size());
-    assertArrayEquals(
-        new Short[] {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
-        bindMessage.getFormatCodes().toArray(new Short[0]));
+    assertEquals(11, bindMessage.getFormatCodes().length);
+    assertArrayEquals(new short[] {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, bindMessage.getFormatCodes());
   }
 
   @Test
@@ -690,10 +688,8 @@ public class Psycopg3MockServerTest extends AbstractMockServerTest {
             .collect(Collectors.toList());
     assertEquals(1, bindMessages.size());
     BindMessage bindMessage = bindMessages.get(0);
-    assertEquals(11, bindMessage.getFormatCodes().size());
-    assertArrayEquals(
-        new Short[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-        bindMessage.getFormatCodes().toArray(new Short[0]));
+    assertEquals(11, bindMessage.getFormatCodes().length);
+    assertArrayEquals(new short[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, bindMessage.getFormatCodes());
   }
 
   @Test
diff --git a/src/test/java/com/google/cloud/spanner/pgadapter/statements/StatementTest.java b/src/test/java/com/google/cloud/spanner/pgadapter/statements/StatementTest.java
index a5513ef5..bae11d0d 100644
--- a/src/test/java/com/google/cloud/spanner/pgadapter/statements/StatementTest.java
+++ b/src/test/java/com/google/cloud/spanner/pgadapter/statements/StatementTest.java
@@ -14,6 +14,7 @@
 
 package com.google.cloud.spanner.pgadapter.statements;
 
+import static com.google.cloud.spanner.pgadapter.statements.IntermediatePortalStatement.NO_FORMAT_CODES;
 import static com.google.cloud.spanner.pgadapter.statements.IntermediatePortalStatement.NO_PARAMS;
 import static com.google.cloud.spanner.pgadapter.statements.IntermediatePreparedStatement.NO_PARAMETER_TYPES;
 import static com.google.cloud.spanner.pgadapter.utils.ClientAutoDetector.EMPTY_LOCAL_STATEMENTS;
@@ -69,7 +70,6 @@ import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.nio.file.Files;
 import java.nio.file.Paths;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.UUID;
 import java.util.concurrent.ExecutorService;
@@ -126,8 +126,8 @@ public class StatementTest {
             new IntermediatePreparedStatement(
                 connectionHandler, options, "", NO_PARAMETER_TYPES, parse(sql), Statement.of(sql)),
             NO_PARAMS,
-            ImmutableList.of(),
-            ImmutableList.of());
+            NO_FORMAT_CODES,
+            NO_FORMAT_CODES);
 
     assertFalse(intermediateStatement.isExecuted());
     assertEquals("SELECT", intermediateStatement.getCommand());
@@ -155,8 +155,8 @@ public class StatementTest {
             new IntermediatePreparedStatement(
                 connectionHandler, options, "", NO_PARAMETER_TYPES, parse(sql), Statement.of(sql)),
             NO_PARAMS,
-            ImmutableList.of(),
-            ImmutableList.of());
+            NO_FORMAT_CODES,
+            NO_FORMAT_CODES);
 
     assertFalse(intermediateStatement.isExecuted());
     assertEquals("UPDATE", intermediateStatement.getCommand());
@@ -190,8 +190,8 @@ public class StatementTest {
             new IntermediatePreparedStatement(
                 connectionHandler, options, "", NO_PARAMETER_TYPES, parse(sql), Statement.of(sql)),
             NO_PARAMS,
-            ImmutableList.of(),
-            ImmutableList.of());
+            NO_FORMAT_CODES,
+            NO_FORMAT_CODES);
     BackendConnection backendConnection =
         new BackendConnection(
             NOOP_OTEL,
@@ -237,8 +237,8 @@ public class StatementTest {
             new IntermediatePreparedStatement(
                 connectionHandler, options, "", NO_PARAMETER_TYPES, parse(sql), Statement.of(sql)),
             NO_PARAMS,
-            ImmutableList.of(),
-            ImmutableList.of());
+            NO_FORMAT_CODES,
+            NO_FORMAT_CODES);
 
     assertFalse(intermediateStatement.isExecuted());
     assertEquals("CREATE", intermediateStatement.getCommand());
@@ -285,8 +285,8 @@ public class StatementTest {
             new IntermediatePreparedStatement(
                 connectionHandler, options, "", NO_PARAMETER_TYPES, parse(sql), Statement.of(sql)),
             NO_PARAMS,
-            ImmutableList.of(),
-            ImmutableList.of());
+            NO_FORMAT_CODES,
+            NO_FORMAT_CODES);
     BackendConnection backendConnection =
         new BackendConnection(
             NOOP_OTEL,
@@ -358,7 +358,7 @@ public class StatementTest {
     byte[][] parameters = {"userName".getBytes(), "20".getBytes(), "30".getBytes()};
     IntermediatePortalStatement intermediatePortalStatement =
         intermediateStatement.createPortal(
-            "", parameters, Arrays.asList((short) 0, (short) 0, (short) 0), new ArrayList<>());
+            "", parameters, new short[] {(short) 0, (short) 0, (short) 0}, NO_FORMAT_CODES);
     intermediatePortalStatement.bind(Statement.of(sqlStatement));
     intermediatePortalStatement.executeAsync(backendConnection);
     backendConnection.flush();
@@ -397,7 +397,7 @@ public class StatementTest {
     byte[][] parameters = {"{}".getBytes()};
 
     IntermediatePortalStatement portalStatement =
-        intermediateStatement.createPortal("", parameters, new ArrayList<>(), new ArrayList<>());
+        intermediateStatement.createPortal("", parameters, NO_FORMAT_CODES, NO_FORMAT_CODES);
     Statement boundStatement = portalStatement.bind(Statement.of(sqlStatement));
     assertEquals(
         Value.untyped(com.google.protobuf.Value.newBuilder().setStringValue("{}").build()),
@@ -441,8 +441,8 @@ public class StatementTest {
                 parse(sqlStatement),
                 Statement.of(sqlStatement)),
             NO_PARAMS,
-            ImmutableList.of(),
-            ImmutableList.of());
+            NO_FORMAT_CODES,
+            NO_FORMAT_CODES);
     BackendConnection backendConnection =
         new BackendConnection(
             NOOP_OTEL,
@@ -592,8 +592,8 @@ public class StatementTest {
             new IntermediatePreparedStatement(
                 connectionHandler, options, "", NO_PARAMETER_TYPES, parse(sql), Statement.of(sql)),
             NO_PARAMS,
-            ImmutableList.of(),
-            ImmutableList.of());
+            NO_FORMAT_CODES,
+            NO_FORMAT_CODES);
     BackendConnection backendConnection =
         new BackendConnection(
             NOOP_OTEL,
diff --git a/src/test/java/com/google/cloud/spanner/pgadapter/wireprotocol/ProtocolTest.java b/src/test/java/com/google/cloud/spanner/pgadapter/wireprotocol/ProtocolTest.java
index 7a7f4505..273145ad 100644
--- a/src/test/java/com/google/cloud/spanner/pgadapter/wireprotocol/ProtocolTest.java
+++ b/src/test/java/com/google/cloud/spanner/pgadapter/wireprotocol/ProtocolTest.java
@@ -14,6 +14,7 @@
 
 package com.google.cloud.spanner.pgadapter.wireprotocol;
 
+import static com.google.cloud.spanner.pgadapter.statements.IntermediatePortalStatement.NO_FORMAT_CODES;
 import static com.google.cloud.spanner.pgadapter.wireprotocol.ControlMessage.MAX_INVALID_MESSAGE_COUNT;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
@@ -72,11 +73,7 @@ import java.io.DataOutputStream;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.time.ZoneId;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 import org.junit.Rule;
@@ -632,7 +629,7 @@ public class ProtocolTest {
         .thenReturn(intermediatePreparedStatement);
 
     byte[][] expectedParameters = {parameter};
-    List<Short> expectedFormatCodes = new ArrayList<>();
+    short[] expectedFormatCodes = NO_FORMAT_CODES;
     String expectedPortalName = "some portal";
     String expectedStatementName = "some statement";
 
@@ -651,8 +648,8 @@ public class ProtocolTest {
     assertEquals(expectedPortalName, ((BindMessage) message).getPortalName());
     assertEquals(expectedStatementName, ((BindMessage) message).getStatementName());
     assertArrayEquals(expectedParameters, ((BindMessage) message).getParameters());
-    assertEquals(expectedFormatCodes, ((BindMessage) message).getFormatCodes());
-    assertEquals(expectedFormatCodes, ((BindMessage) message).getResultFormatCodes());
+    assertArrayEquals(expectedFormatCodes, ((BindMessage) message).getFormatCodes());
+    assertArrayEquals(expectedFormatCodes, ((BindMessage) message).getResultFormatCodes());
     assertEquals("select * from foo", ((BindMessage) message).getSql());
     assertTrue(((BindMessage) message).hasParameterValues());
 
@@ -716,8 +713,8 @@ public class ProtocolTest {
             resultCodes);
 
     byte[][] expectedParameters = {firstParameter, secondParameter};
-    List<Short> expectedFormatCodes = Arrays.asList((short) 0, (short) 1);
-    List<Short> expectedResultFormatCodes = Collections.singletonList((short) 1);
+    short[] expectedFormatCodes = new short[] {(short) 0, (short) 1};
+    short[] expectedResultFormatCodes = new short[] {(short) 1};
     String expectedPortalName = "some portal";
     String expectedStatementName = "some statement";
 
@@ -737,8 +734,8 @@ public class ProtocolTest {
     assertEquals(expectedPortalName, ((BindMessage) message).getPortalName());
     assertEquals(expectedStatementName, ((BindMessage) message).getStatementName());
     assertArrayEquals(expectedParameters, ((BindMessage) message).getParameters());
-    assertEquals(expectedFormatCodes, ((BindMessage) message).getFormatCodes());
-    assertEquals(expectedResultFormatCodes, ((BindMessage) message).getResultFormatCodes());
+    assertArrayEquals(expectedFormatCodes, ((BindMessage) message).getFormatCodes());
+    assertArrayEquals(expectedResultFormatCodes, ((BindMessage) message).getResultFormatCodes());
   }
 
   @Test
@@ -791,8 +788,8 @@ public class ProtocolTest {
             resultCodes);
 
     byte[][] expectedParameters = {firstParameter, secondParameter};
-    List<Short> expectedFormatCodes = Collections.singletonList((short) 1);
-    List<Short> expectedResultFormatCodes = Collections.singletonList((short) 1);
+    short[] expectedFormatCodes = new short[] {(short) 1};
+    short[] expectedResultFormatCodes = new short[] {(short) 1};
     String expectedPortalName = "some portal";
     String expectedStatementName = "some statement";
 
@@ -812,8 +809,8 @@ public class ProtocolTest {
     assertEquals(expectedPortalName, ((BindMessage) message).getPortalName());
     assertEquals(expectedStatementName, ((BindMessage) message).getStatementName());
     assertArrayEquals(expectedParameters, ((BindMessage) message).getParameters());
-    assertEquals(expectedFormatCodes, ((BindMessage) message).getFormatCodes());
-    assertEquals(expectedResultFormatCodes, ((BindMessage) message).getResultFormatCodes());
+    assertArrayEquals(expectedFormatCodes, ((BindMessage) message).getFormatCodes());
+    assertArrayEquals(expectedResultFormatCodes, ((BindMessage) message).getResultFormatCodes());
   }
 
   @Test