Repository: GoogleCloudPlatform/pgadapter
Pull request #2331 (2024-09-19 01:51:00)

deps: update eclipse-temurin docker tag to v23
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| eclipse-temurin | final | major | `22-jre-alpine` -> `23-jre-alpine` |
| eclipse-temurin | final | major | `22-jre` -> `23-jre` |

---

### 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 these updates 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:eyJjcmVhdGVkSW5WZXIiOiIzOC44MC4wIiwidXBkYXRlZEluVmVyIjoiMzguODAuMCIsInRhcmdldEJyYW5jaCI6InBvc3RncmVzcWwtZGlhbGVjdCIsImxhYmVscyI6W119-->



Patch:
diff --git a/.ci/evaluate-with-psql.sh b/.ci/evaluate-with-psql.sh
index 2d0dec1a..8aa9fe24 100644
--- a/.ci/evaluate-with-psql.sh
+++ b/.ci/evaluate-with-psql.sh
@@ -86,43 +86,43 @@ diff -i -w -s .ci/e2e-result/backslash-l.txt .ci/e2e-expected/backslash-l.txt
 RETURN_CODE=$((${RETURN_CODE}||$?))
 
 echo "------Test \"-c option dml batching\"------"
-/usr/lib/postgresql/"${PSQL_VERSION}"/bin/psql -h localhost -p 4242 -d "${GOOGLE_CLOUD_DATABASE_WITH_VERSION}" -c "$(cat .ci/e2e-batching/dml-batch.txt)" > .ci/e2e-result/dml-batching.txt
+/usr/lib/postgresql/"${PSQL_VERSION}"/bin/psql -h localhost -p 4242 -d "${GOOGLE_CLOUD_DATABASE_WITH_VERSION}" --set=SHOW_ALL_RESULTS=off -c "$(cat .ci/e2e-batching/dml-batch.txt)" > .ci/e2e-result/dml-batching.txt
 diff -i -w -s .ci/e2e-result/dml-batching.txt .ci/e2e-expected/dml-batching.txt
 RETURN_CODE=$((${RETURN_CODE}||$?))
 
 echo "------Test \"-c option ddl batching\"------"
-/usr/lib/postgresql/"${PSQL_VERSION}"/bin/psql -h localhost -p 4242 -d "${GOOGLE_CLOUD_DATABASE_WITH_VERSION}" -c "$(cat .ci/e2e-batching/ddl-batch.txt)"
+/usr/lib/postgresql/"${PSQL_VERSION}"/bin/psql -h localhost -p 4242 -d "${GOOGLE_CLOUD_DATABASE_WITH_VERSION}" --set=SHOW_ALL_RESULTS=off -c "$(cat .ci/e2e-batching/ddl-batch.txt)"
 echo "\d" | /usr/lib/postgresql/"${PSQL_VERSION}"/bin/psql -h localhost -p 4242 -d "${GOOGLE_CLOUD_DATABASE_WITH_VERSION}" > .ci/e2e-result/ddl-batching.txt
 diff -i -w -s .ci/e2e-result/ddl-batching.txt .ci/e2e-expected/ddl-batching.txt
 RETURN_CODE=$((${RETURN_CODE}||$?))
 
 echo "------Test \"-c option ddl-dml mix batching\"------"
-/usr/lib/postgresql/"${PSQL_VERSION}"/bin/psql -h localhost -p 4242 -d "${GOOGLE_CLOUD_DATABASE_WITH_VERSION}" -c "$(cat .ci/e2e-batching/ddl-dml-batch.txt)" &> .ci/e2e-result/ddl-dml-batching.txt
+/usr/lib/postgresql/"${PSQL_VERSION}"/bin/psql -h localhost -p 4242 -d "${GOOGLE_CLOUD_DATABASE_WITH_VERSION}" --set=SHOW_ALL_RESULTS=off -c "$(cat .ci/e2e-batching/ddl-dml-batch.txt)" &> .ci/e2e-result/ddl-dml-batching.txt
 diff -i -w -s .ci/e2e-result/ddl-dml-batching.txt .ci/e2e-expected/ddl-dml-batching.txt
 RETURN_CODE=$((${RETURN_CODE}||$?))
 
 echo "------Test \"-c option SELECT DML batching\"------"
-/usr/lib/postgresql/"${PSQL_VERSION}"/bin/psql -h localhost -p 4242 -d "${GOOGLE_CLOUD_DATABASE_WITH_VERSION}" -c "$(cat .ci/e2e-batching/select-dml-batch.txt)" &> .ci/e2e-result/select-dml-batching.txt
+/usr/lib/postgresql/"${PSQL_VERSION}"/bin/psql -h localhost -p 4242 -d "${GOOGLE_CLOUD_DATABASE_WITH_VERSION}" --set=SHOW_ALL_RESULTS=off -c "$(cat .ci/e2e-batching/select-dml-batch.txt)" &> .ci/e2e-result/select-dml-batching.txt
 diff -i -w -s .ci/e2e-result/select-dml-batching.txt .ci/e2e-expected/select-dml-batching.txt
 RETURN_CODE=$((${RETURN_CODE}||$?))
 
 echo "------Test \"-c option SELECT DDL batching\"------"
-/usr/lib/postgresql/"${PSQL_VERSION}"/bin/psql -h localhost -p 4242 -d "${GOOGLE_CLOUD_DATABASE_WITH_VERSION}" -c "$(cat .ci/e2e-batching/select-ddl-batch.txt)" &> .ci/e2e-result/select-ddl-batching.txt
+/usr/lib/postgresql/"${PSQL_VERSION}"/bin/psql -h localhost -p 4242 -d "${GOOGLE_CLOUD_DATABASE_WITH_VERSION}" --set=SHOW_ALL_RESULTS=off -c "$(cat .ci/e2e-batching/select-ddl-batch.txt)" &> .ci/e2e-result/select-ddl-batching.txt
 diff -i -w -s .ci/e2e-result/select-ddl-batching.txt .ci/e2e-expected/select-ddl-batching.txt
 RETURN_CODE=$((${RETURN_CODE}||$?))
 
 echo "------Test \"-c option WITH DML batching\"------"
-/usr/lib/postgresql/"${PSQL_VERSION}"/bin/psql -h localhost -p 4242 -d "${GOOGLE_CLOUD_DATABASE_WITH_VERSION}" -c "$(cat .ci/e2e-batching/with-dml-batch.txt)" &> .ci/e2e-result/with-dml-batching.txt
+/usr/lib/postgresql/"${PSQL_VERSION}"/bin/psql -h localhost -p 4242 -d "${GOOGLE_CLOUD_DATABASE_WITH_VERSION}" --set=SHOW_ALL_RESULTS=off -c "$(cat .ci/e2e-batching/with-dml-batch.txt)" &> .ci/e2e-result/with-dml-batching.txt
 diff -i -w -s .ci/e2e-result/with-dml-batching.txt .ci/e2e-expected/with-dml-batching.txt
 RETURN_CODE=$((${RETURN_CODE}||$?))
 
 echo "------Test \"-c option begin/commit batching\"------"
-/usr/lib/postgresql/"${PSQL_VERSION}"/bin/psql -h localhost -p 4242 -d "${GOOGLE_CLOUD_DATABASE_WITH_VERSION}" -c "$(cat .ci/e2e-batching/begin-commit-batch.txt)" &> .ci/e2e-result/begin-commit-batching.txt
+/usr/lib/postgresql/"${PSQL_VERSION}"/bin/psql -h localhost -p 4242 -d "${GOOGLE_CLOUD_DATABASE_WITH_VERSION}" --set=SHOW_ALL_RESULTS=off -c "$(cat .ci/e2e-batching/begin-commit-batch.txt)" &> .ci/e2e-result/begin-commit-batching.txt
 diff -i -w -s .ci/e2e-result/begin-commit-batching.txt .ci/e2e-expected/begin-commit-batching.txt
 RETURN_CODE=$((${RETURN_CODE}||$?))
 
 echo "------Test \"COPY FROM STDIN\"------"
-/usr/lib/postgresql/"${PSQL_VERSION}"/bin/psql -h localhost -p 4242 -d "${GOOGLE_CLOUD_DATABASE_WITH_VERSION}" -c "COPY users FROM STDIN;" <<EOF
+/usr/lib/postgresql/"${PSQL_VERSION}"/bin/psql -h localhost -p 4242 -d "${GOOGLE_CLOUD_DATABASE_WITH_VERSION}" --set=SHOW_ALL_RESULTS=off -c "COPY users FROM STDIN;" <<EOF
 12	12	12
 13	13	13
 14	14	14
@@ -136,7 +136,7 @@ diff -i -w -s .ci/e2e-result/copy-from-stdin.txt .ci/e2e-expected/copy-from-stdi
 RETURN_CODE=$((${RETURN_CODE}||$?))
 
 echo "------Test \"COPY FROM STDIN in batch\"------"
-/usr/lib/postgresql/"${PSQL_VERSION}"/bin/psql -h localhost -p 4242 -d "${GOOGLE_CLOUD_DATABASE_WITH_VERSION}" -c "select 0; COPY users FROM STDIN; COPY users FROM STDIN; select 1;" <<EOF
+/usr/lib/postgresql/"${PSQL_VERSION}"/bin/psql -h localhost -p 4242 -d "${GOOGLE_CLOUD_DATABASE_WITH_VERSION}" --set=SHOW_ALL_RESULTS=off -c "select 0; COPY users FROM STDIN; COPY users FROM STDIN; select 1;" <<EOF
 18	18	18
 \.
 19	19	19
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 635eb841..ba1cd26a 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -32,7 +32,7 @@ jobs:
         distribution: 'zulu'
     - run: java -version
     - run: .ci/run-with-credentials.sh lint
-  e2e-psql-v11-v14:
+  e2e-psql-v12-v14:
     needs: [check-env]
     if: needs.check-env.outputs.has-key == 'true'
     runs-on: ubuntu-latest
@@ -43,12 +43,12 @@ jobs:
           java-version: 11
           distribution: 'zulu'
       - run: java -version
-      - name: "Install postgresql-client-11"
+      - name: "Install postgresql-client-12"
         run: |
           sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
           wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
           sudo apt-get update
-          sudo apt-get install postgresql-client-11
+          sudo apt-get install postgresql-client-12
       - id: 'auth'
         uses: google-github-actions/auth@v2
         with:
@@ -60,8 +60,8 @@ jobs:
       - name: "Install gcloud alpha component"
         run: gcloud components install alpha
       - run: .ci/run-with-credentials.sh uber-jar-build
-      - run: .ci/run-with-credentials.sh e2e-psql 11 14.1
-  e2e-psql-v12-v1-v14:
+      - run: .ci/run-with-credentials.sh e2e-psql 12 14.1
+  e2e-psql-v13-v14:
     needs: [check-env]
     if: needs.check-env.outputs.has-key == 'true'
     runs-on: ubuntu-latest
@@ -72,12 +72,12 @@ jobs:
           java-version: 11
           distribution: 'zulu'
       - run: java -version
-      - name: "Install postgresql-client-12"
+      - name: "Install postgresql-client-13"
         run: |
           sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
           wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
           sudo apt-get update
-          sudo apt-get install postgresql-client-12
+          sudo apt-get install postgresql-client-13
       - id: 'auth'
         uses: google-github-actions/auth@v2
         with:
@@ -89,8 +89,8 @@ jobs:
       - name: "Install gcloud alpha component"
         run: gcloud components install alpha
       - run: .ci/run-with-credentials.sh uber-jar-build
-      - run: .ci/run-with-credentials.sh e2e-psql 12 14.1
-  e2e-psql-v13-v14:
+      - run: .ci/run-with-credentials.sh e2e-psql 13 14.1
+  e2e-psql-v14-v14:
     needs: [check-env]
     if: needs.check-env.outputs.has-key == 'true'
     runs-on: ubuntu-latest
@@ -101,12 +101,12 @@ jobs:
           java-version: 11
           distribution: 'zulu'
       - run: java -version
-      - name: "Install postgresql-client-13"
+      - name: "Install postgresql-client-14"
         run: |
           sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
           wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
           sudo apt-get update
-          sudo apt-get install postgresql-client-13
+          sudo apt-get install postgresql-client-14
       - id: 'auth'
         uses: google-github-actions/auth@v2
         with:
@@ -118,8 +118,8 @@ jobs:
       - name: "Install gcloud alpha component"
         run: gcloud components install alpha
       - run: .ci/run-with-credentials.sh uber-jar-build
-      - run: .ci/run-with-credentials.sh e2e-psql 13 14.1
-  e2e-psql-v14-v14:
+      - run: .ci/run-with-credentials.sh e2e-psql 14 14.1
+  e2e-psql-v15-v14:
     needs: [check-env]
     if: needs.check-env.outputs.has-key == 'true'
     runs-on: ubuntu-latest
@@ -130,12 +130,12 @@ jobs:
           java-version: 11
           distribution: 'zulu'
       - run: java -version
-      - name: "Install postgresql-client-14"
+      - name: "Install postgresql-client-15"
         run: |
           sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
           wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
           sudo apt-get update
-          sudo apt-get install postgresql-client-14
+          sudo apt-get install postgresql-client-15
       - id: 'auth'
         uses: google-github-actions/auth@v2
         with:
@@ -147,4 +147,62 @@ jobs:
       - name: "Install gcloud alpha component"
         run: gcloud components install alpha
       - run: .ci/run-with-credentials.sh uber-jar-build
-      - run: .ci/run-with-credentials.sh e2e-psql 14 14.1
+      - run: .ci/run-with-credentials.sh e2e-psql 15 14.1
+  e2e-psql-v16-v14:
+    needs: [check-env]
+    if: needs.check-env.outputs.has-key == 'true'
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      - uses: actions/setup-java@v4
+        with:
+          java-version: 11
+          distribution: 'zulu'
+      - run: java -version
+      - name: "Install postgresql-client-16"
+        run: |
+          sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
+          wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
+          sudo apt-get update
+          sudo apt-get install postgresql-client-16
+      - id: 'auth'
+        uses: google-github-actions/auth@v2
+        with:
+          credentials_json: '${{ secrets.JSON_SERVICE_ACCOUNT_CREDENTIALS }}'
+      - id: 'setup-gcloud'
+        uses: google-github-actions/setup-gcloud@v2
+        with:
+          project_id: ${{ env.GOOGLE_CLOUD_PROJECT }}
+      - name: "Install gcloud alpha component"
+        run: gcloud components install alpha
+      - run: .ci/run-with-credentials.sh uber-jar-build
+      - run: .ci/run-with-credentials.sh e2e-psql 16 14.1
+  e2e-psql-v17-v14:
+    needs: [check-env]
+    if: needs.check-env.outputs.has-key == 'true'
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      - uses: actions/setup-java@v4
+        with:
+          java-version: 11
+          distribution: 'zulu'
+      - run: java -version
+      - name: "Install postgresql-client-17"
+        run: |
+          sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
+          wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
+          sudo apt-get update
+          sudo apt-get install postgresql-client-17
+      - id: 'auth'
+        uses: google-github-actions/auth@v2
+        with:
+          credentials_json: '${{ secrets.JSON_SERVICE_ACCOUNT_CREDENTIALS }}'
+      - id: 'setup-gcloud'
+        uses: google-github-actions/setup-gcloud@v2
+        with:
+          project_id: ${{ env.GOOGLE_CLOUD_PROJECT }}
+      - name: "Install gcloud alpha component"
+        run: gcloud components install alpha
+      - run: .ci/run-with-credentials.sh uber-jar-build
+      - run: .ci/run-with-credentials.sh e2e-psql 17 14.1
diff --git a/.github/workflows/samples.yaml b/.github/workflows/samples.yaml
index 87e83d99..7285d94a 100644
--- a/.github/workflows/samples.yaml
+++ b/.github/workflows/samples.yaml
@@ -18,6 +18,9 @@ jobs:
       - name: Run JDBC Sample tests
         working-directory: ./samples/java/jdbc
         run: mvn test -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
+      - name: Run R2DBC Sample tests
+        working-directory: ./samples/java/r2dbc
+        run: mvn test -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
       - name: Run Hibernate Sample tests
         working-directory: ./samples/java/hibernate
         run: mvn test -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
@@ -38,6 +41,9 @@ jobs:
       - name: Run pgx Sample tests
         working-directory: ./samples/golang/pgx
         run: go test
+      - name: Run migrate Sample tests
+        working-directory: ./samples/golang/migrate
+        run: go test
   python-samples:
     runs-on: ubuntu-latest
     steps:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fd9730e2..2088e38b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,138 @@
 # Changelog
 
+## [0.40.0](https://github.com/GoogleCloudPlatform/pgadapter/compare/v0.39.0...v0.40.0) (2024-10-16)
+
+
+### Features
+
+* support DML auto-batching ([#2427](https://github.com/GoogleCloudPlatform/pgadapter/issues/2427)) ([08fc435](https://github.com/GoogleCloudPlatform/pgadapter/commit/08fc4351be8bdf9770f2ba441dfb96fe056203eb))
+* support SHUTDOWN SQL command ([#2388](https://github.com/GoogleCloudPlatform/pgadapter/issues/2388)) ([42ff00a](https://github.com/GoogleCloudPlatform/pgadapter/commit/42ff00ac612abf76d8df30b1713eec9357e5aa73))
+
+
+### Bug Fixes
+
+* gracefully handle closed sockets and EOF ([#2374](https://github.com/GoogleCloudPlatform/pgadapter/issues/2374)) ([301ade7](https://github.com/GoogleCloudPlatform/pgadapter/commit/301ade798f7319250b8268f048f09ac50c525717)), closes [#2106](https://github.com/GoogleCloudPlatform/pgadapter/issues/2106)
+* recognize GSSENCRequest messages ([#2370](https://github.com/GoogleCloudPlatform/pgadapter/issues/2370)) ([3bea010](https://github.com/GoogleCloudPlatform/pgadapter/commit/3bea0107c8eea0719bb391e974a48e00a4335df0))
+* remove connection-id from metrics attributes ([#2384](https://github.com/GoogleCloudPlatform/pgadapter/issues/2384)) ([23cdc52](https://github.com/GoogleCloudPlatform/pgadapter/commit/23cdc521f2c50ad07908ac3b987075da4c0bd698)), closes [#2377](https://github.com/GoogleCloudPlatform/pgadapter/issues/2377)
+* support \l and \d on psql 15 ([#2379](https://github.com/GoogleCloudPlatform/pgadapter/issues/2379)) ([3ee1a67](https://github.com/GoogleCloudPlatform/pgadapter/commit/3ee1a678ab82468f51ca727bb4dd7e367a7b5e42))
+
+
+### Dependencies
+
+* update dependency com.spotify.fmt:fmt-maven-plugin to v2.25 ([#2419](https://github.com/GoogleCloudPlatform/pgadapter/issues/2419)) ([800bf01](https://github.com/GoogleCloudPlatform/pgadapter/commit/800bf01776246646faba65c24260e514dfd6ec61))
+* update dependency django to v5.1.2 ([#2425](https://github.com/GoogleCloudPlatform/pgadapter/issues/2425)) ([599c220](https://github.com/GoogleCloudPlatform/pgadapter/commit/599c220c811ac1d0498bf1aa22a5165bd014fe84))
+* update dependency go to v1.23.2 ([#2404](https://github.com/GoogleCloudPlatform/pgadapter/issues/2404)) ([279408b](https://github.com/GoogleCloudPlatform/pgadapter/commit/279408b00a92a2db5489d114ba2b755388c41a57))
+* update dependency io.hypersistence:hypersistence-utils-hibernate-63 to v3.8.3 ([#2393](https://github.com/GoogleCloudPlatform/pgadapter/issues/2393)) ([545bf7e](https://github.com/GoogleCloudPlatform/pgadapter/commit/545bf7e3e37f5718ca4c5602a906642c0a96559d))
+* update dependency io.opentelemetry:opentelemetry-bom to v1.43.0 ([#2439](https://github.com/GoogleCloudPlatform/pgadapter/issues/2439)) ([fac47d5](https://github.com/GoogleCloudPlatform/pgadapter/commit/fac47d5686c746ebc53f244233ebd571eee10c6b))
+* update dependency npgsql to 8.0.5 ([#2441](https://github.com/GoogleCloudPlatform/pgadapter/issues/2441)) ([3290c83](https://github.com/GoogleCloudPlatform/pgadapter/commit/3290c8302b4fef8adc28979f0214c5848579aaa0))
+* update dependency org.apache.commons:commons-csv to v1.12.0 ([#2375](https://github.com/GoogleCloudPlatform/pgadapter/issues/2375)) ([81b50ec](https://github.com/GoogleCloudPlatform/pgadapter/commit/81b50ece5f0e8d832d6956bac0515d13fa5b1862))
+* update dependency org.checkerframework:checker-qual to v3.48.0 ([#2412](https://github.com/GoogleCloudPlatform/pgadapter/issues/2412)) ([6737a87](https://github.com/GoogleCloudPlatform/pgadapter/commit/6737a8716be6081bcffdeee9a2c3590c202c7d91))
+* update dependency org.checkerframework:checker-qual to v3.48.1 ([#2438](https://github.com/GoogleCloudPlatform/pgadapter/issues/2438)) ([048c365](https://github.com/GoogleCloudPlatform/pgadapter/commit/048c3652b6ee354c58cf20947cb65d80aa963370))
+* update dependency org.postgresql:r2dbc-postgresql to v1.0.6.release ([#2424](https://github.com/GoogleCloudPlatform/pgadapter/issues/2424)) ([0865571](https://github.com/GoogleCloudPlatform/pgadapter/commit/0865571dde680277bb14bd162771b20f5da00ea0))
+* update dependency org.testcontainers:testcontainers to v1.20.2 ([#2397](https://github.com/GoogleCloudPlatform/pgadapter/issues/2397)) ([eff0ee4](https://github.com/GoogleCloudPlatform/pgadapter/commit/eff0ee40ad8bad9e2e8729ddbe05b5992375c3e1))
+* update dependency org.testcontainers:testcontainers-bom to v1.20.2 ([#2398](https://github.com/GoogleCloudPlatform/pgadapter/issues/2398)) ([8827410](https://github.com/GoogleCloudPlatform/pgadapter/commit/8827410684d2c337a946f16e8d0de0f8ddc63b55))
+* update dependency psycopg to v3.2.3 ([#2389](https://github.com/GoogleCloudPlatform/pgadapter/issues/2389)) ([6c547cf](https://github.com/GoogleCloudPlatform/pgadapter/commit/6c547cf298518ed6f61ec12a0d6920089988d3d0))
+* update dependency psycopg-binary to v3.2.3 ([#2390](https://github.com/GoogleCloudPlatform/pgadapter/issues/2390)) ([4fa32ff](https://github.com/GoogleCloudPlatform/pgadapter/commit/4fa32ffce5a3263acca3215b74fa8bd54e59c3f2))
+* update dependency sqlalchemy to v2.0.36 ([#2449](https://github.com/GoogleCloudPlatform/pgadapter/issues/2449)) ([2326401](https://github.com/GoogleCloudPlatform/pgadapter/commit/2326401e2ba7ca7708565f9362e025f77a1c59b0))
+* update dependency testcontainers to v4.8.2 ([#2442](https://github.com/GoogleCloudPlatform/pgadapter/issues/2442)) ([98c9f2b](https://github.com/GoogleCloudPlatform/pgadapter/commit/98c9f2b9d0b8d36b9b96273f95c661d51b280864))
+* update dependency typescript to v5.6.3 ([#2428](https://github.com/GoogleCloudPlatform/pgadapter/issues/2428)) ([a4c3a97](https://github.com/GoogleCloudPlatform/pgadapter/commit/a4c3a97ba9829e3cf184ebcb516a3b0ca7daf80d))
+* update golang docker tag to v1.23.2 ([#2406](https://github.com/GoogleCloudPlatform/pgadapter/issues/2406)) ([12f52c7](https://github.com/GoogleCloudPlatform/pgadapter/commit/12f52c7b019be1d096ad091d4cef87a976cc9eaa))
+* update junixsocket.version to v2.10.1 ([#2366](https://github.com/GoogleCloudPlatform/pgadapter/issues/2366)) ([a06cd11](https://github.com/GoogleCloudPlatform/pgadapter/commit/a06cd1177a72a6ca937853290d8ef97755751689))
+* update module cloud.google.com/go/spanner to v1.68.0 ([#2376](https://github.com/GoogleCloudPlatform/pgadapter/issues/2376)) ([c06a32c](https://github.com/GoogleCloudPlatform/pgadapter/commit/c06a32c32489f1855bd538f5073296a6331c0fe3))
+* update module cloud.google.com/go/spanner to v1.69.0 ([#2417](https://github.com/GoogleCloudPlatform/pgadapter/issues/2417)) ([7ef276d](https://github.com/GoogleCloudPlatform/pgadapter/commit/7ef276d2f123c6c37fcaa4a010860e41fa1c394f))
+* update module cloud.google.com/go/spanner to v1.70.0 ([#2443](https://github.com/GoogleCloudPlatform/pgadapter/issues/2443)) ([c360542](https://github.com/GoogleCloudPlatform/pgadapter/commit/c36054260d99e886452ac9f9728636ea1057b066))
+* update module google.golang.org/api to v0.199.0 ([#2378](https://github.com/GoogleCloudPlatform/pgadapter/issues/2378)) ([55d17bb](https://github.com/GoogleCloudPlatform/pgadapter/commit/55d17bb0db2dcdb22d808d303279482c51bd2fc9))
+* update module google.golang.org/api to v0.200.0 ([#2440](https://github.com/GoogleCloudPlatform/pgadapter/issues/2440)) ([6f73943](https://github.com/GoogleCloudPlatform/pgadapter/commit/6f7394379b0bce3a6f26547becc5dfba341c537e))
+* update module google.golang.org/api to v0.201.0 ([#2448](https://github.com/GoogleCloudPlatform/pgadapter/issues/2448)) ([97c2c19](https://github.com/GoogleCloudPlatform/pgadapter/commit/97c2c19c89eb6b022c3e87b6c467123ae351c9bc))
+* update opentelemetry.exporter.version to v0.32.0 ([#2369](https://github.com/GoogleCloudPlatform/pgadapter/issues/2369)) ([9787ca4](https://github.com/GoogleCloudPlatform/pgadapter/commit/9787ca4cd21573491b57df039a45c6fced0b0b61))
+* update python docker tag to v3.13 ([#2423](https://github.com/GoogleCloudPlatform/pgadapter/issues/2423)) ([9d01d99](https://github.com/GoogleCloudPlatform/pgadapter/commit/9d01d9919355d9d1ee665d0bec52803d6737f244))
+
+
+### Documentation
+
+* add sample for R2DBC ([#2413](https://github.com/GoogleCloudPlatform/pgadapter/issues/2413)) ([83013a4](https://github.com/GoogleCloudPlatform/pgadapter/commit/83013a4e9517cec853dab9814f96e5ebb1c13e6d))
+* add sample for using Batch DML with Spring Data JPA ([#2357](https://github.com/GoogleCloudPlatform/pgadapter/issues/2357)) ([65d82d8](https://github.com/GoogleCloudPlatform/pgadapter/commit/65d82d8e1ffcc57a5dc3b2ffc043194e174c4a6b))
+
+## [0.39.0](https://github.com/GoogleCloudPlatform/pgadapter/compare/v0.38.0...v0.39.0) (2024-09-21)
+
+
+### Features
+
+* add session variable for batch_dml_update_count ([#2356](https://github.com/GoogleCloudPlatform/pgadapter/issues/2356)) ([345bd4d](https://github.com/GoogleCloudPlatform/pgadapter/commit/345bd4d15478acb27d80003bfb65028a4dd719d5))
+
+
+### Dependencies
+
+* update dependency @types/node to v22 ([#2221](https://github.com/GoogleCloudPlatform/pgadapter/issues/2221)) ([4a8e167](https://github.com/GoogleCloudPlatform/pgadapter/commit/4a8e167c851d290d3028a3880d03da14058224f5))
+* update dependency google.auth to v2.35.0 ([#2347](https://github.com/GoogleCloudPlatform/pgadapter/issues/2347)) ([abe4e24](https://github.com/GoogleCloudPlatform/pgadapter/commit/abe4e242a7ae5b00209056d650eb934f6eab9546))
+* update dependency org.springframework.boot:spring-boot-dependencies to v3.3.4 ([#2334](https://github.com/GoogleCloudPlatform/pgadapter/issues/2334)) ([5632ffa](https://github.com/GoogleCloudPlatform/pgadapter/commit/5632ffad810cc36647376e35c8d477dc98b68acb))
+* update dependency org.springframework.boot:spring-boot-starter-parent to v3.3.4 ([#2335](https://github.com/GoogleCloudPlatform/pgadapter/issues/2335)) ([f28b88f](https://github.com/GoogleCloudPlatform/pgadapter/commit/f28b88f8d9fc33d874bd3dab12a4f8904f4b49d2))
+* update dependency pandas to v2.2.3 ([#2360](https://github.com/GoogleCloudPlatform/pgadapter/issues/2360)) ([b334628](https://github.com/GoogleCloudPlatform/pgadapter/commit/b334628f548c77ea09e59fa0ce2ccabe7c7c6978))
+* update github.com/googlecloudplatform/pgadapter/wrappers/golang digest to c310ce8 ([#2307](https://github.com/GoogleCloudPlatform/pgadapter/issues/2307)) ([d5c5051](https://github.com/GoogleCloudPlatform/pgadapter/commit/d5c5051ec68be5a0a94995bbcb6c8a304201e0f4))
+* update module github.com/docker/docker to v27.3.1+incompatible ([#2349](https://github.com/GoogleCloudPlatform/pgadapter/issues/2349)) ([9abe8d1](https://github.com/GoogleCloudPlatform/pgadapter/commit/9abe8d16dc3d84ef568bb907a30c624d7661234f))
+* update module google.golang.org/api to v0.198.0 ([#2346](https://github.com/GoogleCloudPlatform/pgadapter/issues/2346)) ([d421108](https://github.com/GoogleCloudPlatform/pgadapter/commit/d4211082a3551f96365296458ece8a550eddac52))
+* update spring-boot.version to v3.3.4 ([#2337](https://github.com/GoogleCloudPlatform/pgadapter/issues/2337)) ([6f1a517](https://github.com/GoogleCloudPlatform/pgadapter/commit/6f1a517454f78b416f1b9306e4c555789df03488))
+
+## [0.38.0](https://github.com/GoogleCloudPlatform/pgadapter/compare/v0.37.0...v0.38.0) (2024-09-19)
+
+
+### Features
+
+* add sample for the Go migrate tool ([#2329](https://github.com/GoogleCloudPlatform/pgadapter/issues/2329)) ([d5bcdbf](https://github.com/GoogleCloudPlatform/pgadapter/commit/d5bcdbf237543073657adfcccee508adbb5aef47))
+* register signal handlers for graceful shutdown ([#2079](https://github.com/GoogleCloudPlatform/pgadapter/issues/2079)) ([998161b](https://github.com/GoogleCloudPlatform/pgadapter/commit/998161b64e8500073514677c3b9f00b8c7a53455))
+
+
+### Bug Fixes
+
+* do not overwrite existing Docker config for Go wrapper ([#2251](https://github.com/GoogleCloudPlatform/pgadapter/issues/2251)) ([94e9684](https://github.com/GoogleCloudPlatform/pgadapter/commit/94e968467df838c4b64c58b593db9d0c8858578f))
+* wait for all connections to close before stopping ([#2304](https://github.com/GoogleCloudPlatform/pgadapter/issues/2304)) ([5567b46](https://github.com/GoogleCloudPlatform/pgadapter/commit/5567b46e3b743f1821855e4b04c456ec599181ab))
+
+
+### Dependencies
+
+* remove go toolchain directives ([#2166](https://github.com/GoogleCloudPlatform/pgadapter/issues/2166)) ([8bafddb](https://github.com/GoogleCloudPlatform/pgadapter/commit/8bafddbdd219cf0e75a8cc15c4a91f17bc1def57))
+* update alpine docker tag to v3.20.3 ([#2277](https://github.com/GoogleCloudPlatform/pgadapter/issues/2277)) ([506b61d](https://github.com/GoogleCloudPlatform/pgadapter/commit/506b61d81bcd63bf4ea85ca4345ca7ae937816e9))
+* update dependency django to v5.1.1 ([#2256](https://github.com/GoogleCloudPlatform/pgadapter/issues/2256)) ([c332de4](https://github.com/GoogleCloudPlatform/pgadapter/commit/c332de4a784211249ae4220604f4152d9f449a91))
+* update dependency io.opentelemetry:opentelemetry-bom to v1.42.1 ([#2276](https://github.com/GoogleCloudPlatform/pgadapter/issues/2276)) ([7409477](https://github.com/GoogleCloudPlatform/pgadapter/commit/7409477c4759fa179701a9026b38a18d0717384d))
+* update dependency microsoft.net.test.sdk to 17.11.1 ([#2268](https://github.com/GoogleCloudPlatform/pgadapter/issues/2268)) ([1f22a9f](https://github.com/GoogleCloudPlatform/pgadapter/commit/1f22a9fab7eff42a78d9586fe851bb9b615e6383))
+* update dependency net.java.dev.jna:jna to v5.15.0 ([#2312](https://github.com/GoogleCloudPlatform/pgadapter/issues/2312)) ([9aa4a00](https://github.com/GoogleCloudPlatform/pgadapter/commit/9aa4a008be2d4740377b2a5849bc843a2451677a))
+* update dependency npgsql to 8.0.4 ([#2297](https://github.com/GoogleCloudPlatform/pgadapter/issues/2297)) ([fdc4b11](https://github.com/GoogleCloudPlatform/pgadapter/commit/fdc4b1105f6e429eb1211d7ddb0c7d56b0b41423))
+* update dependency nunit to 4.2.2 ([#2250](https://github.com/GoogleCloudPlatform/pgadapter/issues/2250)) ([f48b1d1](https://github.com/GoogleCloudPlatform/pgadapter/commit/f48b1d1a2f55846c198c3ddbc59362e9acd27054))
+* update dependency org.checkerframework:checker-qual to v3.47.0 ([#2266](https://github.com/GoogleCloudPlatform/pgadapter/issues/2266)) ([56599d5](https://github.com/GoogleCloudPlatform/pgadapter/commit/56599d51198e45a62b80ea1ebd4da0e8272972a0))
+* update dependency org.hibernate.orm:hibernate-core to v6.6.1.final ([#2321](https://github.com/GoogleCloudPlatform/pgadapter/issues/2321)) ([d1bfa9b](https://github.com/GoogleCloudPlatform/pgadapter/commit/d1bfa9b30a9035806244f00954d8611ca1f11b8d))
+* update dependency psycopg to v3.2.2 ([#2313](https://github.com/GoogleCloudPlatform/pgadapter/issues/2313)) ([c16cbe7](https://github.com/GoogleCloudPlatform/pgadapter/commit/c16cbe76ddd27fa53fb3c23e0bc323363824ff06))
+* update dependency psycopg-binary to v3.2.2 ([#2314](https://github.com/GoogleCloudPlatform/pgadapter/issues/2314)) ([c1d0258](https://github.com/GoogleCloudPlatform/pgadapter/commit/c1d02583ce98252340d95d30e067f393e05e4406))
+* update dependency pytz to v2024.2 ([#2299](https://github.com/GoogleCloudPlatform/pgadapter/issues/2299)) ([4d4594d](https://github.com/GoogleCloudPlatform/pgadapter/commit/4d4594d1c3707d5d75ad6b6fff28981018566621))
+* update dependency sqlalchemy to v1.4.54 ([#2272](https://github.com/GoogleCloudPlatform/pgadapter/issues/2272)) ([12d235a](https://github.com/GoogleCloudPlatform/pgadapter/commit/12d235aa2eae80b73e3e9fb9d7b92742f10aab8a))
+* update dependency sqlalchemy to v2.0.34 ([#2259](https://github.com/GoogleCloudPlatform/pgadapter/issues/2259)) ([cf538cf](https://github.com/GoogleCloudPlatform/pgadapter/commit/cf538cf59f5aee2c3ed6e9a3cf83b5ec746b4aa8))
+* update dependency sqlalchemy to v2.0.35 ([#2320](https://github.com/GoogleCloudPlatform/pgadapter/issues/2320)) ([a4dc926](https://github.com/GoogleCloudPlatform/pgadapter/commit/a4dc9268921fcb777e9fa31790f625f60ac26927))
+* update dependency testcontainers to 3.10.0 ([#2258](https://github.com/GoogleCloudPlatform/pgadapter/issues/2258)) ([bb687ac](https://github.com/GoogleCloudPlatform/pgadapter/commit/bb687acb79c61f24a1a4f1a23471233a2dd60203))
+* update dependency testcontainers to v4.8.1 ([#2255](https://github.com/GoogleCloudPlatform/pgadapter/issues/2255)) ([e65c983](https://github.com/GoogleCloudPlatform/pgadapter/commit/e65c983a37440d9a186091377203df341d248bf8))
+* update dependency typescript to v5.6.2 ([#2287](https://github.com/GoogleCloudPlatform/pgadapter/issues/2287)) ([bb99dcf](https://github.com/GoogleCloudPlatform/pgadapter/commit/bb99dcfbc01db09e29e5533f2320e2781c9ec6fb))
+* update github.com/googlecloudplatform/pgadapter/wrappers/golang digest to 5a517d5 ([#2261](https://github.com/GoogleCloudPlatform/pgadapter/issues/2261)) ([c14b730](https://github.com/GoogleCloudPlatform/pgadapter/commit/c14b7300192fb4bbec6e8cdc8d19574046dace99))
+* update github.com/googlecloudplatform/pgadapter/wrappers/golang digest to 8e4420f ([#2262](https://github.com/GoogleCloudPlatform/pgadapter/issues/2262)) ([ca6ac9a](https://github.com/GoogleCloudPlatform/pgadapter/commit/ca6ac9a2e781adb59a5cb600f6302c143caae200))
+* update github.com/googlecloudplatform/pgadapter/wrappers/golang digest to 94e9684 ([#1967](https://github.com/GoogleCloudPlatform/pgadapter/issues/1967)) ([5a517d5](https://github.com/GoogleCloudPlatform/pgadapter/commit/5a517d5836d1e7ae2ae6ee7074eff08e8e14d8e5))
+* update github.com/googlecloudplatform/pgadapter/wrappers/golang digest to c756559 ([#2274](https://github.com/GoogleCloudPlatform/pgadapter/issues/2274)) ([48ceab8](https://github.com/GoogleCloudPlatform/pgadapter/commit/48ceab878b5967809036096b544c11878f6f774d))
+* update golang docker tag ([#2167](https://github.com/GoogleCloudPlatform/pgadapter/issues/2167)) ([086e59b](https://github.com/GoogleCloudPlatform/pgadapter/commit/086e59bdeb1b7b9116e4aa0a49c34d0b1d4ff764))
+* update golang docker tag to v1.23.1 ([#2273](https://github.com/GoogleCloudPlatform/pgadapter/issues/2273)) ([8efb4eb](https://github.com/GoogleCloudPlatform/pgadapter/commit/8efb4ebcf2f19492ab58df32a5dd94086488824f))
+* update module github.com/docker/docker to v27.2.0+incompatible ([#2238](https://github.com/GoogleCloudPlatform/pgadapter/issues/2238)) ([0411eea](https://github.com/GoogleCloudPlatform/pgadapter/commit/0411eea853bc7067b8157e2ccfa55b381b6ca286))
+* update module github.com/docker/docker to v27.2.1+incompatible ([#2281](https://github.com/GoogleCloudPlatform/pgadapter/issues/2281)) ([f778b36](https://github.com/GoogleCloudPlatform/pgadapter/commit/f778b3660759c7af290f26021c2c71331d4e8899))
+* update module github.com/jackc/pgx/v5 to v5.7.1 ([#2278](https://github.com/GoogleCloudPlatform/pgadapter/issues/2278)) ([203b427](https://github.com/GoogleCloudPlatform/pgadapter/commit/203b42762b701fb464f2fc99bf9273db0e8b878e))
+* update module golang.org/x/oauth2 to v0.23.0 ([#2264](https://github.com/GoogleCloudPlatform/pgadapter/issues/2264)) ([31ba4b5](https://github.com/GoogleCloudPlatform/pgadapter/commit/31ba4b57cdb64a157091c382128ec9d751202b4a))
+* update module google.golang.org/api to v0.195.0 ([#2243](https://github.com/GoogleCloudPlatform/pgadapter/issues/2243)) ([36b43b8](https://github.com/GoogleCloudPlatform/pgadapter/commit/36b43b8a1a52bea480d8c142a7a02f9233d218aa))
+* update module google.golang.org/api to v0.196.0 ([#2260](https://github.com/GoogleCloudPlatform/pgadapter/issues/2260)) ([c820849](https://github.com/GoogleCloudPlatform/pgadapter/commit/c82084987eeba440a070bb44604377c4eac4470d))
+* update module google.golang.org/api to v0.197.0 ([#2301](https://github.com/GoogleCloudPlatform/pgadapter/issues/2301)) ([62359ae](https://github.com/GoogleCloudPlatform/pgadapter/commit/62359ae59c1534b7c752e61ad216fc656c699ea8))
+* update module gorm.io/gorm to v1.25.12 ([#2282](https://github.com/GoogleCloudPlatform/pgadapter/issues/2282)) ([218f57a](https://github.com/GoogleCloudPlatform/pgadapter/commit/218f57ac2921f72e27ec11aef09a8088e9902856))
+
+
+### Documentation
+
+* add insert-or-update sample for Sequelize ([#2253](https://github.com/GoogleCloudPlatform/pgadapter/issues/2253)) ([142288c](https://github.com/GoogleCloudPlatform/pgadapter/commit/142288cd96398169f9a908185ce2a699a9dd0f04))
+* add insert-or-update sample for SQLAlchemy 2 ([#2254](https://github.com/GoogleCloudPlatform/pgadapter/issues/2254)) ([53f27e8](https://github.com/GoogleCloudPlatform/pgadapter/commit/53f27e8fc1f2825088d0dfca42000276f42c5c0c))
+* add sample for insert-or-update for Knex.js ([#2252](https://github.com/GoogleCloudPlatform/pgadapter/issues/2252)) ([aca89cb](https://github.com/GoogleCloudPlatform/pgadapter/commit/aca89cb013f5e130bb70dfaa7cec517788f01b2b))
+* add sample for using OnConflict in gorm ([#2247](https://github.com/GoogleCloudPlatform/pgadapter/issues/2247)) ([1f0c25f](https://github.com/GoogleCloudPlatform/pgadapter/commit/1f0c25f45cff994f424f567f5ecb38971f10f4e2))
+* run Spring Data JPA sample on the Emulator ([#2245](https://github.com/GoogleCloudPlatform/pgadapter/issues/2245)) ([6ef07b4](https://github.com/GoogleCloudPlatform/pgadapter/commit/6ef07b40248ee6b03d5c6328d60ba5d94134765b))
+
 ## [0.37.0](https://github.com/GoogleCloudPlatform/pgadapter/compare/v0.36.1...v0.37.0) (2024-08-27)
 
 
diff --git a/README.md b/README.md
index 3b5ccf23..a1967126 100644
--- a/README.md
+++ b/README.md
@@ -115,9 +115,9 @@ Use the `-s` option to specify a different local port than the default 5432 if y
 PostgreSQL running on your local system.
 
 <!--- {x-version-update-start:google-cloud-spanner-pgadapter:released} -->
-You can also download a specific version of the jar. Example (replace `v0.37.0` with the version you want to download):
+You can also download a specific version of the jar. Example (replace `v0.40.0` with the version you want to download):
 ```shell
-VERSION=v0.37.0
+VERSION=v0.40.0
 wget https://storage.googleapis.com/pgadapter-jar-releases/pgadapter-${VERSION}.tar.gz \
   && tar -xzvf pgadapter-${VERSION}.tar.gz
 java -jar pgadapter.jar -p my-project -i my-instance -d my-database
@@ -152,7 +152,7 @@ This option is only available for Java/JVM-based applications.
 <dependency>
   <groupId>com.google.cloud</groupId>
   <artifactId>google-cloud-spanner-pgadapter</artifactId>
-  <version>0.37.0</version>
+  <version>0.40.0</version>
 </dependency>
 <!-- [END pgadapter_dependency] -->
 ```
@@ -271,6 +271,17 @@ The following list contains the most frequently used startup options for PGAdapt
     Use the -x switch to turn off the localhost check. This is required when running PGAdapter in a
     Docker container, as the connections from the host machine will not be seen as a connection from
     localhost in the container.
+
+--allow_shutdown_command
+  * Enables the use of the custom SQL command `SHUTDOWN [SMART | FAST | IMMEDIATE]`. This command can
+    be used to shut down PGAdapter by just sending it a SQL statement. This option should only be enabled
+    when PGAdapter runs in a trusted environment, for example as a side-car container. The default
+    shutdown mode is `FAST`, which terminates all existing connections and then shuts down PGAdapter.
+    Use shutdown mode `SMART` to instruct PGAdapter to wait until all existing connections have been
+    terminated by the client before shutting down. See also https://www.postgresql.org/docs/current/server-shutdown.html
+    for more information about shutdown modes.
+  * Note that `SHUTDOWN [SMART | FAST | IMMEDIATE]` only works on PGAdapter. This command is not
+    supported by PostgreSQL.
 ```
 
 * See [command line arguments](docs/command_line_arguments.md) for a list of all supported arguments.
diff --git a/benchmarks/latency-comparison/golang/go.mod b/benchmarks/latency-comparison/golang/go.mod
index e04e4b23..8fb4974c 100644
--- a/benchmarks/latency-comparison/golang/go.mod
+++ b/benchmarks/latency-comparison/golang/go.mod
@@ -1,43 +1,48 @@
 module cloud.google.com/pgadapter-latency-benchmark
 
-go 1.21
+go 1.22
+
+toolchain go1.23.2
 
 require (
-	cloud.google.com/go/spanner v1.67.0
-	github.com/docker/docker v27.2.1+incompatible
+	cloud.google.com/go/spanner v1.70.0
+	github.com/docker/docker v27.3.1+incompatible
 	github.com/jackc/pgx/v4 v4.18.3
 	github.com/jackc/pgx/v5 v5.7.1
 	github.com/montanaflynn/stats v0.7.0
-	github.com/testcontainers/testcontainers-go v0.33.0
+	github.com/testcontainers/testcontainers-go v0.34.0
 	golang.org/x/oauth2 v0.23.0
-	google.golang.org/api v0.197.0
+	google.golang.org/api v0.204.0
 )
 
 require (
-	cel.dev/expr v0.15.0 // indirect
-	cloud.google.com/go v0.115.1 // indirect
-	cloud.google.com/go/auth v0.9.3 // indirect
-	cloud.google.com/go/auth/oauth2adapt v0.2.4 // indirect
-	cloud.google.com/go/compute/metadata v0.5.0 // indirect
+	cel.dev/expr v0.16.0 // indirect
+	cloud.google.com/go v0.116.0 // indirect
+	cloud.google.com/go/auth v0.10.0 // indirect
+	cloud.google.com/go/auth/oauth2adapt v0.2.5 // indirect
+	cloud.google.com/go/compute/metadata v0.5.2 // indirect
+	cloud.google.com/go/monitoring v1.21.1 // indirect
 	dario.cat/mergo v1.0.0 // indirect
 	github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
 	github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.0 // indirect
+	github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.24.1 // indirect
 	github.com/Microsoft/go-winio v0.6.2 // indirect
 	github.com/Microsoft/hcsshim v0.11.5 // indirect
 	github.com/cenkalti/backoff/v4 v4.2.1 // indirect
 	github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
 	github.com/cespare/xxhash/v2 v2.3.0 // indirect
-	github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b // indirect
+	github.com/cncf/xds/go v0.0.0-20240822171458-6449f94b4d59 // indirect
 	github.com/containerd/containerd v1.7.18 // indirect
 	github.com/containerd/errdefs v0.1.0 // indirect
 	github.com/containerd/log v0.1.0 // indirect
 	github.com/containerd/platforms v0.2.1 // indirect
-	github.com/cpuguy83/dockercfg v0.3.1 // indirect
+	github.com/cpuguy83/dockercfg v0.3.2 // indirect
+	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/distribution/reference v0.6.0 // indirect
 	github.com/docker/go-connections v0.5.0 // indirect
 	github.com/docker/go-units v0.5.0 // indirect
-	github.com/envoyproxy/go-control-plane v0.12.1-0.20240621013728-1eb8caab5155 // indirect
-	github.com/envoyproxy/protoc-gen-validate v1.0.4 // indirect
+	github.com/envoyproxy/go-control-plane v0.13.0 // indirect
+	github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
 	github.com/felixge/httpsnoop v1.0.4 // indirect
 	github.com/go-logr/logr v1.4.2 // indirect
 	github.com/go-logr/stdr v1.2.2 // indirect
@@ -70,28 +75,35 @@ require (
 	github.com/opencontainers/image-spec v1.1.0 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
 	github.com/shirou/gopsutil/v3 v3.23.12 // indirect
 	github.com/shoenig/go-m1cpu v0.1.6 // indirect
 	github.com/sirupsen/logrus v1.9.3 // indirect
+	github.com/stretchr/testify v1.9.0 // indirect
 	github.com/tklauser/go-sysconf v0.3.12 // indirect
 	github.com/tklauser/numcpus v0.6.1 // indirect
 	github.com/yusufpapurcu/wmi v1.2.3 // indirect
 	go.opencensus.io v0.24.0 // indirect
+	go.opentelemetry.io/contrib/detectors/gcp v1.29.0 // indirect
 	go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect
 	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
 	go.opentelemetry.io/otel v1.29.0 // indirect
 	go.opentelemetry.io/otel/metric v1.29.0 // indirect
+	go.opentelemetry.io/otel/sdk v1.29.0 // indirect
+	go.opentelemetry.io/otel/sdk/metric v1.29.0 // indirect
 	go.opentelemetry.io/otel/trace v1.29.0 // indirect
-	golang.org/x/crypto v0.27.0 // indirect
-	golang.org/x/net v0.29.0 // indirect
+	golang.org/x/crypto v0.28.0 // indirect
+	golang.org/x/net v0.30.0 // indirect
 	golang.org/x/sync v0.8.0 // indirect
-	golang.org/x/sys v0.25.0 // indirect
-	golang.org/x/text v0.18.0 // indirect
-	golang.org/x/time v0.6.0 // indirect
+	golang.org/x/sys v0.26.0 // indirect
+	golang.org/x/text v0.19.0 // indirect
+	golang.org/x/time v0.7.0 // indirect
 	golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect
-	google.golang.org/genproto/googleapis/api v0.0.0-20240725223205-93522f1f2a9f // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
-	google.golang.org/grpc v1.66.1 // indirect
-	google.golang.org/protobuf v1.34.2 // indirect
+	google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 // indirect
+	google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 // indirect
+	google.golang.org/grpc v1.67.1 // indirect
+	google.golang.org/protobuf v1.35.1 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
diff --git a/benchmarks/latency-comparison/golang/go.sum b/benchmarks/latency-comparison/golang/go.sum
index 81ec651c..b7e8e7f5 100644
--- a/benchmarks/latency-comparison/golang/go.sum
+++ b/benchmarks/latency-comparison/golang/go.sum
@@ -1,5 +1,7 @@
 cel.dev/expr v0.15.0 h1:O1jzfJCQBfL5BFoYktaxwIhuttaQPsVWerH9/EEKx0w=
 cel.dev/expr v0.15.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg=
+cel.dev/expr v0.16.0 h1:yloc84fytn4zmJX2GU3TkXGsaieaV7dQ057Qs4sIG2Y=
+cel.dev/expr v0.16.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg=
 cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
@@ -42,6 +44,8 @@ cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14=
 cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU=
 cloud.google.com/go v0.115.1 h1:Jo0SM9cQnSkYfp44+v+NQXHpcHqlnRJk2qxh6yvxxxQ=
 cloud.google.com/go v0.115.1/go.mod h1:DuujITeaufu3gL68/lOFIirVNJwQeyf5UXyi+Wbgknc=
+cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE=
+cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U=
 cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4=
 cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw=
 cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E=
@@ -115,12 +119,24 @@ cloud.google.com/go/auth v0.9.1 h1:+pMtLEV2k0AXKvs/tGZojuj6QaioxfUjOpMsG5Gtx+w=
 cloud.google.com/go/auth v0.9.1/go.mod h1:Sw8ocT5mhhXxFklyhT12Eiy0ed6tTrPMCJjSI8KhYLk=
 cloud.google.com/go/auth v0.9.3 h1:VOEUIAADkkLtyfr3BLa3R8Ed/j6w1jTBmARx+wb5w5U=
 cloud.google.com/go/auth v0.9.3/go.mod h1:7z6VY+7h3KUdRov5F1i8NDP5ZzWKYmEPO842BgCsmTk=
+cloud.google.com/go/auth v0.9.4 h1:DxF7imbEbiFu9+zdKC6cKBko1e8XeJnipNqIbWZ+kDI=
+cloud.google.com/go/auth v0.9.4/go.mod h1:SHia8n6//Ya940F1rLimhJCjjx7KE17t0ctFEci3HkA=
+cloud.google.com/go/auth v0.9.5 h1:4CTn43Eynw40aFVr3GpPqsQponx2jv0BQpjvajsbbzw=
+cloud.google.com/go/auth v0.9.5/go.mod h1:Xo0n7n66eHyOWWCnitop6870Ilwo3PiZyodVkkH1xWM=
+cloud.google.com/go/auth v0.9.8 h1:+CSJ0Gw9iVeSENVCKJoLHhdUykDgXSc4Qn+gu2BRtR8=
+cloud.google.com/go/auth v0.9.8/go.mod h1:xxA5AqpDrvS+Gkmo9RqrGGRh6WSNKKOXhY3zNOr38tI=
+cloud.google.com/go/auth v0.9.9 h1:BmtbpNQozo8ZwW2t7QJjnrQtdganSdmqeIBxHxNkEZQ=
+cloud.google.com/go/auth v0.9.9/go.mod h1:xxA5AqpDrvS+Gkmo9RqrGGRh6WSNKKOXhY3zNOr38tI=
+cloud.google.com/go/auth v0.10.0 h1:tWlkvFAh+wwTOzXIjrwM64karR1iTBZ/GRr0S/DULYo=
+cloud.google.com/go/auth v0.10.0/go.mod h1:xxA5AqpDrvS+Gkmo9RqrGGRh6WSNKKOXhY3zNOr38tI=
 cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4=
 cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q=
 cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI=
 cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I=
 cloud.google.com/go/auth/oauth2adapt v0.2.4 h1:0GWE/FUsXhf6C+jAkWgYm7X9tK8cuEIfy19DBn6B6bY=
 cloud.google.com/go/auth/oauth2adapt v0.2.4/go.mod h1:jC/jOpwFP6JBxhB3P5Rr0a9HLMC/Pe3eaL4NmdvqPtc=
+cloud.google.com/go/auth/oauth2adapt v0.2.5 h1:2p29+dePqsCHPP1bqDJcKj4qxRyYCcbzKpFyKGt3MTk=
+cloud.google.com/go/auth/oauth2adapt v0.2.5/go.mod h1:AlmsELtlEBnaNTL7jCj8VQFLy6mbZv0s4Q7NGBeQ5E8=
 cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0=
 cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8=
 cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8=
@@ -206,6 +222,10 @@ cloud.google.com/go/compute/metadata v0.4.0 h1:vHzJCWaM4g8XIcm8kopr3XmDA4Gy/lblD
 cloud.google.com/go/compute/metadata v0.4.0/go.mod h1:SIQh1Kkb4ZJ8zJ874fqVkslA29PRXuleyj6vOzlbK7M=
 cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY=
 cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY=
+cloud.google.com/go/compute/metadata v0.5.1 h1:NM6oZeZNlYjiwYje+sYFjEpP0Q0zCan1bmQW/KmIrGs=
+cloud.google.com/go/compute/metadata v0.5.1/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k=
+cloud.google.com/go/compute/metadata v0.5.2 h1:UxK4uu/Tn+I3p2dYWTfiX4wva7aYlKixAHn3fyqngqo=
+cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k=
 cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY=
 cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck=
 cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w=
@@ -398,6 +418,10 @@ cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhI
 cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4=
 cloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtDEiEqG4kLK50w=
 cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw=
+cloud.google.com/go/monitoring v1.21.0 h1:EMc0tB+d3lUewT2NzKC/hr8cSR9WsUieVywzIHetGro=
+cloud.google.com/go/monitoring v1.21.0/go.mod h1:tuJ+KNDdJbetSsbSGTqnaBvbauS5kr3Q/koy3Up6r+4=
+cloud.google.com/go/monitoring v1.21.1 h1:zWtbIoBMnU5LP9A/fz8LmWMGHpk4skdfeiaa66QdFGc=
+cloud.google.com/go/monitoring v1.21.1/go.mod h1:Rj++LKrlht9uBi8+Eb530dIrzG/cU/lB8mt+lbeFK1c=
 cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA=
 cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o=
 cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM=
@@ -550,6 +574,12 @@ cloud.google.com/go/spanner v1.65.0 h1:XK15cs9lFFQo5n4Wh9nfrcPXAxWln6NdodDiQKmoD
 cloud.google.com/go/spanner v1.65.0/go.mod h1:dQGB+w5a67gtyE3qSKPPxzniedrnAmV6tewQeBY7Hxs=
 cloud.google.com/go/spanner v1.67.0 h1:h8xfobxh5lQu4qJVMPH+wSiyU+ZM6ZTxRNqGeu9iIVA=
 cloud.google.com/go/spanner v1.67.0/go.mod h1:Um+TNmxfcCHqNCKid4rmAMvoe/Iu1vdz6UfxJ9GPxRQ=
+cloud.google.com/go/spanner v1.68.0 h1:54nL8lEUj5A6frSGnL9VPmHDYbV5UwVkK8fbdnZyDCs=
+cloud.google.com/go/spanner v1.68.0/go.mod h1:X5T0XftydYp0K1adeJQDJtdWpbrOeJ7wHecM4tK6FiE=
+cloud.google.com/go/spanner v1.69.0 h1:/llYvGj7j8ocRDagvHfJW1cM7url9Oa94IScX37eILk=
+cloud.google.com/go/spanner v1.69.0/go.mod h1:X5T0XftydYp0K1adeJQDJtdWpbrOeJ7wHecM4tK6FiE=
+cloud.google.com/go/spanner v1.70.0 h1:nj6p/GJTgMDiSQ1gQ034ItsKuJgHiMOjtOlONOg8PSo=
+cloud.google.com/go/spanner v1.70.0/go.mod h1:X5T0XftydYp0K1adeJQDJtdWpbrOeJ7wHecM4tK6FiE=
 cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM=
 cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ=
 cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0=
@@ -645,6 +675,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.0 h1:oVLqHXhnYtUwM89y9T1fXGaK9wTkXHgNp8/ZNMQzUxE=
 github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.0/go.mod h1:dppbR7CwXD4pgtV9t3wD1812RaLDcBjtblcDF5f1vI0=
+github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.24.1 h1:pB2F2JKCj1Znmp2rwxxt1J0Fg0wezTMgWYk5Mpbi1kg=
+github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.24.1/go.mod h1:itPGVDKf9cC/ov4MdvJ2QZ0khw4bfoo9jzwTJlaxy2k=
 github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk=
 github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
 github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
@@ -696,6 +728,8 @@ github.com/cncf/xds/go v0.0.0-20240318125728-8a4994d93e50 h1:DBmgJDC9dTfkVyGgipa
 github.com/cncf/xds/go v0.0.0-20240318125728-8a4994d93e50/go.mod h1:5e1+Vvlzido69INQaVO6d87Qn543Xr6nooe9Kz7oBFM=
 github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b h1:ga8SEFjZ60pxLcmhnThWgvH2wg8376yUJmPhEH4H3kw=
 github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
+github.com/cncf/xds/go v0.0.0-20240822171458-6449f94b4d59 h1:fLZ97KE86ELjEYJCEUVzmbhfzDxHHGwBrDVMd4XL6Bs=
+github.com/cncf/xds/go v0.0.0-20240822171458-6449f94b4d59/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
 github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
 github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
 github.com/containerd/containerd v1.7.18 h1:jqjZTQNfXGoEaZdW1WwPU0RqSn1Bm2Ay/KJPUuO8nao=
@@ -710,6 +744,8 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7
 github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
 github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E=
 github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
+github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA=
+github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
 github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
@@ -731,6 +767,8 @@ github.com/docker/docker v27.2.0+incompatible h1:Rk9nIVdfH3+Vz4cyI/uhbINhEZ/oLmc
 github.com/docker/docker v27.2.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 github.com/docker/docker v27.2.1+incompatible h1:fQdiLfW7VLscyoeYEBz7/J8soYFDZV1u6VW6gJEjNMI=
 github.com/docker/docker v27.2.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI=
+github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
 github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
 github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
@@ -752,12 +790,16 @@ github.com/envoyproxy/go-control-plane v0.12.0 h1:4X+VP1GHd1Mhj6IB5mMeGbLCleqxjl
 github.com/envoyproxy/go-control-plane v0.12.0/go.mod h1:ZBTaoJ23lqITozF0M6G4/IragXCQKCnYbmlmtHvwRG0=
 github.com/envoyproxy/go-control-plane v0.12.1-0.20240621013728-1eb8caab5155 h1:IgJPqnrlY2Mr4pYB6oaMKvFvwJ9H+X6CCY5x1vCTcpc=
 github.com/envoyproxy/go-control-plane v0.12.1-0.20240621013728-1eb8caab5155/go.mod h1:5Wkq+JduFtdAXihLmeTJf+tRYIT4KBc2vPXDhwVo1pA=
+github.com/envoyproxy/go-control-plane v0.13.0 h1:HzkeUz1Knt+3bK+8LG1bxOO/jzWZmdxpwC51i202les=
+github.com/envoyproxy/go-control-plane v0.13.0/go.mod h1:GRaKG3dwvFoTg4nj7aXdZnvMg4d7nvT/wl9WgVXn3Q8=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo=
 github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w=
 github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss=
 github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A=
 github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew=
+github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM=
+github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4=
 github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
 github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
 github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
@@ -1109,6 +1151,8 @@ github.com/testcontainers/testcontainers-go v0.32.0 h1:ug1aK08L3gCHdhknlTTwWjPHP
 github.com/testcontainers/testcontainers-go v0.32.0/go.mod h1:CRHrzHLQhlXUsa5gXjTOfqIEJcrK5+xMDmBr/WMI88E=
 github.com/testcontainers/testcontainers-go v0.33.0 h1:zJS9PfXYT5O0ZFXM2xxXfk4J5UMw/kRiISng037Gxdw=
 github.com/testcontainers/testcontainers-go v0.33.0/go.mod h1:W80YpTa8D5C3Yy16icheD01UTDu+LmXIA2Keo+jWtT8=
+github.com/testcontainers/testcontainers-go v0.34.0 h1:5fbgF0vIN5u+nD3IWabQwRybuB4GY8G2HHgCkbMzMHo=
+github.com/testcontainers/testcontainers-go v0.34.0/go.mod h1:6P/kMkQe8yqPHfPWNulFGdFHTD8HB2vLq/231xY2iPQ=
 github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
 github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
 github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
@@ -1134,6 +1178,8 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
 go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
 go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
 go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
+go.opentelemetry.io/contrib/detectors/gcp v1.29.0 h1:TiaiXB4DpGD3sdzNlYQxruQngn5Apwzi1X0DRhuGvDQ=
+go.opentelemetry.io/contrib/detectors/gcp v1.29.0/go.mod h1:GW2aWZNwR2ZxDLdv8OyC2G8zkRoQBuURgV7RPQgcPoU=
 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg=
 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0=
 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 h1:r6I7RJCN86bpD/FQwedZ0vSixDpwuWREjW9oRMsmqDc=
@@ -1156,6 +1202,10 @@ go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2
 go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8=
 go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw=
 go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg=
+go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo=
+go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok=
+go.opentelemetry.io/otel/sdk/metric v1.29.0 h1:K2CfmJohnRgvZ9UAj2/FhIf/okdWcNdBwe1m8xFXiSY=
+go.opentelemetry.io/otel/sdk/metric v1.29.0/go.mod h1:6zZLdCl2fkauYoZIOn/soQIDSWFmNSRcICarHfuhNJQ=
 go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
 go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
 go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4=
@@ -1197,6 +1247,8 @@ golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
 golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
 golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
 golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
+golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
+golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
 golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -1320,6 +1372,8 @@ golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
 golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
 golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
 golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
+golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
+golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -1472,6 +1526,8 @@ golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
 golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
 golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
+golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -1505,6 +1561,8 @@ golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
 golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
 golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
 golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
+golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
+golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -1515,6 +1573,8 @@ golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
 golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
 golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
 golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
+golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
+golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
 golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -1678,6 +1738,18 @@ google.golang.org/api v0.196.0 h1:k/RafYqebaIJBO3+SMnfEGtFVlvp5vSgqTUF54UN/zg=
 google.golang.org/api v0.196.0/go.mod h1:g9IL21uGkYgvQ5BZg6BAtoGJQIm8r6EgaAbpNey5wBE=
 google.golang.org/api v0.197.0 h1:x6CwqQLsFiA5JKAiGyGBjc2bNtHtLddhJCE2IKuhhcQ=
 google.golang.org/api v0.197.0/go.mod h1:AuOuo20GoQ331nq7DquGHlU6d+2wN2fZ8O0ta60nRNw=
+google.golang.org/api v0.198.0 h1:OOH5fZatk57iN0A7tjJQzt6aPfYQ1JiWkt1yGseazks=
+google.golang.org/api v0.198.0/go.mod h1:/Lblzl3/Xqqk9hw/yS97TImKTUwnf1bv89v7+OagJzc=
+google.golang.org/api v0.199.0 h1:aWUXClp+VFJmqE0JPvpZOK3LDQMyFKYIow4etYd9qxs=
+google.golang.org/api v0.199.0/go.mod h1:ohG4qSztDJmZdjK/Ar6MhbAmb/Rpi4JHOqagsh90K28=
+google.golang.org/api v0.200.0 h1:0ytfNWn101is6e9VBoct2wrGDjOi5vn7jw5KtaQgDrU=
+google.golang.org/api v0.200.0/go.mod h1:Tc5u9kcbjO7A8SwGlYj4IiVifJU01UqXtEgDMYmBmV8=
+google.golang.org/api v0.201.0 h1:+7AD9JNM3tREtawRMu8sOjSbb8VYcYXJG/2eEOmfDu0=
+google.golang.org/api v0.201.0/go.mod h1:HVY0FCHVs89xIW9fzf/pBvOEm+OolHa86G/txFezyq4=
+google.golang.org/api v0.203.0 h1:SrEeuwU3S11Wlscsn+LA1kb/Y5xT8uggJSkIhD08NAU=
+google.golang.org/api v0.203.0/go.mod h1:BuOVyCSYEPwJb3npWvDnNmFI92f3GeRnHNkETneT3SI=
+google.golang.org/api v0.204.0 h1:3PjmQQEDkR/ENVZZwIYB4W/KzYtN8OrqnNcHWpeR8E4=
+google.golang.org/api v0.204.0/go.mod h1:69y8QSoKIbL9F94bWgWAq6wGqGwyjBgi2y8rAK8zLag=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -1819,6 +1891,14 @@ google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOl
 google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
 google.golang.org/genproto v0.0.0-20240624140628-dc46fd24d27d h1:PksQg4dV6Sem3/HkBX+Ltq8T0ke0PKIRBNBatoDTVls=
 google.golang.org/genproto v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:s7iA721uChleev562UJO2OYB0PPT9CMFjV+Ce7VJH5M=
+google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1 h1:BulPr26Jqjnd4eYDVe+YvyR7Yc2vJGkO5/0UxD0/jZU=
+google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:hL97c3SYopEHblzpxRL4lSs523++l8DYxGM1FQiYmb4=
+google.golang.org/genproto v0.0.0-20241007155032-5fefd90f89a9 h1:nFS3IivktIU5Mk6KQa+v6RKkHUpdQpphqGNLxqNnbEk=
+google.golang.org/genproto v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:tEzYTYZxbmVNOu0OAFH9HzdJtLn6h4Aj89zzlBCdHms=
+google.golang.org/genproto v0.0.0-20241015192408-796eee8c2d53 h1:Df6WuGvthPzc+JiQ/G+m+sNX24kc0aTBqoDN/0yyykE=
+google.golang.org/genproto v0.0.0-20241015192408-796eee8c2d53/go.mod h1:fheguH3Am2dGp1LfXkrvwqC/KlFq8F0nLq3LryOMrrE=
+google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 h1:Q3nlH8iSQSRUwOskjbcSMcF2jiYMNiQYZ0c2KEJLKKU=
+google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38/go.mod h1:xBI+tzfqGGN2JBeSebfKXFSdBpWVQ7sLW40PTupVRm4=
 google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 h1:MuYw1wJzT+ZkybKfaOXKp5hJiZDn2iHaXRw0mRYdHSc=
 google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4/go.mod h1:px9SlOOZBg1wM1zdnr8jEL4CNGUBZ+ZKYtNPApNQc4c=
 google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY=
@@ -1827,6 +1907,14 @@ google.golang.org/genproto/googleapis/api v0.0.0-20240722135656-d784300faade h1:
 google.golang.org/genproto/googleapis/api v0.0.0-20240722135656-d784300faade/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0=
 google.golang.org/genproto/googleapis/api v0.0.0-20240725223205-93522f1f2a9f h1:b1Ln/PG8orm0SsBbHZWke8dDp2lrCD4jSmfglFpTZbk=
 google.golang.org/genproto/googleapis/api v0.0.0-20240725223205-93522f1f2a9f/go.mod h1:AHT0dDg3SoMOgZGnZk29b5xTbPHMoEC8qthmBLJCpys=
+google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc=
+google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I=
+google.golang.org/genproto/googleapis/api v0.0.0-20240930140551-af27646dc61f h1:jTm13A2itBi3La6yTGqn8bVSrc3ZZ1r8ENHlIXBfnRA=
+google.golang.org/genproto/googleapis/api v0.0.0-20240930140551-af27646dc61f/go.mod h1:CLGoBuH1VHxAUXVPP8FfPwPEVJB6lz3URE5mY2SuayE=
+google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 h1:T6rh4haD3GVYsgEfWExoCZA2o2FmbNyKpTuAxbEFPTg=
+google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:wp2WsuBYj6j8wUdo3ToZsdxxixbvQNAHqVJrTgi5E5M=
+google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 h1:fVoAXEKA4+yufmbdVYv+SE73+cPZbbbe8paLsHfkK+U=
+google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53/go.mod h1:riSXTwQ4+nqmPGtobMFyW5FqVAmIs0St6VPp4Ug7CE4=
 google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d h1:k3zyW3BYYR30e8v3x0bTDdE9vpYFjZHK+HcyqkrppWk=
 google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
 google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b h1:04+jVzTs2XBnOZcPsLnmrTGqltqJbZQ1Ey26hjYdQQ0=
@@ -1839,6 +1927,12 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20240823204242-4ba0660f739c h1:
 google.golang.org/genproto/googleapis/rpc v0.0.0-20240823204242-4ba0660f739c/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
 google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
 google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 h1:X58yt85/IXCx0Y3ZwN6sEIKZzQtDEYaBWrDvErdXrRE=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 h1:zciRKQ4kBpFgpfC5QQCVtnnNAcLIqweL7plyZRQHVpI=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
 google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@@ -1888,6 +1982,12 @@ google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c=
 google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
 google.golang.org/grpc v1.66.1 h1:hO5qAXR19+/Z44hmvIM4dQFMSYX9XcWsByfoxutBpAM=
 google.golang.org/grpc v1.66.1/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
+google.golang.org/grpc v1.66.2 h1:3QdXkuq3Bkh7w+ywLdLvM56cmGvQHUMZpiCzt6Rqaoo=
+google.golang.org/grpc v1.66.2/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
+google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw=
+google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
+google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
+google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
@@ -1908,6 +2008,8 @@ google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
 google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
 google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
+google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
+google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
diff --git a/benchmarks/latency-comparison/java/pom.xml b/benchmarks/latency-comparison/java/pom.xml
index 0aea5137..9915e638 100644
--- a/benchmarks/latency-comparison/java/pom.xml
+++ b/benchmarks/latency-comparison/java/pom.xml
@@ -21,7 +21,7 @@
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 
-    <junixsocket.version>2.10.0</junixsocket.version>
+    <junixsocket.version>2.10.1</junixsocket.version>
   </properties>
 
   <modelVersion>4.0.0</modelVersion>
@@ -35,7 +35,7 @@
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-shared-config</artifactId>
-    <version>1.11.1</version>
+    <version>1.11.3</version>
   </parent>
 
   <dependencyManagement>
@@ -43,14 +43,14 @@
       <dependency>
         <groupId>com.google.cloud</groupId>
         <artifactId>libraries-bom</artifactId>
-        <version>26.46.0</version>
+        <version>26.50.0</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
       <dependency>
         <groupId>io.opentelemetry</groupId>
         <artifactId>opentelemetry-bom</artifactId>
-        <version>1.42.1</version>
+        <version>1.43.0</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
@@ -76,7 +76,7 @@
     <dependency>
       <groupId>com.google.cloud</groupId>
       <artifactId>google-cloud-spanner-pgadapter</artifactId>
-      <version>0.37.0</version>
+      <version>0.40.0</version>
       <exclusions>
         <exclusion>
           <groupId>io.opentelemetry</groupId>
@@ -109,7 +109,7 @@
     <dependency>
       <groupId>org.checkerframework</groupId>
       <artifactId>checker-qual</artifactId>
-      <version>3.47.0</version>
+      <version>3.48.1</version>
     </dependency>
 
     <dependency>
@@ -124,7 +124,7 @@
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>exec-maven-plugin</artifactId>
-        <version>3.4.1</version>
+        <version>3.5.0</version>
         <configuration>
           <mainClass>com.google.cloud.spanner.pgadapter.latency.LatencyBenchmark</mainClass>
           <cleanupDaemonThreads>false</cleanupDaemonThreads>
diff --git a/benchmarks/latency-comparison/nodejs/package.json b/benchmarks/latency-comparison/nodejs/package.json
index c0ad67a2..dd7f16b8 100644
--- a/benchmarks/latency-comparison/nodejs/package.json
+++ b/benchmarks/latency-comparison/nodejs/package.json
@@ -4,7 +4,7 @@
   "description": "Node.js Latency Comparison for PGAdapter and the Spanner client library",
   "type": "commonjs",
   "devDependencies": {
-    "@types/node": "^20.1.4",
+    "@types/node": "^22.0.0",
     "@types/yargs": "^17.0.32",
     "typescript": "^5.4.5"
   },
diff --git a/benchmarks/tpcc/pom.xml b/benchmarks/tpcc/pom.xml
index 5a3ada42..495c575a 100644
--- a/benchmarks/tpcc/pom.xml
+++ b/benchmarks/tpcc/pom.xml
@@ -5,7 +5,7 @@
   <parent>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-parent</artifactId>
-    <version>3.3.3</version>
+    <version>3.3.5</version>
     <relativePath/> <!-- lookup parent from repository -->
   </parent>
   <groupId>com.google.cloud.spanner</groupId>
@@ -21,21 +21,21 @@
       <dependency>
         <groupId>com.google.cloud</groupId>
         <artifactId>libraries-bom</artifactId>
-        <version>26.46.0</version>
+        <version>26.50.0</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
       <dependency>
         <groupId>io.opentelemetry</groupId>
         <artifactId>opentelemetry-bom</artifactId>
-        <version>1.42.1</version>
+        <version>1.43.0</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
       <dependency>
         <groupId>org.testcontainers</groupId>
         <artifactId>testcontainers-bom</artifactId>
-        <version>1.20.1</version>
+        <version>1.20.3</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
@@ -61,7 +61,7 @@
     <dependency>
       <groupId>com.google.cloud</groupId>
       <artifactId>google-cloud-spanner-pgadapter</artifactId>
-      <version>0.37.0</version>
+      <version>0.40.0</version>
     </dependency>
     <dependency>
           <groupId>io.opentelemetry</groupId>
@@ -97,7 +97,7 @@
       <plugin>
         <groupId>com.spotify.fmt</groupId>
         <artifactId>fmt-maven-plugin</artifactId>
-        <version>2.24</version>
+        <version>2.25</version>
         <executions>
           <execution>
             <goals>
diff --git a/benchmarks/tpcc/src/main/java/com/google/cloud/pgadapter/tpcc/BenchmarkApplication.java b/benchmarks/tpcc/src/main/java/com/google/cloud/pgadapter/tpcc/BenchmarkApplication.java
index 1f2f704e..996e859f 100644
--- a/benchmarks/tpcc/src/main/java/com/google/cloud/pgadapter/tpcc/BenchmarkApplication.java
+++ b/benchmarks/tpcc/src/main/java/com/google/cloud/pgadapter/tpcc/BenchmarkApplication.java
@@ -245,7 +245,6 @@ public class BenchmarkApplication implements CommandLineRunner {
 
   static Attributes createMetricAttributes(SpannerConfiguration spannerConfiguration) {
     AttributesBuilder attributesBuilder = Attributes.builder();
-    attributesBuilder.put("connection_id", UUID.randomUUID().toString());
     attributesBuilder.put("database", spannerConfiguration.getDatabase());
     attributesBuilder.put("instance_id", spannerConfiguration.getInstance());
     attributesBuilder.put("project_id", spannerConfiguration.getProject());
diff --git a/build/Dockerfile b/build/Dockerfile
index 5d4e6531..169d3c0f 100644
--- a/build/Dockerfile
+++ b/build/Dockerfile
@@ -24,7 +24,7 @@ RUN mvn package -Passembly -DskipTests
 #                                   RELEASE                                    #
 ################################################################################
 
-FROM eclipse-temurin:22-jre
+FROM eclipse-temurin:23-jre
 
 COPY --from=build target/pgadapter /home/pgadapter
 COPY --from=build LICENSE /home/pgadapter/
diff --git a/docs/command_line_arguments.md b/docs/command_line_arguments.md
index 40d5048a..cc1784ca 100644
--- a/docs/command_line_arguments.md
+++ b/docs/command_line_arguments.md
@@ -70,6 +70,17 @@
     Docker container, as the connections from the host machine will not be seen as a connection from
     localhost in the container.
 
+--allow_shutdown_command
+  * Enables the use of the custom SQL command `SHUTDOWN [SMART | FAST | IMMEDIATE]`. This command can
+    be used to shut down PGAdapter by just sending it a SQL statement. This option should only be enabled
+    when PGAdapter runs in a trusted environment, for example as a side-car container. The default
+    shutdown mode is `FAST`, which terminates all existing connections and then shuts down PGAdapter.
+    Use shutdown mode `SMART` to instruct PGAdapter to wait until all existing connections have been
+    terminated by the client before shutting down. See also https://www.postgresql.org/docs/current/server-shutdown.html
+    for more information about shutdown modes.
+  * Note that `SHUTDOWN [SMART | FAST | IMMEDIATE]` only works on PGAdapter. This command is not
+    supported by PostgreSQL.
+
 -r
   * PGAdapter internally uses the core engine of the Cloud Spanner JDBC driver. This option specifies
     additional properties that will be used with that internal JDBC connection. All connection properties
diff --git a/pom.xml b/pom.xml
index 12bf03e3..2c35bd55 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,13 +37,13 @@
     </excludedTests>
     <excludedIntegrationTests/>
 
-    <junixsocket.version>2.10.0</junixsocket.version>
-    <opentelemetry.exporter.version>0.31.0</opentelemetry.exporter.version>
+    <junixsocket.version>2.10.1</junixsocket.version>
+    <opentelemetry.exporter.version>0.33.0</opentelemetry.exporter.version>
   </properties>
 
   <modelVersion>4.0.0</modelVersion>
   <artifactId>google-cloud-spanner-pgadapter</artifactId>
-  <version>0.37.1-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner-pgadapter:current} -->
+  <version>0.40.1-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner-pgadapter:current} -->
   <name>Google Cloud Spanner PostgreSQL Adapter</name>
   <packaging>jar</packaging>
   <description>
@@ -55,7 +55,7 @@
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-shared-config</artifactId>
-    <version>1.11.1</version>
+    <version>1.11.3</version>
   </parent>
   <scm>
     <connection>scm:git:git@github.com:GoogleCloudPlatform/pgadapter.git</connection>
@@ -78,14 +78,14 @@
       <dependency>
         <groupId>io.opentelemetry</groupId>
         <artifactId>opentelemetry-bom</artifactId>
-        <version>1.42.1</version>
+        <version>1.43.0</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
       <dependency>
         <groupId>com.google.cloud</groupId>
         <artifactId>libraries-bom</artifactId>
-        <version>26.46.0</version>
+        <version>26.50.0</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
@@ -110,7 +110,7 @@
     <dependency>
       <groupId>org.checkerframework</groupId>
       <artifactId>checker-qual</artifactId>
-      <version>3.47.0</version>
+      <version>3.48.1</version>
     </dependency>
     <dependency>
       <groupId>io.opentelemetry</groupId>
@@ -136,7 +136,7 @@
       <!-- Not managed by opentelemetry-bom -->
       <groupId>io.opentelemetry.semconv</groupId>
       <artifactId>opentelemetry-semconv</artifactId>
-      <version>1.27.0-alpha</version>
+      <version>1.28.0-alpha</version>
     </dependency>
     <dependency>
       <groupId>io.opentelemetry</groupId>
@@ -159,7 +159,7 @@
     <dependency>
       <groupId>org.jetbrains.kotlin</groupId>
       <artifactId>kotlin-stdlib-jdk8</artifactId>
-      <version>2.0.20</version>
+      <version>2.0.21</version>
       <scope>runtime</scope>
     </dependency>
     <dependency>
@@ -197,7 +197,7 @@
     <dependency>
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-csv</artifactId>
-      <version>1.11.0</version>
+      <version>1.12.0</version>
     </dependency>
     <dependency>
       <groupId>org.apache.commons</groupId>
@@ -212,7 +212,7 @@
     <dependency>
       <groupId>org.bouncycastle</groupId>
       <artifactId>bcpkix-jdk18on</artifactId>
-      <version>1.78.1</version>
+      <version>1.79</version>
     </dependency>
     <dependency>
       <groupId>org.codehaus.mojo</groupId>
diff --git a/samples/cloud-run/dotnet/dotnet.csproj b/samples/cloud-run/dotnet/dotnet.csproj
index d79e1940..268bc047 100644
--- a/samples/cloud-run/dotnet/dotnet.csproj
+++ b/samples/cloud-run/dotnet/dotnet.csproj
@@ -7,7 +7,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Npgsql" Version="8.0.4" />
+    <PackageReference Include="Npgsql" Version="8.0.5" />
   </ItemGroup>
 
 </Project>
diff --git a/samples/cloud-run/golang/go.mod b/samples/cloud-run/golang/go.mod
index a821012e..5903036d 100644
--- a/samples/cloud-run/golang/go.mod
+++ b/samples/cloud-run/golang/go.mod
@@ -2,8 +2,6 @@ module pgadapter-cloud-run
 
 go 1.21
 
-toolchain go1.23.1
-
 require github.com/jackc/pgx/v5 v5.7.1
 
 require (
diff --git a/samples/cloud-run/golang/go.sum b/samples/cloud-run/golang/go.sum
index 137381b1..345521ef 100644
--- a/samples/cloud-run/golang/go.sum
+++ b/samples/cloud-run/golang/go.sum
@@ -1,35 +1,28 @@
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
 github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
-github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
-github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
 github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
 github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
-github.com/jackc/pgx/v5 v5.5.4 h1:Xp2aQS8uXButQdnCMWNmvx6UysWQQC+u1EoizjguY+8=
-github.com/jackc/pgx/v5 v5.5.4/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
-github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
-github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
-github.com/jackc/pgx/v5 v5.6.0 h1:SWJzexBzPL5jb0GEsrPMLIsi/3jOo7RHlzTjcAeDrPY=
-github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw=
 github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs=
 github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA=
-github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
+github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
+github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
-golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
-golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
 golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
-golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
-golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
-golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
+golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
 golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/samples/cloud-run/java/pom.xml b/samples/cloud-run/java/pom.xml
index 0a84859a..e59b2741 100644
--- a/samples/cloud-run/java/pom.xml
+++ b/samples/cloud-run/java/pom.xml
@@ -21,8 +21,8 @@
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 
-    <spring-boot.version>3.3.3</spring-boot.version>
-    <junixsocket.version>2.10.0</junixsocket.version>
+    <spring-boot.version>3.3.5</spring-boot.version>
+    <junixsocket.version>2.10.1</junixsocket.version>
   </properties>
 
   <modelVersion>4.0.0</modelVersion>
@@ -97,7 +97,7 @@
       <plugin>
         <groupId>com.google.cloud.tools</groupId>
         <artifactId>jib-maven-plugin</artifactId>
-        <version>3.4.3</version>
+        <version>3.4.4</version>
         <configuration>
           <to>
             <image>gcr.io/PROJECT_ID/pgadapter-sidecar-example</image>
diff --git a/samples/cloud-run/python/Dockerfile b/samples/cloud-run/python/Dockerfile
index f3f6cebf..7902f123 100644
--- a/samples/cloud-run/python/Dockerfile
+++ b/samples/cloud-run/python/Dockerfile
@@ -1,7 +1,7 @@
 
 # Use the official lightweight Python image.
 # https://hub.docker.com/_/python
-FROM python:3.12-slim
+FROM python:3.13-slim
 
 # Allow statements and log messages to immediately appear in the logs
 ENV PYTHONUNBUFFERED True
diff --git a/samples/dotnet/npgsql-sample/npgsql-sample.csproj b/samples/dotnet/npgsql-sample/npgsql-sample.csproj
index c0c0fff4..3200f30a 100644
--- a/samples/dotnet/npgsql-sample/npgsql-sample.csproj
+++ b/samples/dotnet/npgsql-sample/npgsql-sample.csproj
@@ -9,7 +9,7 @@
     </PropertyGroup>
 
     <ItemGroup>
-      <PackageReference Include="Npgsql" Version="8.0.4" />
+      <PackageReference Include="Npgsql" Version="8.0.5" />
       <PackageReference Include="Testcontainers" Version="3.10.0" />
     </ItemGroup>
 
diff --git a/samples/golang/gorm/go.mod b/samples/golang/gorm/go.mod
index 2d8483bf..2661fd17 100644
--- a/samples/golang/gorm/go.mod
+++ b/samples/golang/gorm/go.mod
@@ -1,15 +1,17 @@
 module gorm
 
-go 1.21
+go 1.22
+
+toolchain go1.23.2
 
 require (
-	github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20240912183532-c756559e4665
+	github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20241022193243-92bc36f15266
 	github.com/google/uuid v1.6.0
-	github.com/jackc/pgtype v1.14.3
+	github.com/jackc/pgtype v1.14.4
 	github.com/shopspring/decimal v1.4.0
-	github.com/testcontainers/testcontainers-go v0.33.0
-	github.com/testcontainers/testcontainers-go/modules/postgres v0.33.0
-	gorm.io/datatypes v1.2.2
+	github.com/testcontainers/testcontainers-go v0.34.0
+	github.com/testcontainers/testcontainers-go/modules/postgres v0.34.0
+	gorm.io/datatypes v1.2.4
 	gorm.io/driver/postgres v1.5.9
 	gorm.io/gorm v1.25.12
 )
@@ -23,9 +25,10 @@ require (
 	github.com/cenkalti/backoff/v4 v4.2.1 // indirect
 	github.com/containerd/log v0.1.0 // indirect
 	github.com/containerd/platforms v0.2.1 // indirect
-	github.com/cpuguy83/dockercfg v0.3.1 // indirect
+	github.com/cpuguy83/dockercfg v0.3.2 // indirect
+	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/distribution/reference v0.6.0 // indirect
-	github.com/docker/docker v27.2.1+incompatible // indirect
+	github.com/docker/docker v27.3.1+incompatible // indirect
 	github.com/docker/go-connections v0.5.0 // indirect
 	github.com/docker/go-units v0.5.0 // indirect
 	github.com/felixge/httpsnoop v1.0.4 // indirect
@@ -54,10 +57,12 @@ require (
 	github.com/opencontainers/go-digest v1.0.0 // indirect
 	github.com/opencontainers/image-spec v1.1.0 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
 	github.com/shirou/gopsutil/v3 v3.23.12 // indirect
 	github.com/shoenig/go-m1cpu v0.1.6 // indirect
 	github.com/sirupsen/logrus v1.9.3 // indirect
+	github.com/stretchr/testify v1.9.0 // indirect
 	github.com/tklauser/go-sysconf v0.3.13 // indirect
 	github.com/tklauser/numcpus v0.7.0 // indirect
 	github.com/yusufpapurcu/wmi v1.2.3 // indirect
@@ -72,5 +77,6 @@ require (
 	golang.org/x/sync v0.7.0 // indirect
 	golang.org/x/sys v0.21.0 // indirect
 	golang.org/x/text v0.16.0 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
 	gorm.io/driver/mysql v1.5.6 // indirect
 )
diff --git a/samples/golang/gorm/go.sum b/samples/golang/gorm/go.sum
index 4845e97e..91bb5067 100644
--- a/samples/golang/gorm/go.sum
+++ b/samples/golang/gorm/go.sum
@@ -9,8 +9,10 @@ github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h
 github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
 github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20240912183532-c756559e4665 h1:y2O+wODDmfREw15/LE1jkIziNJLYOVq3cllbu85H6kg=
-github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20240912183532-c756559e4665/go.mod h1:o0VdiWILEdFOmmWaLjI/CR1cojsHX748rEmqb++PfOU=
+github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20240919150510-c310ce84d0c9 h1:3JCzAQ/YdZ/wrGq3wgGQq24uG/IHfnlq2TPpGQqWiTE=
+github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20240919150510-c310ce84d0c9/go.mod h1:o0VdiWILEdFOmmWaLjI/CR1cojsHX748rEmqb++PfOU=
+github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20241022193243-92bc36f15266 h1:5uo7tPRv0+14g/+dZKQrBg9hQVWWNCtOl3G8tZuFOM8=
+github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20241022193243-92bc36f15266/go.mod h1:tPyvuD/QQH7tjAAjLzxjPK/L6DAybS/UO7kEA32XqSE=
 github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
 github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
 github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
@@ -25,6 +27,8 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7
 github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
 github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E=
 github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
+github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA=
+github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
 github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
 github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
 github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
@@ -35,6 +39,8 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr
 github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
 github.com/docker/docker v27.2.1+incompatible h1:fQdiLfW7VLscyoeYEBz7/J8soYFDZV1u6VW6gJEjNMI=
 github.com/docker/docker v27.2.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI=
+github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
 github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
 github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
@@ -112,6 +118,8 @@ github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9
 github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
 github.com/jackc/pgtype v1.14.3 h1:h6W9cPuHsRWQFTWUZMAKMgG5jSwQI0Zurzdvlx3Plus=
 github.com/jackc/pgtype v1.14.3/go.mod h1:aKeozOde08iifGosdJpz9MBZonJOUJxqNpPBcMJTlVA=
+github.com/jackc/pgtype v1.14.4 h1:fKuNiCumbKTAIxQwXfB/nsrnkEI6bPJrrSiMKgbJ2j8=
+github.com/jackc/pgtype v1.14.4/go.mod h1:aKeozOde08iifGosdJpz9MBZonJOUJxqNpPBcMJTlVA=
 github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
 github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
 github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
@@ -223,8 +231,12 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
 github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 github.com/testcontainers/testcontainers-go v0.33.0 h1:zJS9PfXYT5O0ZFXM2xxXfk4J5UMw/kRiISng037Gxdw=
 github.com/testcontainers/testcontainers-go v0.33.0/go.mod h1:W80YpTa8D5C3Yy16icheD01UTDu+LmXIA2Keo+jWtT8=
+github.com/testcontainers/testcontainers-go v0.34.0 h1:5fbgF0vIN5u+nD3IWabQwRybuB4GY8G2HHgCkbMzMHo=
+github.com/testcontainers/testcontainers-go v0.34.0/go.mod h1:6P/kMkQe8yqPHfPWNulFGdFHTD8HB2vLq/231xY2iPQ=
 github.com/testcontainers/testcontainers-go/modules/postgres v0.33.0 h1:c+Gt+XLJjqFAejgX4hSpnHIpC9eAhvgI/TFWL/PbrFI=
 github.com/testcontainers/testcontainers-go/modules/postgres v0.33.0/go.mod h1:I4DazHBoWDyf69ByOIyt3OdNjefiUx372459txOpQ3o=
+github.com/testcontainers/testcontainers-go/modules/postgres v0.34.0 h1:c51aBXT3v2HEBVarmaBnsKzvgZjC5amn0qsj8Naqi50=
+github.com/testcontainers/testcontainers-go/modules/postgres v0.34.0/go.mod h1:EWP75ogLQU4M4L8U+20mFipjV4WIR9WtlMXSB6/wiuc=
 github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
 github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4=
 github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0=
@@ -390,8 +402,8 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gorm.io/datatypes v1.2.2 h1:sdn7ZmG4l7JWtMDUb3L98f2Ym7CO5F8mZLlrQJMfF9g=
-gorm.io/datatypes v1.2.2/go.mod h1:f4BsLcFAX67szSv8svwLRjklArSHAvHLeE3pXAS5DZI=
+gorm.io/datatypes v1.2.4 h1:uZmGAcK/QZ0uyfCuVg0VQY1ZmV9h1fuG0tMwKByO1z4=
+gorm.io/datatypes v1.2.4/go.mod h1:f4BsLcFAX67szSv8svwLRjklArSHAvHLeE3pXAS5DZI=
 gorm.io/driver/mysql v1.5.6 h1:Ld4mkIickM+EliaQZQx3uOJDJHtrd70MxAUqWqlx3Y8=
 gorm.io/driver/mysql v1.5.6/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
 gorm.io/driver/postgres v1.5.9 h1:DkegyItji119OlcaLjqN11kHoUgZ/j13E0jkJZgD6A8=
diff --git a/samples/golang/migrate/README.md b/samples/golang/migrate/README.md
new file mode 100644
index 00000000..423ce7fa
--- /dev/null
+++ b/samples/golang/migrate/README.md
@@ -0,0 +1,16 @@
+# Golang Migrate
+
+This sample application shows how to use [Golang Migrate](https://github.com/golang-migrate/migrate)
+with PGAdapter. The sample application automatically starts PGAdapter and the Spanner emulator in a
+Docker container and connects to this. It then executes a small set of migration scripts.
+
+__NOTE__: Golang Migrate only works with PGAdapter if you add `fallback_application_name=golang-migrate`
+to the connection string. See [sample.go](./sample.go) for a full example.
+
+```go
+connString := "postgres://localhost:5432/my-database?sslmode=disable&fallback_application_name=golang-migrate"
+m, err := migrate.New("file://migrations", connString)
+```
+
+If you fail to add the application name to the connection string, you will get an error that
+the function `pg_advisory_lock` is not supported.
diff --git a/samples/golang/migrate/go.mod b/samples/golang/migrate/go.mod
new file mode 100644
index 00000000..4f242017
--- /dev/null
+++ b/samples/golang/migrate/go.mod
@@ -0,0 +1,66 @@
+module migrate
+
+go 1.22.3
+
+require (
+	github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20241022193243-92bc36f15266
+	github.com/golang-migrate/migrate/v4 v4.18.1
+)
+
+require (
+	cloud.google.com/go/compute/metadata v0.3.0 // indirect
+	dario.cat/mergo v1.0.0 // indirect
+	github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
+	github.com/Microsoft/go-winio v0.6.2 // indirect
+	github.com/cenkalti/backoff/v4 v4.2.1 // indirect
+	github.com/containerd/log v0.1.0 // indirect
+	github.com/containerd/platforms v0.2.1 // indirect
+	github.com/cpuguy83/dockercfg v0.3.2 // indirect
+	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/distribution/reference v0.6.0 // indirect
+	github.com/docker/docker v27.3.1+incompatible // indirect
+	github.com/docker/go-connections v0.5.0 // indirect
+	github.com/docker/go-units v0.5.0 // indirect
+	github.com/felixge/httpsnoop v1.0.4 // indirect
+	github.com/go-logr/logr v1.4.2 // indirect
+	github.com/go-logr/stdr v1.2.2 // indirect
+	github.com/go-ole/go-ole v1.2.6 // indirect
+	github.com/gogo/protobuf v1.3.2 // indirect
+	github.com/google/uuid v1.6.0 // indirect
+	github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect
+	github.com/hashicorp/errwrap v1.1.0 // indirect
+	github.com/hashicorp/go-multierror v1.1.1 // indirect
+	github.com/klauspost/compress v1.17.4 // indirect
+	github.com/lib/pq v1.10.9 // indirect
+	github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
+	github.com/magiconair/properties v1.8.7 // indirect
+	github.com/moby/docker-image-spec v1.3.1 // indirect
+	github.com/moby/patternmatcher v0.6.0 // indirect
+	github.com/moby/sys/sequential v0.5.0 // indirect
+	github.com/moby/sys/user v0.1.0 // indirect
+	github.com/moby/sys/userns v0.1.0 // indirect
+	github.com/moby/term v0.5.0 // indirect
+	github.com/morikuni/aec v1.0.0 // indirect
+	github.com/opencontainers/go-digest v1.0.0 // indirect
+	github.com/opencontainers/image-spec v1.1.0 // indirect
+	github.com/pkg/errors v0.9.1 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
+	github.com/shirou/gopsutil/v3 v3.23.12 // indirect
+	github.com/shoenig/go-m1cpu v0.1.6 // indirect
+	github.com/sirupsen/logrus v1.9.3 // indirect
+	github.com/stretchr/testify v1.9.0 // indirect
+	github.com/testcontainers/testcontainers-go v0.34.0 // indirect
+	github.com/tklauser/go-sysconf v0.3.12 // indirect
+	github.com/tklauser/numcpus v0.6.1 // indirect
+	github.com/yusufpapurcu/wmi v1.2.3 // indirect
+	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
+	go.opentelemetry.io/otel v1.29.0 // indirect
+	go.opentelemetry.io/otel/metric v1.29.0 // indirect
+	go.opentelemetry.io/otel/trace v1.29.0 // indirect
+	go.uber.org/atomic v1.7.0 // indirect
+	golang.org/x/crypto v0.27.0 // indirect
+	golang.org/x/oauth2 v0.23.0 // indirect
+	golang.org/x/sys v0.25.0 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
+)
diff --git a/samples/golang/migrate/go.sum b/samples/golang/migrate/go.sum
new file mode 100644
index 00000000..3b76ccca
--- /dev/null
+++ b/samples/golang/migrate/go.sum
@@ -0,0 +1,212 @@
+cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
+cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
+dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
+dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
+github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
+github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
+github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
+github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
+github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20240918132525-a4dc9268921f h1:LAdtwZoHYcWnCqzUKdDkNG7nngy8il3i9eE/fW3oQq0=
+github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20240918132525-a4dc9268921f/go.mod h1:o0VdiWILEdFOmmWaLjI/CR1cojsHX748rEmqb++PfOU=
+github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20240919150510-c310ce84d0c9 h1:3JCzAQ/YdZ/wrGq3wgGQq24uG/IHfnlq2TPpGQqWiTE=
+github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20240919150510-c310ce84d0c9/go.mod h1:o0VdiWILEdFOmmWaLjI/CR1cojsHX748rEmqb++PfOU=
+github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20241022193243-92bc36f15266 h1:5uo7tPRv0+14g/+dZKQrBg9hQVWWNCtOl3G8tZuFOM8=
+github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20241022193243-92bc36f15266/go.mod h1:tPyvuD/QQH7tjAAjLzxjPK/L6DAybS/UO7kEA32XqSE=
+github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
+github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
+github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
+github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
+github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
+github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
+github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A=
+github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw=
+github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E=
+github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
+github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA=
+github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
+github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
+github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dhui/dktest v0.4.3 h1:wquqUxAFdcUgabAVLvSCOKOlag5cIZuaOjYIBOWdsR0=
+github.com/dhui/dktest v0.4.3/go.mod h1:zNK8IwktWzQRm6I/l2Wjp7MakiyaFWv4G1hjmodmMTs=
+github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
+github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
+github.com/docker/docker v27.2.1+incompatible h1:fQdiLfW7VLscyoeYEBz7/J8soYFDZV1u6VW6gJEjNMI=
+github.com/docker/docker v27.2.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI=
+github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
+github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
+github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
+github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
+github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
+github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
+github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
+github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
+github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
+github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
+github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+github.com/golang-migrate/migrate/v4 v4.18.1 h1:JML/k+t4tpHCpQTCAD62Nu43NUFzHY4CV3uAuvHGC+Y=
+github.com/golang-migrate/migrate/v4 v4.18.1/go.mod h1:HAX6m3sQgcdO81tdjn5exv20+3Kb13cmGli1hrD6hks=
+github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I=
+github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
+github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
+github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
+github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4=
+github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
+github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
+github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
+github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
+github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
+github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
+github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
+github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
+github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
+github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
+github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
+github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
+github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
+github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg=
+github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU=
+github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=
+github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=
+github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
+github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
+github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
+github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
+github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
+github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
+github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
+github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
+github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
+github.com/shirou/gopsutil/v3 v3.23.12 h1:z90NtUkp3bMtmICZKpC4+WaknU1eXtp5vtbQ11DgpE4=
+github.com/shirou/gopsutil/v3 v3.23.12/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM=
+github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
+github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
+github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
+github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
+github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
+github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/testcontainers/testcontainers-go v0.33.0 h1:zJS9PfXYT5O0ZFXM2xxXfk4J5UMw/kRiISng037Gxdw=
+github.com/testcontainers/testcontainers-go v0.33.0/go.mod h1:W80YpTa8D5C3Yy16icheD01UTDu+LmXIA2Keo+jWtT8=
+github.com/testcontainers/testcontainers-go v0.34.0 h1:5fbgF0vIN5u+nD3IWabQwRybuB4GY8G2HHgCkbMzMHo=
+github.com/testcontainers/testcontainers-go v0.34.0/go.mod h1:6P/kMkQe8yqPHfPWNulFGdFHTD8HB2vLq/231xY2iPQ=
+github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
+github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
+github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
+github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
+github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8=
+go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw=
+go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0/go.mod h1:jlRVBe7+Z1wyxFSUs48L6OBQZ5JwH2Hg/Vbl+t9rAgI=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU=
+go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc=
+go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8=
+go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo=
+go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok=
+go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4=
+go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ=
+go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
+go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
+go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
+go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
+golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
+golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
+golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
+golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
+golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=
+golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
+golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
+golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
+golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y=
+google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8=
+google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
+google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA=
+google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0=
+google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
+google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
+gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
diff --git a/samples/golang/migrate/migrations/1_create_schema.down.sql b/samples/golang/migrate/migrations/1_create_schema.down.sql
new file mode 100644
index 00000000..ee5d4515
--- /dev/null
+++ b/samples/golang/migrate/migrations/1_create_schema.down.sql
@@ -0,0 +1,9 @@
+-- Use DDL batching to improve execution speed.
+-- See https://cloud.google.com/spanner/docs/pgadapter-session-mgmt-commands#batch-statements
+-- for more information.
+start batch ddl;
+
+drop table numbers;
+drop table prime_numbers;
+
+run batch;
diff --git a/samples/golang/migrate/migrations/1_create_schema.up.sql b/samples/golang/migrate/migrations/1_create_schema.up.sql
new file mode 100644
index 00000000..56597de9
--- /dev/null
+++ b/samples/golang/migrate/migrations/1_create_schema.up.sql
@@ -0,0 +1,9 @@
+-- Use DDL batching to improve execution speed.
+-- See https://cloud.google.com/spanner/docs/pgadapter-session-mgmt-commands#batch-statements
+-- for more information.
+start batch ddl;
+
+create table numbers (num bigint primary key, name varchar);
+create table prime_numbers (num bigint primary key, name varchar, n bigint);
+
+run batch;
diff --git a/samples/golang/migrate/migrations/2_add_index.down.sql b/samples/golang/migrate/migrations/2_add_index.down.sql
new file mode 100644
index 00000000..b166ed44
--- /dev/null
+++ b/samples/golang/migrate/migrations/2_add_index.down.sql
@@ -0,0 +1,1 @@
+drop index idx_nth_prime_number;
diff --git a/samples/golang/migrate/migrations/2_add_index.up.sql b/samples/golang/migrate/migrations/2_add_index.up.sql
new file mode 100644
index 00000000..579ba0a2
--- /dev/null
+++ b/samples/golang/migrate/migrations/2_add_index.up.sql
@@ -0,0 +1,1 @@
+create index idx_nth_prime_number on prime_numbers (n);
diff --git a/samples/golang/migrate/migrations/3_insert_data.down.sql b/samples/golang/migrate/migrations/3_insert_data.down.sql
new file mode 100644
index 00000000..4091487d
--- /dev/null
+++ b/samples/golang/migrate/migrations/3_insert_data.down.sql
@@ -0,0 +1,4 @@
+begin;
+delete from numbers where num>=1 and num<=8;
+delete from prime_numbers where num>=2 and num<=5;
+commit;
diff --git a/samples/golang/migrate/migrations/3_insert_data.up.sql b/samples/golang/migrate/migrations/3_insert_data.up.sql
new file mode 100644
index 00000000..e5b00a97
--- /dev/null
+++ b/samples/golang/migrate/migrations/3_insert_data.up.sql
@@ -0,0 +1,29 @@
+begin;
+
+insert into numbers (num, name)
+select 1, 'One'
+union all
+select 2, 'Two'
+union all
+select 3, 'Three'
+union all
+select 4, 'Four'
+union all
+select 5, 'Five'
+union all
+select 6, 'Six'
+union all
+select 7, 'Seven'
+union all
+select 8, 'Eight'
+;
+
+insert into prime_numbers (num, name, n)
+select 2, 'Two', 1
+union all
+select 3, 'Three', 2
+union all
+select 5, 'Five', 3
+;
+
+commit;
diff --git a/samples/golang/migrate/sample.go b/samples/golang/migrate/sample.go
new file mode 100644
index 00000000..05de3a2a
--- /dev/null
+++ b/samples/golang/migrate/sample.go
@@ -0,0 +1,83 @@
+/*
+Copyright 2024 Google LLC
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+    http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package main
+
+import (
+	"context"
+	"fmt"
+	"os"
+
+	pgadapter "github.com/GoogleCloudPlatform/pgadapter/wrappers/golang"
+	"github.com/golang-migrate/migrate/v4"
+	_ "github.com/golang-migrate/migrate/v4/database/postgres"
+	_ "github.com/golang-migrate/migrate/v4/source/file"
+)
+
+func main() {
+	msg, err := runSample()
+	if err != nil {
+		fmt.Printf("Failed to run migrations: %v", err)
+		os.Exit(1)
+	}
+	fmt.Println(msg)
+}
+
+func runSample() (string, error) {
+	ctx := context.Background()
+
+	// Start a PGAdapter instance with the emulator embedded and connect to this.
+	pg, err := pgadapter.Start(ctx, pgadapter.Config{
+		Project:           "emulator-project",
+		Instance:          "test-instance",
+		ConnectToEmulator: true,
+	})
+	if err != nil {
+		fmt.Printf("failed to start PGAdapter: %v\n", err)
+		return "", err
+	}
+	// Stop PGAdapter when this function returns.
+	// This is not required, as the PGAdapter sub-process shuts down automatically when your
+	// application shuts down. The PGAdapter sub-process is not guaranteed to shut down if
+	// your application is killed or crashes.
+	defer pg.Stop(ctx)
+
+	// Get the TCP port that was assigned to PGAdapter.
+	port, err := pg.GetHostPort()
+	if err != nil {
+		fmt.Printf("failed to start get TCP port for PGAdapter: %v\n", err)
+		return "", err
+	}
+
+	// Connect to PGAdapter and execute the migrations.
+	database := "test-database"
+
+	// IMPORTANT: PGAdapter will only recognize the Golang migrate tool if you set this application name
+	//            in the connection string!
+	applicationName := "golang-migrate"
+
+	connString := fmt.Sprintf("postgres://localhost:%d/%s?sslmode=disable&fallback_application_name=%s", port, database, applicationName)
+	m, err := migrate.New("file://migrations", connString)
+	if err != nil {
+		return "", err
+	}
+	// Execute the 2 first migration steps.
+	if err := m.Steps(2); err != nil {
+		return "", err
+	}
+	// Execute all remaining migration steps.
+	if err := m.Up(); err != nil {
+		return "", err
+	}
+	return "Finished running migrations on Spanner", nil
+}
diff --git a/samples/golang/pgx/go.mod b/samples/golang/pgx/go.mod
index 3a61652b..f9a473ae 100644
--- a/samples/golang/pgx/go.mod
+++ b/samples/golang/pgx/go.mod
@@ -1,9 +1,11 @@
 module pgadapter-pgx-sample
 
-go 1.21
+go 1.22
+
+toolchain go1.23.2
 
 require (
-	github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20240912183532-c756559e4665
+	github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20241022193243-92bc36f15266
 	github.com/jackc/pgx/v5 v5.7.1
 )
 
@@ -15,9 +17,10 @@ require (
 	github.com/cenkalti/backoff/v4 v4.2.1 // indirect
 	github.com/containerd/log v0.1.0 // indirect
 	github.com/containerd/platforms v0.2.1 // indirect
-	github.com/cpuguy83/dockercfg v0.3.1 // indirect
+	github.com/cpuguy83/dockercfg v0.3.2 // indirect
+	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/distribution/reference v0.6.0 // indirect
-	github.com/docker/docker v27.2.1+incompatible // indirect
+	github.com/docker/docker v27.3.1+incompatible // indirect
 	github.com/docker/go-connections v0.5.0 // indirect
 	github.com/docker/go-units v0.5.0 // indirect
 	github.com/felixge/httpsnoop v1.0.4 // indirect
@@ -41,11 +44,13 @@ require (
 	github.com/opencontainers/go-digest v1.0.0 // indirect
 	github.com/opencontainers/image-spec v1.1.0 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
 	github.com/shirou/gopsutil/v3 v3.23.12 // indirect
 	github.com/shoenig/go-m1cpu v0.1.6 // indirect
 	github.com/sirupsen/logrus v1.9.3 // indirect
-	github.com/testcontainers/testcontainers-go v0.33.0 // indirect
+	github.com/stretchr/testify v1.9.0 // indirect
+	github.com/testcontainers/testcontainers-go v0.34.0 // indirect
 	github.com/tklauser/go-sysconf v0.3.12 // indirect
 	github.com/tklauser/numcpus v0.6.1 // indirect
 	github.com/yusufpapurcu/wmi v1.2.3 // indirect
@@ -59,4 +64,5 @@ require (
 	golang.org/x/oauth2 v0.23.0 // indirect
 	golang.org/x/sys v0.25.0 // indirect
 	golang.org/x/text v0.18.0 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
diff --git a/samples/golang/pgx/go.sum b/samples/golang/pgx/go.sum
index b065b5a6..cfb792c3 100644
--- a/samples/golang/pgx/go.sum
+++ b/samples/golang/pgx/go.sum
@@ -6,10 +6,12 @@ github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9
 github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
 github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
 github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
-github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20240905145036-8e4420f4237b h1:paFLGSEOD37Kg1FwYHEOd8pmctcFjqtELrRvVA6BU+s=
-github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20240905145036-8e4420f4237b/go.mod h1:AePg/g/kQCpx2r82bOQyF4HN/ZOX5SUcEuJz09MYpjA=
 github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20240912183532-c756559e4665 h1:y2O+wODDmfREw15/LE1jkIziNJLYOVq3cllbu85H6kg=
 github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20240912183532-c756559e4665/go.mod h1:o0VdiWILEdFOmmWaLjI/CR1cojsHX748rEmqb++PfOU=
+github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20240919150510-c310ce84d0c9 h1:3JCzAQ/YdZ/wrGq3wgGQq24uG/IHfnlq2TPpGQqWiTE=
+github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20240919150510-c310ce84d0c9/go.mod h1:o0VdiWILEdFOmmWaLjI/CR1cojsHX748rEmqb++PfOU=
+github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20241022193243-92bc36f15266 h1:5uo7tPRv0+14g/+dZKQrBg9hQVWWNCtOl3G8tZuFOM8=
+github.com/GoogleCloudPlatform/pgadapter/wrappers/golang v0.0.0-20241022193243-92bc36f15266/go.mod h1:tPyvuD/QQH7tjAAjLzxjPK/L6DAybS/UO7kEA32XqSE=
 github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
 github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
 github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
@@ -20,6 +22,8 @@ github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpS
 github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw=
 github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E=
 github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
+github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA=
+github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
 github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
 github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -27,10 +31,10 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
 github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
-github.com/docker/docker v27.2.0+incompatible h1:Rk9nIVdfH3+Vz4cyI/uhbINhEZ/oLmc+CBXmH6fbNk4=
-github.com/docker/docker v27.2.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 github.com/docker/docker v27.2.1+incompatible h1:fQdiLfW7VLscyoeYEBz7/J8soYFDZV1u6VW6gJEjNMI=
 github.com/docker/docker v27.2.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI=
+github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
 github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
 github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
@@ -114,6 +118,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
 github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 github.com/testcontainers/testcontainers-go v0.33.0 h1:zJS9PfXYT5O0ZFXM2xxXfk4J5UMw/kRiISng037Gxdw=
 github.com/testcontainers/testcontainers-go v0.33.0/go.mod h1:W80YpTa8D5C3Yy16icheD01UTDu+LmXIA2Keo+jWtT8=
+github.com/testcontainers/testcontainers-go v0.34.0 h1:5fbgF0vIN5u+nD3IWabQwRybuB4GY8G2HHgCkbMzMHo=
+github.com/testcontainers/testcontainers-go v0.34.0/go.mod h1:6P/kMkQe8yqPHfPWNulFGdFHTD8HB2vLq/231xY2iPQ=
 github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
 github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
 github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
@@ -151,8 +157,6 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
 golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
-golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
-golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
 golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
 golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
diff --git a/samples/java/cloud-run/Dockerfile b/samples/java/cloud-run/Dockerfile
index 6f5244fb..8dfa1c59 100644
--- a/samples/java/cloud-run/Dockerfile
+++ b/samples/java/cloud-run/Dockerfile
@@ -24,7 +24,7 @@ COPY src ./src
 RUN mvn package -DskipTests
 
 # Use AdoptOpenJDK for base image.
-FROM eclipse-temurin:22-jre-alpine
+FROM eclipse-temurin:23-jre-alpine
 
 # Copy the jar to the production image from the builder stage.
 COPY --from=builder /app/target/google-cloud-spanner-pgadapter-samples-cloud-run-*.jar /google-cloud-spanner-pgadapter-samples-cloud-run.jar
diff --git a/samples/java/cloud-run/pom.xml b/samples/java/cloud-run/pom.xml
index 33e939ed..bcd061a6 100644
--- a/samples/java/cloud-run/pom.xml
+++ b/samples/java/cloud-run/pom.xml
@@ -18,7 +18,7 @@
     <maven.compiler.source>17</maven.compiler.source>
     <maven.compiler.target>17</maven.compiler.target>
     <java.version>17</java.version>
-    <junixsocket.version>2.10.0</junixsocket.version>
+    <junixsocket.version>2.10.1</junixsocket.version>
   </properties>
 
   <modelVersion>4.0.0</modelVersion>
@@ -36,7 +36,7 @@
       <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-dependencies</artifactId>
-        <version>3.3.3</version>
+        <version>3.3.5</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
@@ -53,7 +53,7 @@
     <dependency>
       <groupId>com.google.cloud</groupId>
       <artifactId>google-cloud-spanner-pgadapter</artifactId>
-      <version>0.37.0</version>
+      <version>0.40.0</version>
     </dependency>
     <dependency>
       <groupId>com.kohlschutter.junixsocket</groupId>
@@ -96,7 +96,7 @@
       <plugin>
         <groupId>com.google.cloud.tools</groupId>
         <artifactId>jib-maven-plugin</artifactId>
-        <version>3.4.3</version>
+        <version>3.4.4</version>
         <configuration>
           <to>
             <image>gcr.io/PROJECT_ID/pgadapter-example</image>
@@ -106,7 +106,7 @@
       <plugin>
         <groupId>com.spotify.fmt</groupId>
         <artifactId>fmt-maven-plugin</artifactId>
-        <version>2.24</version>
+        <version>2.25</version>
         <executions>
           <execution>
             <goals>
diff --git a/samples/java/hibernate/pom.xml b/samples/java/hibernate/pom.xml
index 1092482d..7677e565 100644
--- a/samples/java/hibernate/pom.xml
+++ b/samples/java/hibernate/pom.xml
@@ -21,7 +21,7 @@
       <dependency>
         <groupId>org.testcontainers</groupId>
         <artifactId>testcontainers-bom</artifactId>
-        <version>1.20.1</version>
+        <version>1.20.3</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
@@ -33,7 +33,7 @@
     <dependency>
       <groupId>com.google.cloud</groupId>
       <artifactId>google-cloud-spanner-pgadapter</artifactId>
-      <version>0.37.0</version>
+      <version>0.40.0</version>
     </dependency>
     <!-- Hibernate core dependency -->
     <dependency>
@@ -51,13 +51,13 @@
     <dependency>
       <groupId>com.google.cloud</groupId>
       <artifactId>google-cloud-spanner-hibernate-tools</artifactId>
-      <version>3.4.1</version>
+      <version>3.7.1</version>
     </dependency>
     <!-- Add Hypersistence Utils for access to additional data type mappings, for example for arrays. -->
     <dependency>
       <groupId>io.hypersistence</groupId>
       <artifactId>hypersistence-utils-hibernate-63</artifactId>
-      <version>3.8.2</version>
+      <version>3.8.3</version>
     </dependency>
     <!-- Add testcontainers, so we can run a Docker container with PGAdapter+Spanner Emulator -->
     <dependency>
@@ -69,7 +69,7 @@
     <dependency>
       <groupId>com.fasterxml.jackson.core</groupId>
       <artifactId>jackson-databind</artifactId>
-      <version>2.17.2</version>
+      <version>2.18.1</version>
     </dependency>
     
     <!-- NOTE: This dependency is deliberately not defined with scope <test>, as that breaks the use of testcontainers in the sample application. -->
@@ -85,7 +85,7 @@
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>exec-maven-plugin</artifactId>
-        <version>3.4.1</version>
+        <version>3.5.0</version>
         <configuration>
           <mainClass>com.google.cloud.postgres.SampleApplication</mainClass>
           <cleanupDaemonThreads>false</cleanupDaemonThreads>
diff --git a/samples/java/jdbc/README.md b/samples/java/jdbc/README.md
index 38a741fe..ac149ff5 100644
--- a/samples/java/jdbc/README.md
+++ b/samples/java/jdbc/README.md
@@ -14,12 +14,12 @@ The sample application adds the following dependencies:
 <dependency>
   <groupId>org.postgresql</groupId>
   <artifactId>postgresql</artifactId>
-  <version>0.37.0</version>
+  <version>0.40.0</version>
 </dependency>
 <dependency>
   <groupId>com.google.cloud</groupId>
   <artifactId>google-cloud-spanner-pgadapter</artifactId>
-  <version>0.37.0</version>
+  <version>0.40.0</version>
 </dependency>
 <!-- [END pgadapter_and_jdbc_dependency] -->
 ```
diff --git a/samples/java/jdbc/pom.xml b/samples/java/jdbc/pom.xml
index c16fafcd..e8bb30f5 100644
--- a/samples/java/jdbc/pom.xml
+++ b/samples/java/jdbc/pom.xml
@@ -21,7 +21,7 @@
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 
-    <junixsocket.version>2.10.0</junixsocket.version>
+    <junixsocket.version>2.10.1</junixsocket.version>
   </properties>
 
   <modelVersion>4.0.0</modelVersion>
@@ -39,7 +39,7 @@
       <dependency>
         <groupId>org.testcontainers</groupId>
         <artifactId>testcontainers-bom</artifactId>
-        <version>1.20.1</version>
+        <version>1.20.3</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
@@ -56,7 +56,7 @@
     <dependency>
       <groupId>com.google.cloud</groupId>
       <artifactId>google-cloud-spanner-pgadapter</artifactId>
-      <version>0.37.0</version>
+      <version>0.40.0</version>
     </dependency>
     <!-- [END pgadapter_and_jdbc_dependency] -->
     <dependency>
@@ -80,7 +80,7 @@
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>exec-maven-plugin</artifactId>
-        <version>3.4.1</version>
+        <version>3.5.0</version>
         <configuration>
           <mainClass>com.google.cloud.spanner.pgadapter.sample.SampleApplication</mainClass>
           <cleanupDaemonThreads>false</cleanupDaemonThreads>
diff --git a/samples/java/liquibase/pom.xml b/samples/java/liquibase/pom.xml
index 729c4747..61d95584 100644
--- a/samples/java/liquibase/pom.xml
+++ b/samples/java/liquibase/pom.xml
@@ -37,7 +37,7 @@
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-shared-config</artifactId>
-    <version>1.11.1</version>
+    <version>1.11.3</version>
   </parent>
   <scm>
     <connection>scm:git:git@github.com:GoogleCloudPlatform/pgadapter.git</connection>
diff --git a/samples/java/r2dbc/README.md b/samples/java/r2dbc/README.md
new file mode 100644
index 00000000..f0479fb0
--- /dev/null
+++ b/samples/java/r2dbc/README.md
@@ -0,0 +1,88 @@
+# R2DBC sample
+
+This sample application shows how to connect to Cloud Spanner through PGAdapter using the standard
+`R2DBC` PostgreSQL driver. PGAdapter is automatically started in-process together with the sample
+application.
+
+### Dependencies
+
+The sample application adds the following dependencies:
+
+<!--- {x-version-update-start:google-cloud-spanner-pgadapter:released} -->
+```xml
+<dependency>
+  <groupId>org.postgresql</groupId>
+  <artifactId>r2dbc-postgresql</artifactId>
+  <version>1.0.5.RELEASE</version>
+</dependency>
+<dependency>
+  <groupId>com.google.cloud</groupId>
+  <artifactId>google-cloud-spanner-pgadapter</artifactId>
+  <version>0.39.0</version>
+</dependency>
+```
+<!--- {x-version-update-end} -->
+
+### Connecting
+PGAdapter is started in-process with the sample application:
+
+```java
+OptionsMetadata.Builder builder =
+    OptionsMetadata.newBuilder()
+        .setProject(project)
+        .setInstance(instance)
+        // Start PGAdapter on any available port.
+        .setPort(0);
+ProxyServer server = new ProxyServer(builder.build());
+server.startServer();
+server.awaitRunning();
+```
+
+The PostgreSQL R2DBC driver can connect to the in-process PGAdapter instance:
+
+```java
+ConnectionFactory connectionFactory = ConnectionFactories.get(ConnectionFactoryOptions.builder()
+    .option(DRIVER, "postgresql")
+    .option(HOST, "localhost")
+    .option(PORT, port) 
+    .option(USER, "")
+    .option(PASSWORD, "")
+    .option(DATABASE, database)
+    .option(OPTIONS, options)
+    .build());
+
+CountDownLatch finished = new CountDownLatch(1);
+Flux.usingWhen(
+        connectionFactory.create(),
+        connection ->
+            Flux.from(connection.createStatement(
+                        "select 'Hello World!' as greeting")
+                    .execute())
+                .flatMap(result ->
+                    result.map(row -> row.get("greeting", String.class))),
+        Connection::close)
+    .doOnNext(greeting -> System.out.printf("\nGreeting: %s\n\n", greeting))
+    .doOnError(Throwable::printStackTrace)
+    .doFinally(ignore -> finished.countDown())
+    .subscribe();
+
+finished.await();
+```
+
+### Run Sample
+
+Run the sample on the Spanner Emulator with the following command:
+
+```shell
+mvn exec:java
+```
+
+Run the sample on a real Spanner instance with the following command:
+
+```shell
+mvn exec:java \
+  -Dexec.args=" \
+    -p my-project \
+    -i my-instance \
+    -d my-database"
+```
diff --git a/samples/java/r2dbc/pom.xml b/samples/java/r2dbc/pom.xml
new file mode 100644
index 00000000..e643dff7
--- /dev/null
+++ b/samples/java/r2dbc/pom.xml
@@ -0,0 +1,83 @@
+<!--
+ Copyright 2022 Google LLC
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+      http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <properties>
+    <java.version>1.8</java.version>
+    <maven.compiler.source>1.8</maven.compiler.source>
+    <maven.compiler.target>1.8</maven.compiler.target>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+
+    <junixsocket.version>2.10.1</junixsocket.version>
+  </properties>
+
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.google.cloud</groupId>
+  <artifactId>google-cloud-spanner-pgadapter-samples-r2dbc</artifactId>
+  <version>0.1.0-SNAPSHOT</version>
+  <name>Google Cloud Spanner PGAdapter R2DBC Sample</name>
+  <packaging>jar</packaging>
+  <description>
+    Sample for using the PostgreSQL R2DBC driver with PGAdapter
+  </description>
+  
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.testcontainers</groupId>
+        <artifactId>testcontainers-bom</artifactId>
+        <version>1.20.3</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.postgresql</groupId>
+      <artifactId>r2dbc-postgresql</artifactId>
+      <version>1.0.7.RELEASE</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.cloud</groupId>
+      <artifactId>google-cloud-spanner-pgadapter</artifactId>
+      <version>0.40.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.testcontainers</groupId>
+      <artifactId>testcontainers</artifactId>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>exec-maven-plugin</artifactId>
+        <version>3.5.0</version>
+        <configuration>
+          <mainClass>com.google.cloud.spanner.pgadapter.sample.SampleApplication</mainClass>
+          <cleanupDaemonThreads>false</cleanupDaemonThreads>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>com.coveo</groupId>
+        <artifactId>fmt-maven-plugin</artifactId>
+        <version>2.13</version>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/samples/java/r2dbc/src/main/java/com/google/cloud/spanner/pgadapter/sample/SampleApplication.java b/samples/java/r2dbc/src/main/java/com/google/cloud/spanner/pgadapter/sample/SampleApplication.java
new file mode 100644
index 00000000..2c8f79e3
--- /dev/null
+++ b/samples/java/r2dbc/src/main/java/com/google/cloud/spanner/pgadapter/sample/SampleApplication.java
@@ -0,0 +1,266 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.cloud.spanner.pgadapter.sample;
+
+import static io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider.OPTIONS;
+import static io.r2dbc.spi.ConnectionFactoryOptions.DATABASE;
+import static io.r2dbc.spi.ConnectionFactoryOptions.DRIVER;
+import static io.r2dbc.spi.ConnectionFactoryOptions.HOST;
+import static io.r2dbc.spi.ConnectionFactoryOptions.PASSWORD;
+import static io.r2dbc.spi.ConnectionFactoryOptions.PORT;
+import static io.r2dbc.spi.ConnectionFactoryOptions.USER;
+
+import com.google.cloud.spanner.connection.SpannerPool;
+import com.google.cloud.spanner.pgadapter.ProxyServer;
+import com.google.cloud.spanner.pgadapter.metadata.OptionsMetadata;
+import io.r2dbc.spi.Connection;
+import io.r2dbc.spi.ConnectionFactories;
+import io.r2dbc.spi.ConnectionFactory;
+import io.r2dbc.spi.ConnectionFactoryOptions;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.wait.strategy.Wait;
+import org.testcontainers.utility.DockerImageName;
+import reactor.core.publisher.Flux;
+
+/**
+ * Sample application for connecting to Cloud Spanner using the PostgreSQL R2DBC driver. This sample
+ * application starts an embedded in-process PGAdapter instance together with the sample application
+ * and connects to it.
+ *
+ * <p>Run the sample application using the Cloud Spanner Emulator as follows:
+ *
+ * <pre>{@code
+ * mvn exec:java
+ * }</pre>
+ *
+ * <p>Run the sample application using default credentials as follows:
+ *
+ * <pre>{@code
+ * mvn exec:java \
+ *   -Dexec.args=" \
+ *     -p my-project \
+ *     -i my-instance \
+ *     -d my-database"
+ * }</pre>
+ *
+ * <p>Run the sample application using a specific credential file as follows:
+ *
+ * <pre>{@code
+ * mvn exec:java \
+ *   -Dexec.args=" \
+ *     -p my-project \
+ *     -i my-instance \
+ *     -d my-database \
+ *     -c /path/to/credentials.json"
+ * }</pre>
+ */
+public class SampleApplication {
+
+  /**
+   * Reads the options from the command line, starts PGAdapter, connects using the PostgreSQL R2DBC
+   * driver, and executes a simple query on Cloud Spanner.
+   */
+  public static void main(String[] args) throws Exception {
+    // Read command line arguments.
+    CommandLine commandLine = parseCommandLine(args);
+    // Use the Cloud Spanner Emulator if no project/instance/database has been specified.
+    boolean useEmulator = commandLine.getOptions().length == 0;
+
+    String project = commandLine.getOptionValue('p', "my-project");
+    String instance = commandLine.getOptionValue('i', "my-instance");
+    String database = commandLine.getOptionValue('d', "my-database");
+    String credentials = commandLine.getOptionValue('c');
+
+    // Start PGAdapter in-process or as a Docker container with the Cloud Spanner Emulator.
+    // The server will be started on a random available port.
+    Server server =
+        useEmulator ? startPGAdapterWithEmulator() : startPGAdapter(project, instance, credentials);
+    try {
+      runSample(server.getPort(), database);
+    } finally {
+      server.shutdown();
+      SpannerPool.closeSpannerPool();
+    }
+  }
+
+  /** Connects to PGAdapter using the PostgreSQL R2DBC driver and executes a simple query. */
+  static void runSample(int port, String database) throws Exception {
+    Map<String, String> options = new HashMap<>();
+    options.put("lock_timeout", "10s");
+    options.put("statement_timeout", "5m");
+
+    ConnectionFactory connectionFactory = ConnectionFactories.get(ConnectionFactoryOptions.builder()
+        .option(DRIVER, "postgresql")
+        .option(HOST, "localhost")
+        .option(PORT, port) 
+        .option(USER, "")
+        .option(PASSWORD, "")
+        .option(DATABASE, database)
+        .option(OPTIONS, options)
+        .build());
+
+    CountDownLatch finished = new CountDownLatch(1);
+    Flux.usingWhen(
+            connectionFactory.create(),
+            connection ->
+                Flux.from(connection.createStatement(
+                            "select 'Hello World!' as greeting")
+                        .execute())
+                    .flatMap(result ->
+                        result.map(row -> row.get("greeting", String.class))),
+            Connection::close)
+        .doOnNext(greeting -> System.out.printf("\nGreeting: %s\n\n", greeting))
+        .doOnError(Throwable::printStackTrace)
+        .doFinally(ignore -> finished.countDown())
+        .subscribe();
+
+    finished.await();
+  }
+  
+  /**
+   * Starts PGAdapter in-process and returns a reference to the server. Use this reference to
+   * gracefully shut down the server when your application shuts down.
+   *
+   * @param project the Google Cloud project that PGAdapter should connect to
+   * @param instance the Cloud Spanner instance that PGAdapter should connect to
+   * @param credentialsFile the full path of a credentials file that PGAdapter should use, or <code>
+   *     null</code> if PGAdapter should use the application default credentials
+   */
+  static Server startPGAdapter(String project, String instance, String credentialsFile) {
+    OptionsMetadata.Builder builder =
+        OptionsMetadata.newBuilder()
+            .setProject(project)
+            .setInstance(instance)
+            // Start PGAdapter on any available port.
+            .setPort(0);
+    if (credentialsFile != null) {
+      builder.setCredentialsFile(credentialsFile);
+    }
+    ProxyServer server = new ProxyServer(builder.build());
+    server.startServer();
+    server.awaitRunning();
+
+    return new PGAdapter(server);
+  }
+
+  /** Starts a Docker container that contains both PGAdapter and the Cloud Spanner Emulator. */
+  static Server startPGAdapterWithEmulator() {
+    GenericContainer<?> container =
+        new GenericContainer<>(
+            DockerImageName.parse("gcr.io/cloud-spanner-pg-adapter/pgadapter-emulator"));
+    container.addExposedPort(5432);
+    container.setWaitStrategy(Wait.forListeningPorts(5432));
+    container.start();
+
+    return new PGAdapterWithEmulator(container);
+  }
+
+  static CommandLine parseCommandLine(String[] args) {
+    String commandLineArguments =
+        "pgadapter [-p <project> -i <instance> -d <database> -c <credentials_file>]";
+
+    CommandLineParser parser = new DefaultParser();
+    HelpFormatter help = new HelpFormatter();
+    help.setWidth(120);
+    Options options = createOptions();
+    try {
+      CommandLine commandLine = parser.parse(options, args);
+      if (commandLine.hasOption('h')) {
+        help.printHelp(commandLineArguments, options);
+        System.exit(0);
+      }
+      return commandLine;
+    } catch (ParseException e) {
+      help.printHelp(commandLineArguments, options);
+      throw new IllegalArgumentException(e.getMessage());
+    }
+  }
+
+  static Options createOptions() {
+    Options options = new Options();
+    options.addOption(
+        "p", "project", true, "The Google Cloud project ID that PGAdapter should connect to.");
+    options.addOption(
+        "i",
+        "instance",
+        true,
+        "The id of the Cloud Spanner instance that PGAdapter should connect to.");
+    options.addOption(
+        "d",
+        "database",
+        true,
+        "The id of the database that the R2DBC driver should connect to.");
+    options.addOption(
+        "c",
+        "credentials",
+        true,
+        "The full path of a Google Cloud credentials file that should be used. "
+            + "If not specified, the sample application will try to read the application default "
+            + "credentials.");
+    return options;
+  }
+
+  interface Server {
+    int getPort();
+
+    void shutdown();
+  }
+
+  static class PGAdapterWithEmulator implements Server {
+    private final GenericContainer<?> container;
+
+    PGAdapterWithEmulator(GenericContainer<?> container) {
+      this.container = container;
+    }
+
+    @Override
+    public int getPort() {
+      return container.getMappedPort(5432);
+    }
+
+    @Override
+    public void shutdown() {
+      container.stop();
+    }
+  }
+
+  static class PGAdapter implements Server {
+    private final ProxyServer server;
+
+    PGAdapter(ProxyServer server) {
+      this.server = server;
+    }
+
+    @Override
+    public int getPort() {
+      return server.getLocalPort();
+    }
+
+    @Override
+    public void shutdown() {
+      server.stopServer();
+      server.awaitTerminated();
+    }
+  }
+}
diff --git a/samples/java/spring-data-jpa/pom.xml b/samples/java/spring-data-jpa/pom.xml
index ebef5c9d..9da95e96 100644
--- a/samples/java/spring-data-jpa/pom.xml
+++ b/samples/java/spring-data-jpa/pom.xml
@@ -5,7 +5,7 @@
   <parent>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-parent</artifactId>
-    <version>3.3.3</version>
+    <version>3.3.5</version>
     <relativePath/> <!-- lookup parent from repository -->
   </parent>
   <groupId>com.google.cloud.spanner</groupId>
@@ -22,7 +22,7 @@
       <dependency>
         <groupId>org.testcontainers</groupId>
         <artifactId>testcontainers-bom</artifactId>
-        <version>1.20.1</version>
+        <version>1.20.3</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
@@ -55,19 +55,19 @@
     <dependency>
       <groupId>com.google.cloud</groupId>
       <artifactId>google-cloud-spanner-pgadapter</artifactId>
-      <version>0.37.0</version>
+      <version>0.40.0</version>
     </dependency>
     <!-- Add Spanner Hibernate tools for access to the batch compatible bit-reversed sequence generator. -->
     <dependency>
       <groupId>com.google.cloud</groupId>
       <artifactId>google-cloud-spanner-hibernate-tools</artifactId>
-      <version>3.4.1</version>
+      <version>3.7.1</version>
     </dependency>
     <!-- Add Hypersistence Utils for access to additional data type mappings, for example for arrays. -->
     <dependency>
       <groupId>io.hypersistence</groupId>
       <artifactId>hypersistence-utils-hibernate-63</artifactId>
-      <version>3.8.2</version>
+      <version>3.8.3</version>
     </dependency>
     <dependency>
       <groupId>org.springframework.boot</groupId>
@@ -111,7 +111,7 @@
       <plugin>
         <groupId>com.spotify.fmt</groupId>
         <artifactId>fmt-maven-plugin</artifactId>
-        <version>2.24</version>
+        <version>2.25</version>
         <executions>
           <execution>
             <goals>
diff --git a/samples/java/spring-data-jpa/src/main/java/com/google/cloud/spanner/pgadapter/sample/SampleApplication.java b/samples/java/spring-data-jpa/src/main/java/com/google/cloud/spanner/pgadapter/sample/SampleApplication.java
index 17ff8fc0..ae6c4540 100644
--- a/samples/java/spring-data-jpa/src/main/java/com/google/cloud/spanner/pgadapter/sample/SampleApplication.java
+++ b/samples/java/spring-data-jpa/src/main/java/com/google/cloud/spanner/pgadapter/sample/SampleApplication.java
@@ -17,6 +17,7 @@ package com.google.cloud.spanner.pgadapter.sample;
 import com.google.cloud.spanner.pgadapter.sample.model.Concert;
 import com.google.cloud.spanner.pgadapter.sample.repository.ConcertRepository;
 import com.google.cloud.spanner.pgadapter.sample.service.AlbumService;
+import com.google.cloud.spanner.pgadapter.sample.service.BatchService;
 import com.google.cloud.spanner.pgadapter.sample.service.ConcertService;
 import com.google.cloud.spanner.pgadapter.sample.service.DirectedReadService;
 import com.google.cloud.spanner.pgadapter.sample.service.SingerService;
@@ -90,6 +91,8 @@ public class SampleApplication implements CommandLineRunner {
 
   private final TicketSaleService ticketSaleService;
 
+  private final BatchService batchService;
+
   public SampleApplication(
       SingerService singerService,
       AlbumService albumService,
@@ -99,7 +102,8 @@ public class SampleApplication implements CommandLineRunner {
       StaleReadService staleReadService,
       DirectedReadService directedReadService,
       ConcertRepository concertRepository,
-      TicketSaleService ticketSaleService) {
+      TicketSaleService ticketSaleService,
+      BatchService batchService) {
     this.singerService = singerService;
     this.albumService = albumService;
     this.trackService = trackService;
@@ -109,6 +113,7 @@ public class SampleApplication implements CommandLineRunner {
     this.directedReadService = directedReadService;
     this.concertRepository = concertRepository;
     this.ticketSaleService = ticketSaleService;
+    this.batchService = batchService;
   }
 
   @Override
@@ -140,6 +145,15 @@ public class SampleApplication implements CommandLineRunner {
     staleRead();
     // Show how to execute queries with directed read options.
     directedRead();
+
+    // Show how to execute multiple DML statements in one Batch DML request. This reduces the number
+    // of round-trips between PGAdapter and Spanner.
+    batchService.generateRandomDataInOneBatch(5);
+
+    // Show how to execute multiple DML statements in an automatic DML batch. This reduces the
+    // number of round-trips between PGAdapter and Spanner, and allows even more DML statements to
+    // be combined into one batch than standard batching.
+    batchService.generateRandomDataInAutoBatch(5);
   }
 
   void printData() {
diff --git a/samples/java/spring-data-jpa/src/main/java/com/google/cloud/spanner/pgadapter/sample/service/AlbumService.java b/samples/java/spring-data-jpa/src/main/java/com/google/cloud/spanner/pgadapter/sample/service/AlbumService.java
index aa178a6a..6f2b8323 100644
--- a/samples/java/spring-data-jpa/src/main/java/com/google/cloud/spanner/pgadapter/sample/service/AlbumService.java
+++ b/samples/java/spring-data-jpa/src/main/java/com/google/cloud/spanner/pgadapter/sample/service/AlbumService.java
@@ -19,6 +19,7 @@ import com.google.cloud.spanner.pgadapter.sample.model.Singer;
 import com.google.cloud.spanner.pgadapter.sample.repository.AlbumRepository;
 import com.google.cloud.spanner.pgadapter.sample.repository.SingerRepository;
 import jakarta.transaction.Transactional;
+import jakarta.transaction.Transactional.TxType;
 import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.util.ArrayList;
@@ -51,10 +52,18 @@ public class AlbumService {
 
   @Transactional
   public List<Album> generateRandomAlbums(int count) {
-    Random random = new Random();
-
     // Get the first 20 singers and link the albums to those.
     List<Singer> singers = singerRepository.findAll(Pageable.ofSize(20)).toList();
+    return albumRepository.saveAll(generateRandomAlbums(count, singers));
+  }
+
+  /**
+   * Generates a batch of random albums. This method may only be called when a transaction is
+   * already active.
+   */
+  @Transactional(TxType.MANDATORY)
+  public List<Album> generateRandomAlbums(int count, List<Singer> singers) {
+    Random random = new Random();
     List<Album> albums = new ArrayList<>(count);
     for (int i = 0; i < count; i++) {
       Album album = new Album();
diff --git a/samples/java/spring-data-jpa/src/main/java/com/google/cloud/spanner/pgadapter/sample/service/BatchService.java b/samples/java/spring-data-jpa/src/main/java/com/google/cloud/spanner/pgadapter/sample/service/BatchService.java
new file mode 100644
index 00000000..106830d6
--- /dev/null
+++ b/samples/java/spring-data-jpa/src/main/java/com/google/cloud/spanner/pgadapter/sample/service/BatchService.java
@@ -0,0 +1,151 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.cloud.spanner.pgadapter.sample.service;
+
+import com.google.cloud.spanner.pgadapter.sample.model.Album;
+import com.google.cloud.spanner.pgadapter.sample.model.Concert;
+import com.google.cloud.spanner.pgadapter.sample.model.Singer;
+import com.google.cloud.spanner.pgadapter.sample.model.Venue;
+import jakarta.persistence.EntityManager;
+import jakarta.persistence.PersistenceContext;
+import jakarta.transaction.Transactional;
+import java.sql.Statement;
+import java.util.List;
+import org.hibernate.Session;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+/**
+ * This service shows how to use DML batching to execute a large number of DML statements as a
+ * single ExecuteBatchDml request when using Spring Data JPA / Hibernate with PGAdapter.
+ */
+@Service
+public class BatchService {
+  private static final Logger log = LoggerFactory.getLogger(BatchService.class);
+
+  private final SingerService singerService;
+  private final AlbumService albumService;
+  private final VenueService venueService;
+  private final ConcertService concertService;
+
+  @PersistenceContext private EntityManager entityManager;
+
+  public BatchService(
+      SingerService singerService,
+      AlbumService albumService,
+      VenueService venueService,
+      ConcertService concertService) {
+    this.singerService = singerService;
+    this.albumService = albumService;
+    this.venueService = venueService;
+    this.concertService = concertService;
+  }
+
+  /**
+   * Generates a batch of random singers, albums, venues and concerts in one DML batch. This method
+   * shows how to unwrap the underlying JDBC connection and use this to execute custom SQL
+   * statements. This is used to create a single batch of DML statements that is sent as one request
+   * to Spanner. This can significantly reduce the number of round-trips between PGAdapter and
+   * Spanner when executing a large number of DML statements.
+   *
+   * <p>See also <a
+   * href="https://cloud.google.com/spanner/docs/pgadapter-session-mgmt-commands#batch-statements">
+   * PGAdapter Batch Statements </a>.
+   */
+  @Transactional
+  public void generateRandomDataInOneBatch(int count) {
+    log.info("Generating {} singers and other random data in one batch", count);
+
+    // Get hold of the underlying Hibernate session.
+    Session session = entityManager.unwrap(Session.class);
+    // Get hold of the underlying JDBC connection that is used by the current Hibernate session.
+    // This connection can be used to execute custom SQL statements to change the state of the
+    // connection.
+    session.doWork(
+        connection -> {
+          try (Statement statement = connection.createStatement()) {
+            // The 'spanner.dml_batch_update_count' variable determines the update count that
+            // PGAdapter returns for DML statements that are buffered in a DML batch.
+            // The default is 0. This method sets that to 1, as Hibernate expects all inserts to
+            // return update count 1.
+            // Note that 'set local' means 'change the value of this variable for the duration of
+            // the current transaction'. The value is automatically reset to the default when the
+            // transaction ends. See https://www.postgresql.org/docs/current/sql-set.html for more
+            // information on 'set local'.
+            statement.execute("set local spanner.dml_batch_update_count=1");
+            // Start a DML batch. From this point, only DML statements are allowed, and all DML
+            // statements will be buffered locally in PGAdapter and not actually sent to Spanner.
+            statement.execute("start batch dml");
+
+            // Generate some random data.
+            List<Singer> singers = singerService.generateRandomSingers(count);
+            List<Album> albums = albumService.generateRandomAlbums(count, singers);
+            List<Venue> venues = venueService.generateRandomVenues(count);
+            List<Concert> concerts = concertService.generateRandomConcerts(count, singers, venues);
+
+            // Make sure that we flush everything that has been cached by Hibernate. This ensures
+            // that all DML statements are generated by Hibernate and sent to PGAdapter. PGAdapter
+            // buffers these in memory. They will be sent to Spanner when the batch is executed.
+            session.flush();
+
+            // Execute the DML batch. This will flush all buffered DML statements from PGAdapter to
+            // Spanner. Note that this does not commit the transaction. That happens when the method
+            // call to generateRandomDataInOneBatch(int) has finished, as this method is marked as
+            // transactional.
+            connection.createStatement().execute("run batch");
+            log.info(
+                "Generated {} singers, {} albums, {} venues, and {} concerts in one batch",
+                singers.size(),
+                albums.size(),
+                venues.size(),
+                concerts.size());
+          }
+        });
+  }
+
+  @Transactional
+  public void generateRandomDataInAutoBatch(int count) {
+    log.info("Generating {} singers and other random data in one auto-batch", count);
+    try {
+      entityManager
+          .unwrap(Session.class)
+          .doWork(
+              connection ->
+                  connection.createStatement().execute("set spanner.auto_batch_dml = true"));
+
+      // Generate some random data.
+      List<Singer> singers = singerService.generateRandomSingers(count);
+      List<Album> albums = albumService.generateRandomAlbums(count, singers);
+      List<Venue> venues = venueService.generateRandomVenues(count);
+      List<Concert> concerts = concertService.generateRandomConcerts(count, singers, venues);
+
+      log.info(
+          "Generated {} singers, {} albums, {} venues, and {} concerts in one auto-batch",
+          singers.size(),
+          albums.size(),
+          venues.size(),
+          concerts.size());
+    } finally {
+      // Flush the current session and reset the auto_batch_dml property.
+      entityManager.unwrap(Session.class).flush();
+      entityManager
+          .unwrap(Session.class)
+          .doWork(
+              connection ->
+                  connection.createStatement().execute("set spanner.auto_batch_dml = false"));
+    }
+  }
+}
diff --git a/samples/java/spring-data-jpa/src/main/java/com/google/cloud/spanner/pgadapter/sample/service/ConcertService.java b/samples/java/spring-data-jpa/src/main/java/com/google/cloud/spanner/pgadapter/sample/service/ConcertService.java
index 30ab579e..c783bba4 100644
--- a/samples/java/spring-data-jpa/src/main/java/com/google/cloud/spanner/pgadapter/sample/service/ConcertService.java
+++ b/samples/java/spring-data-jpa/src/main/java/com/google/cloud/spanner/pgadapter/sample/service/ConcertService.java
@@ -21,6 +21,7 @@ import com.google.cloud.spanner.pgadapter.sample.repository.ConcertRepository;
 import com.google.cloud.spanner.pgadapter.sample.repository.SingerRepository;
 import com.google.cloud.spanner.pgadapter.sample.repository.VenueRepository;
 import jakarta.transaction.Transactional;
+import jakarta.transaction.Transactional.TxType;
 import java.time.Duration;
 import java.time.OffsetDateTime;
 import java.time.ZoneOffset;
@@ -58,10 +59,19 @@ public class ConcertService {
 
   @Transactional
   public List<Concert> generateRandomConcerts(int count) {
-    Random random = new Random();
-
     List<Singer> singers = singerRepository.findAll(Pageable.ofSize(20)).toList();
     List<Venue> venues = venueRepository.findAll();
+    return generateRandomConcerts(count, singers, venues);
+  }
+
+  /**
+   * Generates a batch of random albums. This method may only be called when a transaction is
+   * already active.
+   */
+  @Transactional(TxType.MANDATORY)
+  public List<Concert> generateRandomConcerts(int count, List<Singer> singers, List<Venue> venues) {
+    Random random = new Random();
+
     List<Concert> concerts = new ArrayList<>(count);
     for (int i = 0; i < count; i++) {
       Concert concert = new Concert();
diff --git a/samples/java/spring-data-jpa/src/main/java/com/google/cloud/spanner/pgadapter/sample/service/TrackService.java b/samples/java/spring-data-jpa/src/main/java/com/google/cloud/spanner/pgadapter/sample/service/TrackService.java
index 0ca06234..b84491b2 100644
--- a/samples/java/spring-data-jpa/src/main/java/com/google/cloud/spanner/pgadapter/sample/service/TrackService.java
+++ b/samples/java/spring-data-jpa/src/main/java/com/google/cloud/spanner/pgadapter/sample/service/TrackService.java
@@ -19,6 +19,7 @@ import com.google.cloud.spanner.pgadapter.sample.model.Track;
 import com.google.cloud.spanner.pgadapter.sample.repository.AlbumRepository;
 import com.google.cloud.spanner.pgadapter.sample.repository.TrackRepository;
 import jakarta.transaction.Transactional;
+import jakarta.transaction.Transactional.TxType;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Random;
@@ -44,9 +45,14 @@ public class TrackService {
 
   @Transactional
   public void generateRandomTracks(int numAlbums, int numTracksPerAlbum) {
+    List<Album> albums = albumRepository.findAll(Pageable.ofSize(numAlbums)).toList();
+    generateRandomTracks(numAlbums, numTracksPerAlbum, albums);
+  }
+
+  @Transactional(TxType.MANDATORY)
+  public void generateRandomTracks(int numAlbums, int numTracksPerAlbum, List<Album> albums) {
     Random random = new Random();
 
-    List<Album> albums = albumRepository.findAll(Pageable.ofSize(numAlbums)).toList();
     for (Album album : albums) {
       List<Track> tracks = new ArrayList<>(numTracksPerAlbum);
       for (int trackNumber = 1; trackNumber <= numTracksPerAlbum; trackNumber++) {
diff --git a/samples/nodejs/knex/package.json b/samples/nodejs/knex/package.json
index 21bccd59..01d28dbf 100644
--- a/samples/nodejs/knex/package.json
+++ b/samples/nodejs/knex/package.json
@@ -4,9 +4,9 @@
   "description": "Knex Query Builder Sample",
   "type": "commonjs",
   "devDependencies": {
-    "@types/node": "^20.1.4",
+    "@types/node": "^22.0.0",
     "ts-node": "10.9.2",
-    "typescript": "5.6.2"
+    "typescript": "5.6.3"
   },
   "dependencies": {
     "pg": "^8.9.0",
diff --git a/samples/nodejs/sequelize/package.json b/samples/nodejs/sequelize/package.json
index 0051599a..3bbd898d 100644
--- a/samples/nodejs/sequelize/package.json
+++ b/samples/nodejs/sequelize/package.json
@@ -8,7 +8,7 @@
     "sequelize-cli": "^6.6.2",
     "testcontainers": "^10.7.1",
     "ts-node": "10.9.2",
-    "typescript": "5.6.2"
+    "typescript": "5.6.3"
   },
   "dependencies": {
     "pg": "^8.11.3",
diff --git a/samples/python/connectorx/requirements.txt b/samples/python/connectorx/requirements.txt
index fe91aab8..d5a705a5 100644
--- a/samples/python/connectorx/requirements.txt
+++ b/samples/python/connectorx/requirements.txt
@@ -1,6 +1,6 @@
 connectorx==0.3.3
-pandas==2.2.2
+pandas==2.2.3
 testcontainers~=4.8.0
 requests==2.32.3
 google~=3.0.0
-google.auth~=2.34.0
+google.auth~=2.35.0
diff --git a/samples/python/django/requirements.txt b/samples/python/django/requirements.txt
index 820427f8..51dfec5d 100644
--- a/samples/python/django/requirements.txt
+++ b/samples/python/django/requirements.txt
@@ -1,7 +1,7 @@
-psycopg-binary==3.2.2
+psycopg-binary==3.2.3
 pytz==2024.2
-Django==5.1.1
+Django==5.1.2
 google==3.0.0
-google.auth==2.34.0
-testcontainers==4.8.1
+google.auth==2.35.0
+testcontainers==4.8.2
 requests==2.32.3
diff --git a/samples/python/psycopg3/requirements.txt b/samples/python/psycopg3/requirements.txt
index e947b7fd..06a31af3 100644
--- a/samples/python/psycopg3/requirements.txt
+++ b/samples/python/psycopg3/requirements.txt
@@ -1,5 +1,5 @@
-psycopg[binary]~=3.2.2
-testcontainers~=4.8.1
+psycopg[binary]~=3.2.3
+testcontainers~=4.8.2
 requests==2.32.3
 google~=3.0.0
-google.auth~=2.34.0
\ No newline at end of file
+google.auth~=2.35.0
\ No newline at end of file
diff --git a/samples/python/sqlalchemy2-sample/requirements.txt b/samples/python/sqlalchemy2-sample/requirements.txt
index 36853211..6ae9ab0b 100644
--- a/samples/python/sqlalchemy2-sample/requirements.txt
+++ b/samples/python/sqlalchemy2-sample/requirements.txt
@@ -1,7 +1,7 @@
-psycopg[binary]==3.2.2
+psycopg[binary]==3.2.3
 pytz==2024.2
-sqlalchemy==2.0.35
+sqlalchemy==2.0.36
 google~=3.0.0
-google.auth~=2.34.0
+google.auth~=2.35.0
 testcontainers~=4.8.0
 requests==2.32.3
diff --git a/samples/sidecar-proxy/Dockerfile b/samples/sidecar-proxy/Dockerfile
index f7e2b85d..9ab6e0ae 100644
--- a/samples/sidecar-proxy/Dockerfile
+++ b/samples/sidecar-proxy/Dockerfile
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-FROM golang:1.23.1 as builder
+FROM golang:1.23.2 as builder
 WORKDIR /app
 RUN go mod init example-app
 RUN go get github.com/jackc/pgx/v4
diff --git a/samples/snippets/dotnet-snippets/dotnet-snippets.csproj b/samples/snippets/dotnet-snippets/dotnet-snippets.csproj
index 5c49c554..eca0ab25 100644
--- a/samples/snippets/dotnet-snippets/dotnet-snippets.csproj
+++ b/samples/snippets/dotnet-snippets/dotnet-snippets.csproj
@@ -9,7 +9,7 @@
     </PropertyGroup>
 
     <ItemGroup>
-      <PackageReference Include="Npgsql" Version="8.0.4" />
+      <PackageReference Include="Npgsql" Version="8.0.5" />
     </ItemGroup>
 
     <ItemGroup>
diff --git a/samples/snippets/golang-snippets/go.mod b/samples/snippets/golang-snippets/go.mod
index 217b982a..4425b5d5 100644
--- a/samples/snippets/golang-snippets/go.mod
+++ b/samples/snippets/golang-snippets/go.mod
@@ -1,11 +1,13 @@
 module golang-snippets
 
-go 1.21
+go 1.22
+
+toolchain go1.23.2
 
 require (
-	github.com/docker/docker v27.2.1+incompatible
+	github.com/docker/docker v27.3.1+incompatible
 	github.com/jackc/pgx/v5 v5.7.1
-	github.com/testcontainers/testcontainers-go v0.33.0
+	github.com/testcontainers/testcontainers-go v0.34.0
 )
 
 require (
@@ -18,7 +20,8 @@ require (
 	github.com/containerd/errdefs v0.1.0 // indirect
 	github.com/containerd/log v0.1.0 // indirect
 	github.com/containerd/platforms v0.2.1 // indirect
-	github.com/cpuguy83/dockercfg v0.3.1 // indirect
+	github.com/cpuguy83/dockercfg v0.3.2 // indirect
+	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/distribution/reference v0.6.0 // indirect
 	github.com/docker/go-connections v0.5.0 // indirect
 	github.com/docker/go-units v0.5.0 // indirect
@@ -44,10 +47,12 @@ require (
 	github.com/opencontainers/go-digest v1.0.0 // indirect
 	github.com/opencontainers/image-spec v1.1.0 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
 	github.com/shirou/gopsutil/v3 v3.23.12 // indirect
 	github.com/shoenig/go-m1cpu v0.1.6 // indirect
 	github.com/sirupsen/logrus v1.9.3 // indirect
+	github.com/stretchr/testify v1.9.0 // indirect
 	github.com/tklauser/go-sysconf v0.3.12 // indirect
 	github.com/tklauser/numcpus v0.6.1 // indirect
 	github.com/yusufpapurcu/wmi v1.2.3 // indirect
@@ -61,4 +66,5 @@ require (
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect
 	google.golang.org/grpc v1.64.1 // indirect
 	google.golang.org/protobuf v1.33.0 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
diff --git a/samples/snippets/golang-snippets/go.sum b/samples/snippets/golang-snippets/go.sum
index a5a17e90..4b8fcb20 100644
--- a/samples/snippets/golang-snippets/go.sum
+++ b/samples/snippets/golang-snippets/go.sum
@@ -20,6 +20,8 @@ github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpS
 github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw=
 github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E=
 github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
+github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA=
+github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
 github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
 github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -39,6 +41,8 @@ github.com/docker/docker v27.2.0+incompatible h1:Rk9nIVdfH3+Vz4cyI/uhbINhEZ/oLmc
 github.com/docker/docker v27.2.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 github.com/docker/docker v27.2.1+incompatible h1:fQdiLfW7VLscyoeYEBz7/J8soYFDZV1u6VW6gJEjNMI=
 github.com/docker/docker v27.2.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI=
+github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
 github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
 github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
@@ -130,6 +134,8 @@ github.com/testcontainers/testcontainers-go v0.32.0 h1:ug1aK08L3gCHdhknlTTwWjPHP
 github.com/testcontainers/testcontainers-go v0.32.0/go.mod h1:CRHrzHLQhlXUsa5gXjTOfqIEJcrK5+xMDmBr/WMI88E=
 github.com/testcontainers/testcontainers-go v0.33.0 h1:zJS9PfXYT5O0ZFXM2xxXfk4J5UMw/kRiISng037Gxdw=
 github.com/testcontainers/testcontainers-go v0.33.0/go.mod h1:W80YpTa8D5C3Yy16icheD01UTDu+LmXIA2Keo+jWtT8=
+github.com/testcontainers/testcontainers-go v0.34.0 h1:5fbgF0vIN5u+nD3IWabQwRybuB4GY8G2HHgCkbMzMHo=
+github.com/testcontainers/testcontainers-go v0.34.0/go.mod h1:6P/kMkQe8yqPHfPWNulFGdFHTD8HB2vLq/231xY2iPQ=
 github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
 github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
 github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
diff --git a/samples/snippets/java-snippets/pom.xml b/samples/snippets/java-snippets/pom.xml
index de95336d..55c19156 100644
--- a/samples/snippets/java-snippets/pom.xml
+++ b/samples/snippets/java-snippets/pom.xml
@@ -44,7 +44,7 @@
     <dependency>
       <groupId>org.testcontainers</groupId>
       <artifactId>testcontainers</artifactId>
-      <version>1.20.1</version>
+      <version>1.20.3</version>
       <scope>test</scope>
     </dependency>
     <dependency>
@@ -114,7 +114,7 @@
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>exec-maven-plugin</artifactId>
-        <version>3.4.1</version>
+        <version>3.5.0</version>
         <configuration>
           <mainClass>com.google.example.SampleRunner</mainClass>
           <cleanupDaemonThreads>false</cleanupDaemonThreads>
diff --git a/samples/snippets/nodejs-snippets/package.json b/samples/snippets/nodejs-snippets/package.json
index e1396c8c..5b45293d 100644
--- a/samples/snippets/nodejs-snippets/package.json
+++ b/samples/snippets/nodejs-snippets/package.json
@@ -5,7 +5,7 @@
   "type": "commonjs",
   "devDependencies": {
     "@types/jest": "^29.5.12",
-    "@types/node": "^20.12.4",
+    "@types/node": "^22.0.0",
     "@types/pg": "^8.11.4",
     "@types/yargs": "^17.0.32",
     "jest": "^29.7.0",
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 918109a6..c1efd80b 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/ConnectionHandler.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/ConnectionHandler.java
@@ -75,6 +75,7 @@ import java.io.DataOutputStream;
 import java.io.EOFException;
 import java.io.IOException;
 import java.net.Socket;
+import java.net.SocketException;
 import java.security.SecureRandom;
 import java.text.MessageFormat;
 import java.time.Duration;
@@ -504,22 +505,46 @@ public class ConnectionHandler implements Runnable {
     try {
       message.nextHandler();
       message.send();
-    } catch (IllegalArgumentException | IllegalStateException | EOFException fatalException) {
-      this.handleError(
-          PGException.newBuilder(fatalException)
-              .setSeverity(Severity.FATAL)
-              .setSQLState(SQLState.InternalError)
-              .build());
+    } catch (IllegalArgumentException | IllegalStateException fatalException) {
+      handleFatalException(fatalException);
       // Only terminate the connection if we are not in COPY_IN mode. In COPY_IN mode the mode will
       // switch to normal mode in these cases.
       if (this.status != ConnectionStatus.COPY_IN) {
         terminate();
       }
+    } catch (EOFException eofException) {
+      // Handle an EOFException as a normal connection termination. The TCP connection can break
+      // without the server receiving a Terminate (X) message if for example the application does
+      // not try-catch all exceptions.
+      // We only terminate the connection if we are not in COPY_IN mode. In COPY_IN mode, this
+      // exception will cause the connection to leave COPY_IN mode, and return to normal operation.
+      if (this.status != ConnectionStatus.COPY_IN) {
+        terminate();
+      } else {
+        handleFatalException(eofException);
+      }
+    } catch (SocketException socketException) {
+      // Handle a SocketException when the socket has been closed as a normal connection
+      // termination. The TCP connection can break without the server receiving a Terminate (X)
+      // message if for example the application does not try-catch all exceptions.
+      if (socket.isClosed()) {
+        terminate();
+      } else {
+        this.handleError(PGExceptionFactory.toPGException(socketException));
+      }
     } catch (Exception exception) {
       this.handleError(PGExceptionFactory.toPGException(exception));
     }
   }
 
+  private void handleFatalException(Exception fatalException) throws Exception {
+    this.handleError(
+        PGException.newBuilder(fatalException)
+            .setSeverity(Severity.FATAL)
+            .setSQLState(SQLState.InternalError)
+            .build());
+  }
+
   /** Called when a Terminate message is received. This closes this {@link ConnectionHandler}. */
   public void handleTerminate() {
     synchronized (this) {
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/ProxyServer.java b/src/main/java/com/google/cloud/spanner/pgadapter/ProxyServer.java
index 72166cd4..f38ee4c9 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/ProxyServer.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/ProxyServer.java
@@ -114,6 +114,8 @@ public class ProxyServer extends AbstractApiService {
     IMMEDIATE,
   }
 
+  private final AtomicReference<ShutdownHandler> shutdownHandler = new AtomicReference<>();
+
   private final AtomicReference<ShutdownMode> shutdownMode = new AtomicReference<>();
 
   private final AtomicReference<CountDownLatch> allHandlersTerminatedLatch =
@@ -322,6 +324,13 @@ public class ProxyServer extends AbstractApiService {
     awaitTerminated();
   }
 
+  public synchronized ShutdownHandler getOrCreateShutdownHandler() {
+    if (this.shutdownHandler.get() == null) {
+      this.shutdownHandler.set(ShutdownHandler.createForServer(this));
+    }
+    return this.shutdownHandler.get();
+  }
+
   void setShutdownMode(ShutdownMode shutdownMode) {
     logger.log(Level.INFO, "Setting shutdown mode to {0}", shutdownMode);
     this.shutdownMode.set(shutdownMode);
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/Server.java b/src/main/java/com/google/cloud/spanner/pgadapter/Server.java
index 958a9a3b..361d6c39 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/Server.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/Server.java
@@ -62,7 +62,7 @@ import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement;
 public class Server {
   private static final Logger logger = Logger.getLogger(Server.class.getName());
 
-  private static ShutdownHandler shutdownHandler;
+  private static volatile ShutdownHandler shutdownHandler;
 
   /**
    * Main method for running a Spanner PostgreSQL Adapter {@link Server} as a stand-alone
@@ -78,7 +78,7 @@ public class Server {
 
       // Create a shutdown handler and register signal handlers for the signals that should
       // terminate the server.
-      Server.shutdownHandler = ShutdownHandler.createForServer(proxyServer);
+      Server.shutdownHandler = proxyServer.getOrCreateShutdownHandler();
       registerSignalHandlers();
     } catch (Exception e) {
       printError(e, System.err, System.out);
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/ShutdownHandler.java b/src/main/java/com/google/cloud/spanner/pgadapter/ShutdownHandler.java
index 4a991404..80037820 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/ShutdownHandler.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/ShutdownHandler.java
@@ -14,6 +14,7 @@
 
 package com.google.cloud.spanner.pgadapter;
 
+import com.google.api.core.InternalApi;
 import com.google.cloud.spanner.pgadapter.ProxyServer.ShutdownMode;
 import com.google.common.base.Preconditions;
 import java.util.concurrent.atomic.AtomicReference;
@@ -28,6 +29,7 @@ public class ShutdownHandler {
   private final Thread shutdownThread;
   private final AtomicReference<ShutdownMode> shutdownMode = new AtomicReference<>();
 
+  @InternalApi
   static ShutdownHandler createForServer(@Nonnull ProxyServer proxyServer) {
     return new ShutdownHandler(proxyServer);
   }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/commands/ListCommand.java b/src/main/java/com/google/cloud/spanner/pgadapter/commands/ListCommand.java
index e5ac8da5..db771778 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/commands/ListCommand.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/commands/ListCommand.java
@@ -24,14 +24,13 @@ public class ListCommand extends Command {
 
   private static final Pattern INPUT_REGEX =
       Pattern.compile(
-          "^SELECT d\\.datname as \"Name\",\n"
-              + "       pg_catalog\\.pg_get_userbyid\\(d.datdba\\) as \"Owner\",\n"
-              + "       pg_catalog\\.pg_encoding_to_char\\(d\\.encoding\\) as \"Encoding\",\n"
-              + "(?:\\s*d\\.datcollate as \"Collate\",\n)?"
-              + "(?:\\s*d\\.datctype as \"Ctype\",\n)?"
-              + "       pg_catalog\\.array_to_string\\(d\\.datacl, .*\\) AS \"Access privileges\"\n"
-              + "FROM pg_catalog\\.pg_database d\n.*\n?"
-              + "ORDER BY 1;?$");
+          "^SELECT\\s+d\\.datname as \"Name\",\n"
+              + "\\s*pg_catalog\\.pg_get_userbyid\\(d.datdba\\) as \"Owner\",\n"
+              + ".*"
+              + "\\s*pg_catalog\\.array_to_string\\(d\\.datacl, .*\\)(:? END)? AS \"Access privileges\"\n"
+              + "FROM (?:pg_catalog\\.)?pg_database d\n.*\n?"
+              + "ORDER BY 1;?$",
+          Pattern.DOTALL);
 
   ListCommand(String sql) {
     super(sql);
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/error/SQLState.java b/src/main/java/com/google/cloud/spanner/pgadapter/error/SQLState.java
index b2afd47e..10d7593a 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/error/SQLState.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/error/SQLState.java
@@ -231,6 +231,7 @@ public enum SQLState {
     return code.equals(otherCode);
   }
 
+  @Override
   public String toString() {
     return this.code;
   }
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/metadata/OptionsMetadata.java b/src/main/java/com/google/cloud/spanner/pgadapter/metadata/OptionsMetadata.java
index 1942510e..1249305d 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/metadata/OptionsMetadata.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/metadata/OptionsMetadata.java
@@ -100,6 +100,7 @@ public class OptionsMetadata {
     private String unixDomainSocketDirectory;
     private boolean autoConfigEmulator;
     private boolean logGrpcMessages;
+    private boolean allowShutdownStatement;
     private boolean debugMode;
     private String endpoint;
     private boolean usePlainText;
@@ -369,6 +370,15 @@ public class OptionsMetadata {
       return this;
     }
 
+    /**
+     * Enables the use of the SHUTDOWN [SMART | FAST | IMMEDIATE] statement to shutdown the proxy
+     * server.
+     */
+    public Builder setAllowShutdownStatement(boolean allowShutdownStatement) {
+      this.allowShutdownStatement = allowShutdownStatement;
+      return this;
+    }
+
     Builder enableDebugMode() {
       this.debugMode = true;
       return this;
@@ -486,6 +496,9 @@ public class OptionsMetadata {
       if (logGrpcMessages) {
         addOption(args, OPTION_LOG_GRPC_MESSAGES);
       }
+      if (allowShutdownStatement) {
+        addOption(args, OPTION_ALLOW_SHUTDOWN_STATEMENT);
+      }
       if (debugMode) {
         addOption(args, OPTION_INTERNAL_DEBUG_MODE);
         addOption(args, OPTION_SKIP_INTERNAL_DEBUG_MODE_WARNING);
@@ -604,6 +617,7 @@ public class OptionsMetadata {
   private static final String OPTION_DEBUG_MODE = "debug";
   private static final String OPTION_LEGACY_LOGGING = "legacy_logging";
   private static final String OPTION_LOG_GRPC_MESSAGES = "log_grpc_messages";
+  private static final String OPTION_ALLOW_SHUTDOWN_STATEMENT = "allow_shutdown_statement";
 
   private final Map<String, String> environment;
   private final String osName;
@@ -635,6 +649,7 @@ public class OptionsMetadata {
   private final boolean debugMode;
   private final Duration startupTimeout;
   private final boolean logGrpcMessages;
+  private final boolean allowShutdownStatement;
 
   /**
    * Creates a new instance of {@link OptionsMetadata} from the given arguments.
@@ -728,6 +743,7 @@ public class OptionsMetadata {
     this.serverVersion = commandLine.getOptionValue(OPTION_SERVER_VERSION, DEFAULT_SERVER_VERSION);
     this.debugMode = commandLine.hasOption(OPTION_INTERNAL_DEBUG_MODE);
     this.logGrpcMessages = commandLine.hasOption(OPTION_LOG_GRPC_MESSAGES);
+    this.allowShutdownStatement = commandLine.hasOption(OPTION_ALLOW_SHUTDOWN_STATEMENT);
     this.startupTimeout = startupTimeout;
   }
 
@@ -802,6 +818,7 @@ public class OptionsMetadata {
     this.serverVersion = DEFAULT_SERVER_VERSION;
     this.debugMode = false;
     this.logGrpcMessages = false;
+    this.allowShutdownStatement = false;
     this.startupTimeout = DEFAULT_STARTUP_TIMEOUT;
   }
 
@@ -1292,6 +1309,11 @@ public class OptionsMetadata {
         "Logs all gRPC messages that are sent by PGAdapter to Spanner to the default log handler (stdout).\n"
             + "This option should only be enabled to debug problems and/or to determine exactly which gRPC messages\n"
             + "are being sent to Spanner. Enabling this in production will cause a large number of messages to be logged.");
+    options.addOption(
+        OPTION_ALLOW_SHUTDOWN_STATEMENT,
+        "allow-shutdown-statement",
+        false,
+        "Allows the proxy server to be shutdown by executing the SHUTDOWN [SMART | FAST | IMMEDIATE] statement.");
     options.addOption(
         OPTION_INTERNAL_DEBUG_MODE,
         "internal-debug-mode",
@@ -1392,6 +1414,10 @@ public class OptionsMetadata {
     return this.logGrpcMessages;
   }
 
+  public boolean isAllowShutdownStatement() {
+    return this.allowShutdownStatement;
+  }
+
   public boolean isDebugMode() {
     return this.debugMode;
   }
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 e59c3427..692d643e 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
@@ -525,6 +525,26 @@ public class SessionState {
     return getIntegerSetting("spanner", "string_conversion_buffer_size", 0);
   }
 
+  /**
+   * Returns the update count that PGAdapter should return for DML statements that are executed
+   * during a DML batch. The default is 0.
+   *
+   * <p>Example:
+   *
+   * <pre>{@code
+   * begin;
+   * set local spanner.dml_batch_update_count=1;
+   * start batch dml;
+   * insert into my_table (id, value) values (1, 'one'); -- This returns update count 1
+   * insert into my_table (id, value) values (2, 'two'); -- This returns update count 1
+   * run batch; -- This actually executes the DML statements.
+   * commit;
+   * }</pre>
+   */
+  public int getDmlBatchUpdateCount() {
+    return getIntegerSetting("spanner", "dml_batch_update_count", 0);
+  }
+
   private ZoneId cachedZoneId;
 
   /** Returns the {@link ZoneId} of the current timezone for this session. */
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/BackendConnection.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/BackendConnection.java
index db3ff6b1..61998a03 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/BackendConnection.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/BackendConnection.java
@@ -285,7 +285,7 @@ public class BackendConnection {
 
     @Override
     boolean isBatchingPossible() {
-      return !analyze;
+      return !analyze && !this.parsedStatement.hasReturningClause();
     }
 
     @Override
@@ -1155,8 +1155,11 @@ public class BackendConnection {
             && bufferedStatement.isBatchingPossible()
             && index < (getStatementCount() - 1)) {
           StatementType statementType = getStatementType(index);
-          StatementType nextStatementType = getStatementType(index + 1);
-          canUseBatch = canBeBatchedTogether(statementType, nextStatementType);
+          // Do not start an explicit batch if the connection is already in auto-DML-batch mode.
+          if (!(statementType == StatementType.UPDATE && spannerConnection.isAutoBatchDml())) {
+            StatementType nextStatementType = getStatementType(index + 1);
+            canUseBatch = canBeBatchedTogether(statementType, nextStatementType);
+          }
         }
 
         if (canUseBatch) {
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/ClientSideResultSet.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/ClientSideResultSet.java
index 91c92bcb..941a49f8 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/ClientSideResultSet.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/ClientSideResultSet.java
@@ -27,14 +27,21 @@ import com.google.spanner.v1.ResultSetStats;
 @InternalApi
 public class ClientSideResultSet extends ForwardingResultSet {
   public static ResultSet forRows(Type type, Iterable<Struct> rows) {
-    return new ClientSideResultSet(ResultSets.forRows(type, rows), type);
+    return forRows(type, rows, ResultSetMetadata.getDefaultInstance());
+  }
+
+  public static ResultSet forRows(Type type, Iterable<Struct> rows, ResultSetMetadata metadata) {
+    return new ClientSideResultSet(ResultSets.forRows(type, rows), type, metadata);
   }
 
   private final Type type;
 
-  private ClientSideResultSet(ResultSet delegate, Type type) {
+  private final ResultSetMetadata metadata;
+
+  private ClientSideResultSet(ResultSet delegate, Type type, ResultSetMetadata metadata) {
     super(delegate);
     this.type = type;
+    this.metadata = metadata;
   }
 
   @Override
@@ -49,6 +56,6 @@ public class ClientSideResultSet extends ForwardingResultSet {
 
   @Override
   public ResultSetMetadata getMetadata() {
-    return ResultSetMetadata.getDefaultInstance();
+    return this.metadata;
   }
 }
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 3c74fce1..1cef475e 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
@@ -66,9 +66,7 @@ public class ExtendedQueryProtocolHandler {
                 .getServer()
                 .getTracer(ConnectionHandler.class.getName(), getVersion()),
             connectionHandler.getServer().getMetrics(),
-            createMetricAttributes(
-                connectionHandler.getDatabaseId(),
-                connectionHandler.getTraceConnectionId().toString()),
+            createMetricAttributes(connectionHandler.getDatabaseId()),
             connectionHandler.getTraceConnectionId().toString(),
             connectionHandler::closeAllPortals,
             connectionHandler.getDatabaseId(),
@@ -97,9 +95,8 @@ public class ExtendedQueryProtocolHandler {
   }
 
   @VisibleForTesting
-  static Attributes createMetricAttributes(DatabaseId databaseId, String connectionId) {
+  static Attributes createMetricAttributes(DatabaseId databaseId) {
     AttributesBuilder attributesBuilder = Attributes.builder();
-    attributesBuilder.put("pgadapter.connection_id", connectionId);
     attributesBuilder.put("database", databaseId.getDatabase());
     attributesBuilder.put("instance_id", databaseId.getInstanceId().getInstance());
     attributesBuilder.put("project_id", databaseId.getInstanceId().getProject());
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
new file mode 100644
index 00000000..329b3e25
--- /dev/null
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/ShutdownStatement.java
@@ -0,0 +1,156 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.cloud.spanner.pgadapter.statements;
+
+import com.google.cloud.spanner.Statement;
+import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement;
+import com.google.cloud.spanner.connection.AbstractStatementParser.StatementType;
+import com.google.cloud.spanner.connection.StatementResult;
+import com.google.cloud.spanner.pgadapter.ConnectionHandler;
+import com.google.cloud.spanner.pgadapter.ProxyServer;
+import com.google.cloud.spanner.pgadapter.ProxyServer.ShutdownMode;
+import com.google.cloud.spanner.pgadapter.ShutdownHandler;
+import com.google.cloud.spanner.pgadapter.error.PGExceptionFactory;
+import com.google.cloud.spanner.pgadapter.error.SQLState;
+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;
+
+/**
+ * <code>SHUTDOWN [FAST | SMART | IMMEDIATE]</code>
+ *
+ * <p>Shuts down the proxy server. This statement is a PGAdapter-only statement, and is not
+ * supported on normal PostgreSQL.
+ */
+public class ShutdownStatement extends IntermediatePortalStatement {
+  static final class ParsedShutdownStatement {
+    static final class Builder {
+      ShutdownMode shutdownMode = ShutdownMode.FAST;
+    }
+
+    /** The server that will be shut down. */
+    final ProxyServer server;
+
+    final ShutdownMode shutdownMode;
+
+    private ParsedShutdownStatement(Builder builder, ProxyServer server) {
+      this.server = server;
+      this.shutdownMode = builder.shutdownMode;
+    }
+  }
+
+  private final ParsedShutdownStatement parsedShutdownStatement;
+
+  private ShutdownHandler shutdownHandler;
+
+  public ShutdownStatement(
+      ConnectionHandler connectionHandler,
+      OptionsMetadata options,
+      String name,
+      ParsedStatement parsedStatement,
+      Statement originalStatement) {
+    super(
+        name,
+        new IntermediatePreparedStatement(
+            connectionHandler,
+            options,
+            name,
+            NO_PARAMETER_TYPES,
+            parsedStatement,
+            originalStatement),
+        NO_PARAMS,
+        ImmutableList.of(),
+        ImmutableList.of());
+    this.parsedShutdownStatement = parse(originalStatement.getSql(), connectionHandler.getServer());
+  }
+
+  @Override
+  public String getCommandTag() {
+    return "SHUTDOWN";
+  }
+
+  @Override
+  public StatementType getStatementType() {
+    return StatementType.UNKNOWN;
+  }
+
+  @Override
+  public void close() throws Exception {
+    super.close();
+    if (this.executed && this.shutdownHandler != null) {
+      this.shutdownHandler.shutdown(this.parsedShutdownStatement.shutdownMode);
+    }
+  }
+
+  @Override
+  public void executeAsync(BackendConnection backendConnection) {
+    if (!this.executed) {
+      this.executed = true;
+      if (options.isAllowShutdownStatement()) {
+        this.shutdownHandler = this.parsedShutdownStatement.server.getOrCreateShutdownHandler();
+        setFutureStatementResult(Futures.immediateFuture(new NoResult(getCommandTag())));
+      } else {
+        setFutureStatementResult(
+            Futures.immediateFailedFuture(
+                PGExceptionFactory.newPGException(
+                    "SHUTDOWN [SMART | FAST | IMMEDIATE] statement is not enabled for this server. Start PGAdapter with --allow_shutdown_statement to enable the use of the SHUTDOWN statement.",
+                    SQLState.FeatureNotSupported)));
+      }
+    }
+  }
+
+  @Override
+  public Future<StatementResult> describeAsync(BackendConnection backendConnection) {
+    // Return null to indicate that this SHUTDOWN statement does not return any
+    // RowDescriptionResponse.
+    return Futures.immediateFuture(null);
+  }
+
+  @Override
+  public IntermediatePortalStatement createPortal(
+      String name,
+      byte[][] parameters,
+      List<Short> parameterFormatCodes,
+      List<Short> resultFormatCodes) {
+    // SHUTDOWN does not support binding any parameters, so we just return the same statement.
+    return this;
+  }
+
+  static ParsedShutdownStatement parse(String sql, ProxyServer server) {
+    Preconditions.checkNotNull(sql);
+    Preconditions.checkNotNull(server);
+
+    SimpleParser parser = new SimpleParser(sql);
+    ParsedShutdownStatement.Builder builder = new Builder();
+    if (!parser.eatKeyword("shutdown")) {
+      throw PGExceptionFactory.newPGException(
+          "not a valid SHUTDOWN statement: " + sql, SQLState.SyntaxError);
+    }
+    if (parser.eatKeyword("fast")) {
+      builder.shutdownMode = ShutdownMode.FAST;
+    } else if (parser.eatKeyword("smart")) {
+      builder.shutdownMode = ShutdownMode.SMART;
+    } else if (parser.eatKeyword("immediate")) {
+      builder.shutdownMode = ShutdownMode.IMMEDIATE;
+    }
+    parser.throwIfHasMoreTokens();
+    return new ParsedShutdownStatement(builder, server);
+  }
+}
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/local/SelectCurrentSchemaStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/local/SelectCurrentSchemaStatement.java
index 6afd994e..c22d8510 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/local/SelectCurrentSchemaStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/local/SelectCurrentSchemaStatement.java
@@ -36,12 +36,15 @@ public class SelectCurrentSchemaStatement implements LocalStatement {
     return new String[] {
       "select current_schema()",
       "SELECT current_schema()",
+      "SELECT CURRENT_SCHEMA()",
       "Select current_schema()",
       "select current_schema",
       "SELECT current_schema",
+      "SELECT CURRENT_SCHEMA",
       "Select current_schema",
       "select * from current_schema()",
       "SELECT * FROM current_schema()",
+      "SELECT * FROM CURRENT_SCHEMA()",
       "select * from current_schema",
       "SELECT * FROM current_schema"
     };
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/local/SelectGolangMigrateAdvisoryLockStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/local/SelectGolangMigrateAdvisoryLockStatement.java
new file mode 100644
index 00000000..a3ed3a04
--- /dev/null
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/local/SelectGolangMigrateAdvisoryLockStatement.java
@@ -0,0 +1,67 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.cloud.spanner.pgadapter.statements.local;
+
+import com.google.api.core.InternalApi;
+import com.google.cloud.spanner.ResultSet;
+import com.google.cloud.spanner.Struct;
+import com.google.cloud.spanner.Type;
+import com.google.cloud.spanner.Type.StructField;
+import com.google.cloud.spanner.connection.StatementResult;
+import com.google.cloud.spanner.pgadapter.statements.BackendConnection;
+import com.google.cloud.spanner.pgadapter.statements.BackendConnection.QueryResult;
+import com.google.cloud.spanner.pgadapter.statements.ClientSideResultSet;
+import com.google.common.collect.ImmutableList;
+import com.google.spanner.v1.ResultSetMetadata;
+import com.google.spanner.v1.StructType;
+import com.google.spanner.v1.StructType.Field;
+import com.google.spanner.v1.TypeCode;
+
+@InternalApi
+public class SelectGolangMigrateAdvisoryLockStatement implements LocalStatement {
+  public static final SelectGolangMigrateAdvisoryLockStatement INSTANCE =
+      new SelectGolangMigrateAdvisoryLockStatement();
+
+  private SelectGolangMigrateAdvisoryLockStatement() {}
+
+  @Override
+  public String[] getSql() {
+    return new String[] {
+      "SELECT pg_advisory_lock($1)",
+    };
+  }
+
+  @Override
+  public StatementResult execute(BackendConnection backendConnection) {
+    ResultSet resultSet =
+        ClientSideResultSet.forRows(
+            Type.struct(StructField.of("pg_advisory_lock", Type.int64())),
+            ImmutableList.of(Struct.newBuilder().set("pg_advisory_lock").to(1L).build()),
+            ResultSetMetadata.newBuilder()
+                .setUndeclaredParameters(
+                    StructType.newBuilder()
+                        .addFields(
+                            Field.newBuilder()
+                                .setName("p1")
+                                .setType(
+                                    com.google.spanner.v1.Type.newBuilder()
+                                        .setCode(TypeCode.INT64)
+                                        .build())
+                                .build())
+                        .build())
+                .build());
+    return new QueryResult(resultSet);
+  }
+}
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/local/SelectGolangMigrateAdvisoryUnlockStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/local/SelectGolangMigrateAdvisoryUnlockStatement.java
new file mode 100644
index 00000000..e13323f7
--- /dev/null
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/local/SelectGolangMigrateAdvisoryUnlockStatement.java
@@ -0,0 +1,67 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.cloud.spanner.pgadapter.statements.local;
+
+import com.google.api.core.InternalApi;
+import com.google.cloud.spanner.ResultSet;
+import com.google.cloud.spanner.Struct;
+import com.google.cloud.spanner.Type;
+import com.google.cloud.spanner.Type.StructField;
+import com.google.cloud.spanner.connection.StatementResult;
+import com.google.cloud.spanner.pgadapter.statements.BackendConnection;
+import com.google.cloud.spanner.pgadapter.statements.BackendConnection.QueryResult;
+import com.google.cloud.spanner.pgadapter.statements.ClientSideResultSet;
+import com.google.common.collect.ImmutableList;
+import com.google.spanner.v1.ResultSetMetadata;
+import com.google.spanner.v1.StructType;
+import com.google.spanner.v1.StructType.Field;
+import com.google.spanner.v1.TypeCode;
+
+@InternalApi
+public class SelectGolangMigrateAdvisoryUnlockStatement implements LocalStatement {
+  public static final SelectGolangMigrateAdvisoryUnlockStatement INSTANCE =
+      new SelectGolangMigrateAdvisoryUnlockStatement();
+
+  private SelectGolangMigrateAdvisoryUnlockStatement() {}
+
+  @Override
+  public String[] getSql() {
+    return new String[] {
+      "SELECT pg_advisory_unlock($1)",
+    };
+  }
+
+  @Override
+  public StatementResult execute(BackendConnection backendConnection) {
+    ResultSet resultSet =
+        ClientSideResultSet.forRows(
+            Type.struct(StructField.of("pg_advisory_unlock", Type.bool())),
+            ImmutableList.of(Struct.newBuilder().set("pg_advisory_unlock").to(true).build()),
+            ResultSetMetadata.newBuilder()
+                .setUndeclaredParameters(
+                    StructType.newBuilder()
+                        .addFields(
+                            Field.newBuilder()
+                                .setName("p1")
+                                .setType(
+                                    com.google.spanner.v1.Type.newBuilder()
+                                        .setCode(TypeCode.INT64)
+                                        .build())
+                                .build())
+                        .build())
+                .build());
+    return new QueryResult(resultSet);
+  }
+}
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/utils/ClientAutoDetector.java b/src/main/java/com/google/cloud/spanner/pgadapter/utils/ClientAutoDetector.java
index 4ca4e7a6..d4d267fc 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/utils/ClientAutoDetector.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/utils/ClientAutoDetector.java
@@ -28,6 +28,8 @@ import com.google.cloud.spanner.pgadapter.statements.local.LocalStatement;
 import com.google.cloud.spanner.pgadapter.statements.local.SelectCurrentCatalogStatement;
 import com.google.cloud.spanner.pgadapter.statements.local.SelectCurrentDatabaseStatement;
 import com.google.cloud.spanner.pgadapter.statements.local.SelectCurrentSchemaStatement;
+import com.google.cloud.spanner.pgadapter.statements.local.SelectGolangMigrateAdvisoryLockStatement;
+import com.google.cloud.spanner.pgadapter.statements.local.SelectGolangMigrateAdvisoryUnlockStatement;
 import com.google.cloud.spanner.pgadapter.statements.local.SelectPrismaAdvisoryLockStatement;
 import com.google.cloud.spanner.pgadapter.statements.local.SelectPrismaAdvisoryUnlockStatement;
 import com.google.cloud.spanner.pgadapter.statements.local.SelectVersionStatement;
@@ -541,6 +543,26 @@ public class ClientAutoDetector {
             RegexQueryPartReplacer.replace(Pattern.compile("ON\\s+UPDATE\\s+CASCADE"), ""));
       }
     },
+    GOLANG_MIGRATE {
+      @Override
+      boolean isClient(List<String> orderedParameterKeys, Map<String, String> parameters) {
+        // Golang migrate can only be recognized if the name is set correctly.
+        return parameters.containsKey("application_name")
+            && parameters.get("application_name").equals("golang-migrate");
+      }
+
+      @Override
+      public ImmutableList<LocalStatement> getLocalStatements(ConnectionHandler connectionHandler) {
+        if (connectionHandler.getServer().getOptions().useDefaultLocalStatements()) {
+          return ImmutableList.<LocalStatement>builder()
+              .addAll(DEFAULT_LOCAL_STATEMENTS)
+              .add(SelectGolangMigrateAdvisoryLockStatement.INSTANCE)
+              .add(SelectGolangMigrateAdvisoryUnlockStatement.INSTANCE)
+              .build();
+        }
+        return ImmutableList.of(new ListDatabasesStatement(connectionHandler));
+      }
+    },
     UNSPECIFIED {
       @Override
       boolean isClient(List<String> orderedParameterKeys, Map<String, String> parameters) {
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/DeclineSSLResponse.java b/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/DeclineSSLResponse.java
index ea8d4398..eaec5dc2 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/DeclineSSLResponse.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/wireoutput/DeclineSSLResponse.java
@@ -18,7 +18,7 @@ import com.google.api.core.InternalApi;
 import java.io.DataOutputStream;
 import java.io.IOException;
 
-/** Signals to client that we do not accept SSL. */
+/** Signals to client that we do not accept SSL or GSSAPI. */
 @InternalApi
 public class DeclineSSLResponse extends WireOutput {
 
@@ -41,7 +41,7 @@ public class DeclineSSLResponse extends WireOutput {
 
   @Override
   protected String getMessageName() {
-    return "Decline SSL";
+    return "Decline SSL/GSSAPI";
   }
 
   @Override
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 2a02bf40..68c7376d 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
@@ -55,6 +55,8 @@ public abstract class BootstrapMessage extends WireMessage {
     switch (protocol) {
       case SSLMessage.IDENTIFIER:
         return new SSLMessage(connection);
+      case GSSENCRequestMessage.IDENTIFIER:
+        return new GSSENCRequestMessage(connection);
       case StartupMessage.IDENTIFIER:
         return new StartupMessage(connection, length);
       case CancelMessage.IDENTIFIER:
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/GSSENCRequestMessage.java b/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/GSSENCRequestMessage.java
new file mode 100644
index 00000000..86bf98b6
--- /dev/null
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/GSSENCRequestMessage.java
@@ -0,0 +1,69 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.cloud.spanner.pgadapter.wireprotocol;
+
+import com.google.api.core.InternalApi;
+import com.google.cloud.spanner.pgadapter.ConnectionHandler;
+import com.google.cloud.spanner.pgadapter.wireoutput.DeclineSSLResponse;
+import java.io.IOException;
+import java.text.MessageFormat;
+
+/** Handles GSSENCRequest bootstrap message. */
+@InternalApi
+public class GSSENCRequestMessage extends BootstrapMessage {
+  private static final int MESSAGE_LENGTH = 8;
+  public static final int IDENTIFIER = 80877104; // First Hextet: 1234, Second Hextet: 5680
+
+  private final ThreadLocal<Boolean> executedOnce = ThreadLocal.withInitial(() -> false);
+
+  public GSSENCRequestMessage(ConnectionHandler connection) {
+    super(connection, MESSAGE_LENGTH);
+  }
+
+  @Override
+  protected void sendPayload() throws Exception {
+    if (executedOnce.get()) {
+      this.connection.handleTerminate();
+      throw new IOException("GSSAPI not supported by server");
+    }
+    // We use the same 'Decline' response for both SSL and GSSAPI.
+    new DeclineSSLResponse(this.outputStream).send();
+    executedOnce.set(true);
+  }
+
+  @Override
+  public void nextHandler() throws Exception {
+    this.connection.setMessageState(BootstrapMessage.create(this.connection));
+  }
+
+  @Override
+  protected String getMessageName() {
+    return "GSSAPI Request";
+  }
+
+  @Override
+  protected String getPayloadString() {
+    return new MessageFormat("GSSENCRequest, Length: {0}")
+        .format(
+            new Object[] {
+              this.length,
+            });
+  }
+
+  @Override
+  public String getIdentifier() {
+    return Integer.toString(IDENTIFIER);
+  }
+}
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 b01fc53f..fcdc30a9 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
@@ -30,6 +30,7 @@ import static com.google.cloud.spanner.pgadapter.wireprotocol.QueryMessage.SAVEP
 import static com.google.cloud.spanner.pgadapter.wireprotocol.QueryMessage.SELECT_CURRENT_SETTING;
 import static com.google.cloud.spanner.pgadapter.wireprotocol.QueryMessage.SELECT_SET_CONFIG;
 import static com.google.cloud.spanner.pgadapter.wireprotocol.QueryMessage.SHOW_DATABASE_DDL;
+import static com.google.cloud.spanner.pgadapter.wireprotocol.QueryMessage.SHUTDOWN;
 import static com.google.cloud.spanner.pgadapter.wireprotocol.QueryMessage.TRUNCATE;
 import static com.google.cloud.spanner.pgadapter.wireprotocol.QueryMessage.VACUUM;
 
@@ -58,6 +59,7 @@ import com.google.cloud.spanner.pgadapter.statements.SavepointStatement;
 import com.google.cloud.spanner.pgadapter.statements.SelectCurrentSettingStatement;
 import com.google.cloud.spanner.pgadapter.statements.SelectSetConfigStatement;
 import com.google.cloud.spanner.pgadapter.statements.ShowDatabaseDdlStatement;
+import com.google.cloud.spanner.pgadapter.statements.ShutdownStatement;
 import com.google.cloud.spanner.pgadapter.statements.TruncateStatement;
 import com.google.cloud.spanner.pgadapter.statements.VacuumStatement;
 import com.google.cloud.spanner.pgadapter.wireoutput.ParseCompleteResponse;
@@ -244,6 +246,13 @@ public class ParseMessage extends AbstractQueryProtocolMessage {
             name,
             parsedStatement,
             originalStatement);
+      } else if (isCommand(SHUTDOWN, originalStatement.getSql())) {
+        return new ShutdownStatement(
+            connectionHandler,
+            connectionHandler.getServer().getOptions(),
+            name,
+            parsedStatement,
+            originalStatement);
       } else {
         return new IntermediatePreparedStatement(
             connectionHandler,
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/QueryMessage.java b/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/QueryMessage.java
index 4f417793..02bd901c 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/QueryMessage.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/wireprotocol/QueryMessage.java
@@ -41,6 +41,7 @@ public class QueryMessage extends ControlMessage {
   public static final String FETCH = "FETCH";
   public static final String MOVE = "MOVE";
   public static final String CLOSE = "CLOSE";
+  public static final String SHUTDOWN = "SHUTDOWN";
   public static final ImmutableList<String> SHOW_DATABASE_DDL =
       ImmutableList.of("SHOW", "DATABASE", "DDL");
   public static final ImmutableList<String> SELECT_CURRENT_SETTING =
diff --git a/src/main/resources/metadata/default_command_metadata.json b/src/main/resources/metadata/default_command_metadata.json
index 7e711d23..647b591e 100644
--- a/src/main/resources/metadata/default_command_metadata.json
+++ b/src/main/resources/metadata/default_command_metadata.json
@@ -123,7 +123,7 @@
       "blurb": "This command is equivalent to the PSQL \\d <param> meta-command. This command is split up among multiple parts, this being the seventh. The Spanner fetch does not require a similar step so we just hardcode it."
     },
     {
-      "input_pattern": "(?s)^SELECT pubname\\s+FROM pg_catalog\\.pg_publication p\\s+JOIN pg_catalog\\.pg_publication_rel pr ON p.oid = pr\\.prpubid\\s+WHERE pr\\.prrelid = '.*'\\s+UNION ALL\\s+SELECT pubname\\s+FROM pg_catalog\\.pg_publication p\\s+WHERE p\\.puballtables AND pg_catalog\\.pg_relation_is_publishable\\('.*'\\)\\s+ORDER BY 1;?$",
+      "input_pattern": "(?s)^SELECT pubname.*\\s+FROM pg_catalog\\.pg_publication p\\s+JOIN pg_catalog\\.pg_publication_rel pr ON p.oid = pr\\.prpubid\\s+WHERE pr\\.prrelid = '.*'\\s+UNION ALL\\s+SELECT pubname.*\\s+FROM pg_catalog\\.pg_publication p\\s+WHERE p\\.puballtables AND pg_catalog\\.pg_relation_is_publishable\\('.*'\\)\\s+ORDER BY 1;?$",
       "output_pattern": "SELECT 1 LIMIT 0;",
       "matcher_array": [],
       "blurb": "This command is equivalent to the PSQL \\d <param> meta-command. This command is split up among multiple parts, this being the eighth. The Spanner fetch does not require a similar step so we just hardcode it."
diff --git a/versions.txt b/versions.txt
index 5953ee4a..35767f02 100644
--- a/versions.txt
+++ b/versions.txt
@@ -1,4 +1,4 @@
 # Format:
 # module:released-version:current-version
 
-google-cloud-spanner-pgadapter:0.37.0:0.37.1-SNAPSHOT
+google-cloud-spanner-pgadapter:0.40.0:0.40.1-SNAPSHOT
diff --git a/wrappers/golang/go.mod b/wrappers/golang/go.mod
index ae85ddfc..237ef527 100644
--- a/wrappers/golang/go.mod
+++ b/wrappers/golang/go.mod
@@ -1,10 +1,12 @@
 module github.com/GoogleCloudPlatform/pgadapter/wrappers/golang
 
-go 1.21
+go 1.22
+
+toolchain go1.23.2
 
 require (
-	github.com/docker/docker v27.2.1+incompatible
-	github.com/testcontainers/testcontainers-go v0.33.0
+	github.com/docker/docker v27.3.1+incompatible
+	github.com/testcontainers/testcontainers-go v0.34.0
 	golang.org/x/oauth2 v0.23.0
 )
 
@@ -17,7 +19,8 @@ require (
 	github.com/cenkalti/backoff/v4 v4.2.1 // indirect
 	github.com/containerd/log v0.1.0 // indirect
 	github.com/containerd/platforms v0.2.1 // indirect
-	github.com/cpuguy83/dockercfg v0.3.1 // indirect
+	github.com/cpuguy83/dockercfg v0.3.2 // indirect
+	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/distribution/reference v0.6.0 // indirect
 	github.com/docker/go-connections v0.5.0 // indirect
 	github.com/docker/go-units v0.5.0 // indirect
@@ -40,10 +43,12 @@ require (
 	github.com/opencontainers/go-digest v1.0.0 // indirect
 	github.com/opencontainers/image-spec v1.1.0 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
 	github.com/shirou/gopsutil/v3 v3.23.12 // indirect
 	github.com/shoenig/go-m1cpu v0.1.6 // indirect
 	github.com/sirupsen/logrus v1.9.3 // indirect
+	github.com/stretchr/testify v1.9.0 // indirect
 	github.com/tklauser/go-sysconf v0.3.12 // indirect
 	github.com/tklauser/numcpus v0.6.1 // indirect
 	github.com/yusufpapurcu/wmi v1.2.3 // indirect
@@ -60,4 +65,5 @@ require (
 	google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 // indirect
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect
 	google.golang.org/protobuf v1.33.0 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
diff --git a/wrappers/golang/go.sum b/wrappers/golang/go.sum
index c1fa4f98..7b1d7c29 100644
--- a/wrappers/golang/go.sum
+++ b/wrappers/golang/go.sum
@@ -16,6 +16,8 @@ github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpS
 github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw=
 github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E=
 github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
+github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA=
+github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
 github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
 github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -27,6 +29,8 @@ github.com/docker/docker v27.2.0+incompatible h1:Rk9nIVdfH3+Vz4cyI/uhbINhEZ/oLmc
 github.com/docker/docker v27.2.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 github.com/docker/docker v27.2.1+incompatible h1:fQdiLfW7VLscyoeYEBz7/J8soYFDZV1u6VW6gJEjNMI=
 github.com/docker/docker v27.2.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI=
+github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
 github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
 github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
@@ -101,6 +105,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
 github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 github.com/testcontainers/testcontainers-go v0.33.0 h1:zJS9PfXYT5O0ZFXM2xxXfk4J5UMw/kRiISng037Gxdw=
 github.com/testcontainers/testcontainers-go v0.33.0/go.mod h1:W80YpTa8D5C3Yy16icheD01UTDu+LmXIA2Keo+jWtT8=
+github.com/testcontainers/testcontainers-go v0.34.0 h1:5fbgF0vIN5u+nD3IWabQwRybuB4GY8G2HHgCkbMzMHo=
+github.com/testcontainers/testcontainers-go v0.34.0/go.mod h1:6P/kMkQe8yqPHfPWNulFGdFHTD8HB2vLq/231xY2iPQ=
 github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
 github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
 github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=


Test patch:
diff --git a/.ci/e2e-expected/backslash-dt.txt b/.ci/e2e-expected/backslash-dt.txt
index 9c3fc099..35c3ccfa 100644
--- a/.ci/e2e-expected/backslash-dt.txt
+++ b/.ci/e2e-expected/backslash-dt.txt
@@ -65,9 +65,8 @@
  testdb_e2e_psql_v?? | spanner_sys        | read_stats_total_hour            | VIEW       |                              |                      |                           |                          |                        |                    |          |               |                   |                  |               |                 | 
  testdb_e2e_psql_v?? | spanner_sys        | read_stats_total_minute          | VIEW       |                              |                      |                           |                          |                        |                    |          |               |                   |                  |               |                 | 
  testdb_e2e_psql_v?? | spanner_sys        | row_deletion_policies            | VIEW       |                              |                      |                           |                          |                        |                    |          |               |                   |                  |               |                 |
- testdb_e2e_psql_v?? | spanner_sys        | split_hotness_stats_top_10minute | VIEW       |                              |                      |                           |                          |                        |                    |          |               |                   |                  |               |                 | 
- testdb_e2e_psql_v?? | spanner_sys        | split_hotness_stats_top_hour     | VIEW       |                              |                      |                           |                          |                        |                    |          |               |                   |                  |               |                 | 
  testdb_e2e_psql_v?? | spanner_sys        | split_hotness_stats_top_minute   | VIEW       |                              |                      |                           |                          |                        |                    |          |               |                   |                  |               |                 | 
+ testdb_e2e_psql_v?? | spanner_sys        | split_stats_top_minute           | VIEW       |                              |                      |                           |                          |                        |                    |          |               |                   |                  |               |                 | 
  testdb_e2e_psql_v?? | spanner_sys        | supported_optimizer_versions     | VIEW       |                              |                      |                           |                          |                        |                    |          |               |                   |                  |               |                 | 
  testdb_e2e_psql_v?? | spanner_sys        | table_operations_stats_10minute  | VIEW       |                              |                      |                           |                          |                        |                    |          |               |                   |                  |               |                 | 
  testdb_e2e_psql_v?? | spanner_sys        | table_operations_stats_hour      | VIEW       |                              |                      |                           |                          |                        |                    |          |               |                   |                  |               |                 | 
@@ -79,5 +78,5 @@
  testdb_e2e_psql_v?? | spanner_sys        | txn_stats_total_10minute         | VIEW       |                              |                      |                           |                          |                        |                    |          |               |                   |                  |               |                 | 
  testdb_e2e_psql_v?? | spanner_sys        | txn_stats_total_hour             | VIEW       |                              |                      |                           |                          |                        |                    |          |               |                   |                  |               |                 | 
  testdb_e2e_psql_v?? | spanner_sys        | txn_stats_total_minute           | VIEW       |                              |                      |                           |                          |                        |                    |          |               |                   |                  |               |                 | 
-(78 rows)
+(77 rows)
 
diff --git a/samples/golang/migrate/sample_test.go b/samples/golang/migrate/sample_test.go
new file mode 100644
index 00000000..a4f57fa0
--- /dev/null
+++ b/samples/golang/migrate/sample_test.go
@@ -0,0 +1,22 @@
+/*
+Copyright 2024 Google LLC
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+    http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package main
+
+import "testing"
+
+func TestRunSample(t *testing.T) {
+	if _, err := runSample(); err != nil {
+		t.Errorf("failed to run sample: %v", err)
+	}
+}
diff --git a/samples/java/r2dbc/src/test/java/com/google/cloud/spanner/pgadapter/sample/SampleApplicationTest.java b/samples/java/r2dbc/src/test/java/com/google/cloud/spanner/pgadapter/sample/SampleApplicationTest.java
new file mode 100644
index 00000000..a0e425bb
--- /dev/null
+++ b/samples/java/r2dbc/src/test/java/com/google/cloud/spanner/pgadapter/sample/SampleApplicationTest.java
@@ -0,0 +1,53 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.cloud.spanner.pgadapter.sample;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.collect.ImmutableList;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.stream.Collectors;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class SampleApplicationTest {
+
+  @Test
+  public void testRunApplication() throws Exception {
+    ProcessBuilder builder = new ProcessBuilder();
+    ImmutableList<String> command = ImmutableList.of("mvn", "exec:java");
+    builder.command(command);
+    Process process = builder.start();
+
+    String errors;
+    String output;
+
+    try (BufferedReader reader =
+            new BufferedReader(new InputStreamReader(process.getInputStream()));
+        BufferedReader errorReader =
+            new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
+      errors = errorReader.lines().collect(Collectors.joining("\n"));
+      output = reader.lines().collect(Collectors.joining("\n"));
+    }
+
+    int res = process.waitFor();
+    assertEquals(errors, 0, res);
+    assertTrue(output, output.contains("Greeting: Hello World!"));
+  }
+}
diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/IntermediateStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/IntermediateStatement.java
index ee438e6b..50d7baff 100644
--- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/IntermediateStatement.java
+++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/IntermediateStatement.java
@@ -175,6 +175,15 @@ public class IntermediateStatement {
         return -1L;
       case UPDATE:
         long res = this.statementResult.getUpdateCount();
+        // The Connection API returns update count -1 if DML statements that are executed during
+        // DML batches. PostgreSQL-drivers expect this update count to be >= 0.
+        if (res == -1L) {
+          // Sometimes the application that is executing DML statements in a batch want the driver
+          // to return a specific update count. E.g. Hibernate expects all insert statements to
+          // return an update count of 1. This can be achieved by setting the session variable
+          // spanner.dml_batch_update_count to 1.
+          return getDmlBatchUpdateCount();
+        }
         return Math.max(res, 0L);
       case CLIENT_SIDE:
       case DDL:
@@ -184,6 +193,15 @@ public class IntermediateStatement {
     }
   }
 
+  private long getDmlBatchUpdateCount() {
+    // This value comes from the session variable 'spanner.dml_batch_update_count'.
+    return getConnectionHandler()
+        .getExtendedQueryProtocolHandler()
+        .getBackendConnection()
+        .getSessionState()
+        .getDmlBatchUpdateCount();
+  }
+
   /**
    * @return True if at some point in execution an exception was thrown. Fails if execution has not
    *     yet finished.
diff --git a/src/test/csharp/pgadapter_npgsql_tests/npgsql_tests/npgsql_tests.csproj b/src/test/csharp/pgadapter_npgsql_tests/npgsql_tests/npgsql_tests.csproj
index badf4c30..bffe394e 100644
--- a/src/test/csharp/pgadapter_npgsql_tests/npgsql_tests/npgsql_tests.csproj
+++ b/src/test/csharp/pgadapter_npgsql_tests/npgsql_tests/npgsql_tests.csproj
@@ -9,7 +9,7 @@
     </PropertyGroup>
 
     <ItemGroup>
-      <PackageReference Include="Npgsql" Version="8.0.4" />
+      <PackageReference Include="Npgsql" Version="8.0.5" />
     </ItemGroup>
 
 </Project>
diff --git a/src/test/golang/pgadapter_gorm_tests/go.mod b/src/test/golang/pgadapter_gorm_tests/go.mod
index 588847f9..539e3354 100644
--- a/src/test/golang/pgadapter_gorm_tests/go.mod
+++ b/src/test/golang/pgadapter_gorm_tests/go.mod
@@ -3,9 +3,9 @@ module cloud.google.com/pgadapter_gorm_tests
 go 1.17
 
 require (
-	github.com/jackc/pgtype v1.14.3
+	github.com/jackc/pgtype v1.14.4
 	github.com/shopspring/decimal v1.4.0
-	gorm.io/datatypes v1.2.2
+	gorm.io/datatypes v1.2.4
 	gorm.io/driver/postgres v1.5.9
 	gorm.io/gorm v1.25.12
 )
diff --git a/src/test/golang/pgadapter_gorm_tests/go.sum b/src/test/golang/pgadapter_gorm_tests/go.sum
index 39e6c01e..6ff836a4 100644
--- a/src/test/golang/pgadapter_gorm_tests/go.sum
+++ b/src/test/golang/pgadapter_gorm_tests/go.sum
@@ -74,8 +74,8 @@ github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCM
 github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
 github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
 github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
-github.com/jackc/pgtype v1.14.3 h1:h6W9cPuHsRWQFTWUZMAKMgG5jSwQI0Zurzdvlx3Plus=
-github.com/jackc/pgtype v1.14.3/go.mod h1:aKeozOde08iifGosdJpz9MBZonJOUJxqNpPBcMJTlVA=
+github.com/jackc/pgtype v1.14.4 h1:fKuNiCumbKTAIxQwXfB/nsrnkEI6bPJrrSiMKgbJ2j8=
+github.com/jackc/pgtype v1.14.4/go.mod h1:aKeozOde08iifGosdJpz9MBZonJOUJxqNpPBcMJTlVA=
 github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
 github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
 github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
@@ -280,8 +280,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gorm.io/datatypes v1.2.2 h1:sdn7ZmG4l7JWtMDUb3L98f2Ym7CO5F8mZLlrQJMfF9g=
-gorm.io/datatypes v1.2.2/go.mod h1:f4BsLcFAX67szSv8svwLRjklArSHAvHLeE3pXAS5DZI=
+gorm.io/datatypes v1.2.4 h1:uZmGAcK/QZ0uyfCuVg0VQY1ZmV9h1fuG0tMwKByO1z4=
+gorm.io/datatypes v1.2.4/go.mod h1:f4BsLcFAX67szSv8svwLRjklArSHAvHLeE3pXAS5DZI=
 gorm.io/driver/mysql v1.5.6 h1:Ld4mkIickM+EliaQZQx3uOJDJHtrd70MxAUqWqlx3Y8=
 gorm.io/driver/mysql v1.5.6/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
 gorm.io/driver/postgres v1.5.0/go.mod h1:FUZXzO+5Uqg5zzwzv4KK49R8lvGIyscBOqYrtI1Ce9A=
diff --git a/src/test/golang/pgadapter_pgx_tests/go.mod b/src/test/golang/pgadapter_pgx_tests/go.mod
index adae1d91..9b9432e9 100644
--- a/src/test/golang/pgadapter_pgx_tests/go.mod
+++ b/src/test/golang/pgadapter_pgx_tests/go.mod
@@ -4,7 +4,7 @@ go 1.17
 
 require (
 	github.com/jackc/pgconn v1.14.3
-	github.com/jackc/pgtype v1.14.3
+	github.com/jackc/pgtype v1.14.4
 	github.com/jackc/pgx/v4 v4.18.3
 )
 
diff --git a/src/test/golang/pgadapter_pgx_tests/go.sum b/src/test/golang/pgadapter_pgx_tests/go.sum
index 07f61d67..9423355d 100644
--- a/src/test/golang/pgadapter_pgx_tests/go.sum
+++ b/src/test/golang/pgadapter_pgx_tests/go.sum
@@ -53,8 +53,8 @@ github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCM
 github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
 github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
 github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
-github.com/jackc/pgtype v1.14.3 h1:h6W9cPuHsRWQFTWUZMAKMgG5jSwQI0Zurzdvlx3Plus=
-github.com/jackc/pgtype v1.14.3/go.mod h1:aKeozOde08iifGosdJpz9MBZonJOUJxqNpPBcMJTlVA=
+github.com/jackc/pgtype v1.14.4 h1:fKuNiCumbKTAIxQwXfB/nsrnkEI6bPJrrSiMKgbJ2j8=
+github.com/jackc/pgtype v1.14.4/go.mod h1:aKeozOde08iifGosdJpz9MBZonJOUJxqNpPBcMJTlVA=
 github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
 github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
 github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
diff --git a/src/test/java/com/google/cloud/spanner/pgadapter/ITJdbcMetadataTest.java b/src/test/java/com/google/cloud/spanner/pgadapter/ITJdbcMetadataTest.java
index b3c390c6..795e262d 100644
--- a/src/test/java/com/google/cloud/spanner/pgadapter/ITJdbcMetadataTest.java
+++ b/src/test/java/com/google/cloud/spanner/pgadapter/ITJdbcMetadataTest.java
@@ -46,34 +46,25 @@ import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
-import org.junit.runners.Parameterized.Parameters;
+import org.junit.runners.JUnit4;
 
 @Category({IntegrationTest.class, SlowTest.class})
-@RunWith(Parameterized.class)
+@RunWith(JUnit4.class)
 public class ITJdbcMetadataTest implements IntegrationTest {
   private static final String[] VERSIONS =
       new String[] {
-        "42.7.2", "42.7.1", "42.7.0", "42.6.0", "42.5.4", "42.5.3", "42.5.2", "42.5.1", "42.5.0",
-        "42.4.2", "42.4.1", "42.4.0", "42.3.6", "42.3.5", "42.3.4", "42.3.3", "42.3.2", "42.3.1",
-        "42.3.0", "42.2.25", "42.2.24", "42.2.23", "42.2.22", "42.2.21", "42.2.20", "42.2.19",
-        "42.2.18", "42.2.17", "42.2.16", "42.2.15", "42.2.14", "42.2.13", "42.2.12", "42.2.11",
-        "42.2.10", "42.2.9", "42.2.8", "42.2.7", "42.2.6", "42.2.5", "42.2.4", "42.2.3", "42.2.2",
-        "42.2.1", "42.2.0", "42.1.4",
+        "42.7.4", "42.7.3", "42.7.2", "42.7.1", "42.7.0", "42.6.0", "42.5.4", "42.5.3", "42.5.2",
+        "42.5.1", "42.5.0", "42.4.2", "42.4.1", "42.4.0", "42.3.6", "42.3.5", "42.3.4", "42.3.3",
+        "42.3.2", "42.3.1", "42.3.0", "42.2.25", "42.2.24", "42.2.23", "42.2.22", "42.2.21",
+        "42.2.20", "42.2.19", "42.2.18", "42.2.17", "42.2.16", "42.2.15", "42.2.14", "42.2.13",
+        "42.2.12", "42.2.11", "42.2.10", "42.2.9", "42.2.8", "42.2.7", "42.2.6", "42.2.5", "42.2.4",
+        "42.2.3", "42.2.2", "42.2.1", "42.2.0", "42.1.4",
         /* "42.1.3", "42.1.2", "42.1.1", "42.1.0", "42.0.0" */
       };
 
   private static final PgAdapterTestEnv testEnv = new PgAdapterTestEnv();
   private static Database database;
 
-  @Parameter public String pgVersion;
-
-  @Parameters(name = "pgVersion = {0}")
-  public static Object[] data() {
-    return new Object[] {"1.0", "14.1"};
-  }
-
   @BeforeClass
   public static void setup() {
     testEnv.setUp();
@@ -119,9 +110,7 @@ public class ITJdbcMetadataTest implements IntegrationTest {
   }
 
   private String createUrl() {
-    return String.format(
-        "jdbc:postgresql://%s/?options=-c%%20server_version=%s",
-        testEnv.getPGAdapterHostAndPort(), pgVersion);
+    return String.format("jdbc:postgresql://%s/", testEnv.getPGAdapterHostAndPort());
   }
 
   private void runForAllVersions(BiConsumer<Connection, String> runnable) throws Exception {
@@ -201,10 +190,10 @@ public class ITJdbcMetadataTest implements IntegrationTest {
             DatabaseMetaData metadata = connection.getMetaData();
             // Options in the connection string are only supported from version 42.2.6.
             if (comparableVersion.compareTo("42.2.006") >= 0) {
-              assertEquals(pgVersion, metadata.getDatabaseProductVersion());
+              assertEquals("14.1", metadata.getDatabaseProductVersion());
             } else if (testEnv.getServer() != null) {
               assertEquals(
-                  pgVersion,
+                  "14.1",
                   testEnv.getServer().getOptions().getServerVersion(),
                   metadata.getDatabaseProductVersion());
             }
diff --git a/src/test/java/com/google/cloud/spanner/pgadapter/ITQueryTest.java b/src/test/java/com/google/cloud/spanner/pgadapter/ITQueryTest.java
index 0075b0c3..81888e0d 100644
--- a/src/test/java/com/google/cloud/spanner/pgadapter/ITQueryTest.java
+++ b/src/test/java/com/google/cloud/spanner/pgadapter/ITQueryTest.java
@@ -16,8 +16,10 @@ package com.google.cloud.spanner.pgadapter;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import com.google.cloud.spanner.Database;
+import com.google.common.base.Stopwatch;
 import com.google.common.collect.ImmutableList;
 import com.google.common.primitives.Bytes;
 import java.io.ByteArrayInputStream;
@@ -28,6 +30,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -51,6 +54,13 @@ public final class ITQueryTest implements IntegrationTest {
 
   @AfterClass
   public static void teardown() {
+    // Wait a bit until all connections have been terminated (or fail if they fail to terminate).
+    Stopwatch stopwatch = Stopwatch.createStarted();
+    while (testEnv.getServer().getNumberOfConnections() > 0
+        && stopwatch.elapsed(TimeUnit.MILLISECONDS) < 1000) {
+      Thread.yield();
+    }
+    assertTrue(testEnv.getServer().getConnectionHandlers().isEmpty());
     testEnv.stopPGAdapterServer();
     testEnv.cleanUp();
   }
@@ -109,6 +119,8 @@ public final class ITQueryTest implements IntegrationTest {
     // Value of the column: '42'
     assertEquals('4', dataRowIn.readByte());
     assertEquals('2', dataRowIn.readByte());
+
+    clientSocket.close();
   }
 
   @Test
@@ -183,5 +195,7 @@ public final class ITQueryTest implements IntegrationTest {
     assertArrayEquals(dataRow2, dataRows[2].getPayload());
     assertArrayEquals(commandCompleteData, commandComplete.getPayload());
     assertArrayEquals(readyForQueryData, readyForQuery.getPayload());
+
+    clientSocket.close();
   }
 }
diff --git a/src/test/java/com/google/cloud/spanner/pgadapter/JdbcMockServerTest.java b/src/test/java/com/google/cloud/spanner/pgadapter/JdbcMockServerTest.java
index b8eef2cd..f4f8eb86 100644
--- a/src/test/java/com/google/cloud/spanner/pgadapter/JdbcMockServerTest.java
+++ b/src/test/java/com/google/cloud/spanner/pgadapter/JdbcMockServerTest.java
@@ -1047,13 +1047,22 @@ public class JdbcMockServerTest extends AbstractMockServerTest {
 
   @Test
   public void testSelectCurrentSchema() throws SQLException {
-    String sql = "SELECT current_schema";
+    for (String sql :
+        new String[] {
+          "select current_schema",
+          "select current_schema()",
+          "SELECT current_schema",
+          "SELECT current_schema()",
+          "SELECT CURRENT_SCHEMA",
+          "SELECT CURRENT_SCHEMA()",
+        }) {
 
-    try (Connection connection = DriverManager.getConnection(createUrl())) {
-      try (ResultSet resultSet = connection.createStatement().executeQuery(sql)) {
-        assertTrue(resultSet.next());
-        assertEquals("public", resultSet.getString("current_schema"));
-        assertFalse(resultSet.next());
+      try (Connection connection = DriverManager.getConnection(createUrl())) {
+        try (ResultSet resultSet = connection.createStatement().executeQuery(sql)) {
+          assertTrue(resultSet.next());
+          assertEquals("public", resultSet.getString("current_schema"));
+          assertFalse(resultSet.next());
+        }
       }
     }
 
@@ -5542,6 +5551,70 @@ public class JdbcMockServerTest extends AbstractMockServerTest {
     assertEquals(TimeUnit.MILLISECONDS.toNanos(20), request.getMaxCommitDelay().getNanos());
   }
 
+  @Test
+  public void testDmlBatchUpdateCount() throws SQLException {
+    String sql = "insert into foo (id) values (1)";
+    mockSpanner.putStatementResult(StatementResult.update(Statement.of(sql), 1L));
+
+    try (Connection connection = DriverManager.getConnection(createUrl());
+        java.sql.Statement statement = connection.createStatement()) {
+      connection.setAutoCommit(false);
+
+      for (Integer updateCount : new Integer[] {null, 1, 2, 10}) {
+        if (updateCount != null) {
+          // 'set local' means that the effect of the statement will be undone by the end of the
+          // transaction.
+          statement.execute("set local spanner.dml_batch_update_count=" + updateCount);
+        }
+        statement.execute("start batch dml");
+        assertEquals(updateCount == null ? 0 : updateCount, statement.executeUpdate(sql));
+        assertEquals(updateCount == null ? 0 : updateCount, statement.executeUpdate(sql));
+        statement.execute("run batch");
+        connection.commit();
+      }
+    }
+    assertEquals(4, mockSpanner.countRequestsOfType(ExecuteBatchDmlRequest.class));
+  }
+
+  @Test
+  public void testGSSAPI() throws SQLException {
+    for (String gss : new String[] {"disable", "allow", "prefer"}) {
+      try (Connection connection =
+              DriverManager.getConnection(createUrl() + String.format("&gssEncMode=%s", gss));
+          java.sql.Statement statement = connection.createStatement()) {
+        verifySelect1(statement);
+      }
+    }
+    SQLException exception =
+        assertThrows(
+            SQLException.class,
+            () -> DriverManager.getConnection(createUrl() + "&gssEncMode=require"));
+    assertEquals(
+        SQLState.SQLServerRejectedEstablishmentOfSQLConnection.toString(), exception.getSQLState());
+    assertTrue(
+        exception.getMessage(),
+        exception.getMessage().contains("The server does not support GSS Encryption"));
+  }
+
+  @Test
+  public void testShutdown_failsByDefault() throws SQLException {
+    try (Connection connection = DriverManager.getConnection(createUrl());
+        java.sql.Statement statement = connection.createStatement()) {
+      PSQLException exception =
+          assertThrows(PSQLException.class, () -> statement.execute("shutdown"));
+      assertEquals(
+          "ERROR: SHUTDOWN [SMART | FAST | IMMEDIATE] statement is not enabled for this server. "
+              + "Start PGAdapter with --allow_shutdown_statement to enable the use of the SHUTDOWN statement.",
+          exception.getMessage());
+    }
+  }
+
+  private void verifySelect1(java.sql.Statement statement) throws SQLException {
+    try (ResultSet resultSet = statement.executeQuery("SELECT 1")) {
+      assertTrue(resultSet.next());
+    }
+  }
+
   @Ignore("Only used for manual performance testing")
   @Test
   public void testBasePerformance() throws SQLException {
diff --git a/src/test/java/com/google/cloud/spanner/pgadapter/ShutdownModeMockServerTest.java b/src/test/java/com/google/cloud/spanner/pgadapter/ShutdownModeMockServerTest.java
index e7d3d61b..ff3e5ca8 100644
--- a/src/test/java/com/google/cloud/spanner/pgadapter/ShutdownModeMockServerTest.java
+++ b/src/test/java/com/google/cloud/spanner/pgadapter/ShutdownModeMockServerTest.java
@@ -32,15 +32,26 @@ import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.sql.Statement;
 import java.util.concurrent.TimeUnit;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
-@RunWith(JUnit4.class)
+@RunWith(Parameterized.class)
 public class ShutdownModeMockServerTest extends AbstractMockServerTest {
+
+  @Parameter public boolean useSqlStatement;
+
+  @Parameters(name = "useSqlStatement = {0}")
+  public static Object[] data() {
+    return new Object[] {false, true};
+  }
+
   private ProxyServer proxyServer;
 
   @Before
@@ -51,7 +62,8 @@ public class ShutdownModeMockServerTest extends AbstractMockServerTest {
         .enableDebugMode()
         .setUsePlainText()
         .setEndpoint(String.format("localhost:%d", spannerServer.getPort()))
-        .setCredentials(NoCredentials.getInstance());
+        .setCredentials(NoCredentials.getInstance())
+        .setAllowShutdownStatement(true);
     proxyServer = new ProxyServer(builder.build(), OpenTelemetry.noop());
     proxyServer.startServer();
   }
@@ -71,7 +83,7 @@ public class ShutdownModeMockServerTest extends AbstractMockServerTest {
   public void testSmartShutdown() throws SQLException {
     String sql = "SELECT 1";
 
-    ShutdownHandler shutdownHandler = ShutdownHandler.createForServer(proxyServer);
+    ShutdownHandler shutdownHandler = createShutdownHandler();
     // Verify that the server is running.
     assertEquals(State.RUNNING, proxyServer.state());
 
@@ -83,7 +95,11 @@ public class ShutdownModeMockServerTest extends AbstractMockServerTest {
         assertFalse(resultSet.next());
       }
       // Initiate a smart shutdown.
-      shutdownHandler.shutdown(ShutdownMode.SMART);
+      if (useSqlStatement) {
+        connection.createStatement().execute("shutdown smart");
+      } else {
+        shutdownHandler.shutdown(ShutdownMode.SMART);
+      }
       // Wait until the server port is no longer open.
       Stopwatch stopwatch = Stopwatch.createStarted();
       while (isPortListening(proxyServer.getLocalPort())
@@ -127,7 +143,7 @@ public class ShutdownModeMockServerTest extends AbstractMockServerTest {
   public void testSmartShutdownWithoutConnections() throws SQLException {
     String sql = "SELECT 1";
 
-    ShutdownHandler shutdownHandler = ShutdownHandler.createForServer(proxyServer);
+    ShutdownHandler shutdownHandler = createShutdownHandler();
     // Verify that the server is running.
     assertEquals(State.RUNNING, proxyServer.state());
 
@@ -140,7 +156,14 @@ public class ShutdownModeMockServerTest extends AbstractMockServerTest {
       }
     }
     // Initiate a smart shutdown.
-    shutdownHandler.shutdown(ShutdownMode.SMART);
+    if (useSqlStatement) {
+      try (Connection connection = DriverManager.getConnection(createUrl());
+          Statement statement = connection.createStatement()) {
+        statement.execute("shutdown smart");
+      }
+    } else {
+      shutdownHandler.shutdown(ShutdownMode.SMART);
+    }
     // Wait until the server port is no longer open.
     Stopwatch stopwatch = Stopwatch.createStarted();
     while (isPortListening(proxyServer.getLocalPort())
@@ -169,7 +192,7 @@ public class ShutdownModeMockServerTest extends AbstractMockServerTest {
   public void testFastShutdown() throws SQLException {
     String sql = "SELECT 1";
 
-    ShutdownHandler shutdownHandler = ShutdownHandler.createForServer(proxyServer);
+    ShutdownHandler shutdownHandler = createShutdownHandler();
     // Verify that the server is running.
     assertEquals(State.RUNNING, proxyServer.state());
 
@@ -181,7 +204,11 @@ public class ShutdownModeMockServerTest extends AbstractMockServerTest {
         assertFalse(resultSet.next());
       }
       // Initiate a fast shutdown.
-      shutdownHandler.shutdown(ShutdownMode.FAST);
+      if (useSqlStatement) {
+        connection.createStatement().execute("shutdown fast");
+      } else {
+        shutdownHandler.shutdown(ShutdownMode.FAST);
+      }
       // Verify that the server stops.
       Stopwatch stopwatch = Stopwatch.createStarted();
       while (proxyServer.state() != State.TERMINATED
@@ -209,7 +236,7 @@ public class ShutdownModeMockServerTest extends AbstractMockServerTest {
   public void testSmartShutdownFollowedByFastShutdown() throws SQLException {
     String sql = "SELECT 1";
 
-    ShutdownHandler shutdownHandler = ShutdownHandler.createForServer(proxyServer);
+    ShutdownHandler shutdownHandler = createShutdownHandler();
     // Verify that the server is running.
     assertEquals(State.RUNNING, proxyServer.state());
 
@@ -221,7 +248,11 @@ public class ShutdownModeMockServerTest extends AbstractMockServerTest {
         assertFalse(resultSet.next());
       }
       // Initiate a smart shutdown.
-      shutdownHandler.shutdown(ShutdownMode.SMART);
+      if (useSqlStatement) {
+        connection.createStatement().execute("shutdown smart");
+      } else {
+        shutdownHandler.shutdown(ShutdownMode.SMART);
+      }
       // Wait until the server port is no longer open.
       Stopwatch stopwatch = Stopwatch.createStarted();
       while (isPortListening(proxyServer.getLocalPort())
@@ -248,7 +279,11 @@ public class ShutdownModeMockServerTest extends AbstractMockServerTest {
       assertEquals(State.STOPPING, proxyServer.state());
 
       // Now force the server to stop by initiating a fast shutdown.
-      shutdownHandler.shutdown(ShutdownMode.FAST);
+      if (useSqlStatement) {
+        connection.createStatement().execute("shutdown fast");
+      } else {
+        shutdownHandler.shutdown(ShutdownMode.FAST);
+      }
       stopwatch = Stopwatch.createStarted();
       while (proxyServer.state() != State.TERMINATED
           && stopwatch.elapsed(TimeUnit.MILLISECONDS) < 2000) {
@@ -263,6 +298,10 @@ public class ShutdownModeMockServerTest extends AbstractMockServerTest {
     }
   }
 
+  ShutdownHandler createShutdownHandler() {
+    return useSqlStatement ? null : ShutdownHandler.createForServer(this.proxyServer);
+  }
+
   boolean isPortListening(int port) {
     try (Socket ignored = new Socket("localhost", port)) {
       return true;
diff --git a/src/test/java/com/google/cloud/spanner/pgadapter/statements/BackendConnectionTest.java b/src/test/java/com/google/cloud/spanner/pgadapter/statements/BackendConnectionTest.java
index 58a06cd4..7edfa78a 100644
--- a/src/test/java/com/google/cloud/spanner/pgadapter/statements/BackendConnectionTest.java
+++ b/src/test/java/com/google/cloud/spanner/pgadapter/statements/BackendConnectionTest.java
@@ -87,7 +87,7 @@ public class BackendConnectionTest {
   private static final Runnable DO_NOTHING = () -> {};
   private static final DatabaseId DATABASE_ID = DatabaseId.of("p", "i", "d");
   private static final Attributes METRIC_ATTRIBUTES =
-      ExtendedQueryProtocolHandler.createMetricAttributes(DATABASE_ID, "test-id");
+      ExtendedQueryProtocolHandler.createMetricAttributes(DATABASE_ID);
 
   @Test
   public void testExtractDdlUpdateCounts() {
diff --git a/src/test/java/com/google/cloud/spanner/pgadapter/statements/ShutdownStatementTest.java b/src/test/java/com/google/cloud/spanner/pgadapter/statements/ShutdownStatementTest.java
new file mode 100644
index 00000000..f3369114
--- /dev/null
+++ b/src/test/java/com/google/cloud/spanner/pgadapter/statements/ShutdownStatementTest.java
@@ -0,0 +1,163 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.cloud.spanner.pgadapter.statements;
+
+import static com.google.cloud.spanner.pgadapter.statements.ShutdownStatement.parse;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.google.cloud.spanner.Dialect;
+import com.google.cloud.spanner.Statement;
+import com.google.cloud.spanner.connection.AbstractStatementParser;
+import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement;
+import com.google.cloud.spanner.pgadapter.ConnectionHandler;
+import com.google.cloud.spanner.pgadapter.ProxyServer;
+import com.google.cloud.spanner.pgadapter.ProxyServer.ShutdownMode;
+import com.google.cloud.spanner.pgadapter.ShutdownHandler;
+import com.google.cloud.spanner.pgadapter.error.PGException;
+import com.google.cloud.spanner.pgadapter.error.SQLState;
+import com.google.cloud.spanner.pgadapter.metadata.ConnectionMetadata;
+import com.google.cloud.spanner.pgadapter.metadata.OptionsMetadata;
+import com.google.cloud.spanner.pgadapter.statements.IntermediateStatement.ResultNotReadyBehavior;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class ShutdownStatementTest {
+
+  @Test
+  public void testParseShutdown() {
+    ProxyServer server = mock(ProxyServer.class);
+
+    assertEquals(ShutdownMode.FAST, parse("shutdown", server).shutdownMode);
+    assertEquals(ShutdownMode.FAST, parse("Shutdown", server).shutdownMode);
+    assertEquals(ShutdownMode.FAST, parse("SHUTDOWN", server).shutdownMode);
+    assertEquals(ShutdownMode.FAST, parse("\t shutdown \n", server).shutdownMode);
+    assertEquals(ShutdownMode.IMMEDIATE, parse("shutdown immediate", server).shutdownMode);
+    assertEquals(ShutdownMode.SMART, parse("shutdown smart", server).shutdownMode);
+    assertEquals(ShutdownMode.FAST, parse("shutdown fast", server).shutdownMode);
+    assertEquals(ShutdownMode.FAST, parse("shutdown\tfast", server).shutdownMode);
+    assertEquals(ShutdownMode.FAST, parse("shutdown\nfast", server).shutdownMode);
+    assertEquals(ShutdownMode.FAST, parse("shutdown\n\t   fast", server).shutdownMode);
+
+    PGException exception;
+    exception = assertThrows(PGException.class, () -> parse("shutdown fast immediate", server));
+    assertEquals(SQLState.SyntaxError, exception.getSQLState());
+    exception = assertThrows(PGException.class, () -> parse("shutdown foo", server));
+    assertEquals(SQLState.SyntaxError, exception.getSQLState());
+    exception = assertThrows(PGException.class, () -> parse("shutdown foo fast", server));
+    assertEquals(SQLState.SyntaxError, exception.getSQLState());
+    exception = assertThrows(PGException.class, () -> parse("shutdown fast,", server));
+    assertEquals(SQLState.SyntaxError, exception.getSQLState());
+    exception = assertThrows(PGException.class, () -> parse("fast shutdown", server));
+    assertEquals(SQLState.SyntaxError, exception.getSQLState());
+  }
+
+  @Test
+  public void testShutdownStatement_usesDefaultShutdownMode() throws Exception {
+    OptionsMetadata options = mock(OptionsMetadata.class);
+    when(options.isAllowShutdownStatement()).thenReturn(true);
+    ConnectionHandler connectionHandler = mock(ConnectionHandler.class);
+    ProxyServer server = mock(ProxyServer.class);
+    when(connectionHandler.getServer()).thenReturn(server);
+    when(connectionHandler.getConnectionMetadata()).thenReturn(mock(ConnectionMetadata.class));
+    ShutdownHandler shutdownHandler = mock(ShutdownHandler.class);
+    when(server.getOrCreateShutdownHandler()).thenReturn(shutdownHandler);
+
+    String sql = "shutdown";
+    Statement originalStatement = Statement.of(sql);
+    ParsedStatement parsedStatement =
+        AbstractStatementParser.getInstance(Dialect.POSTGRESQL).parse(originalStatement);
+    ShutdownStatement statement =
+        new ShutdownStatement(
+            connectionHandler, options, /* name= */ "", parsedStatement, originalStatement);
+
+    statement.executeAsync(mock(BackendConnection.class));
+    statement.close();
+
+    // PGAdapter uses FAST shutdown mode by default.
+    // We need to use a timeout, as the shutdown handler runs async. The wait time is normally much
+    // less than the 1000 milliseconds that is used as the timeout value.
+    verify(shutdownHandler, timeout(1000L)).shutdown(ShutdownMode.FAST);
+  }
+
+  @Test
+  public void testShutdownStatement_usesParsedShutdownMode() throws Exception {
+    OptionsMetadata options = mock(OptionsMetadata.class);
+    when(options.isAllowShutdownStatement()).thenReturn(true);
+    ConnectionHandler connectionHandler = mock(ConnectionHandler.class);
+    ProxyServer server = mock(ProxyServer.class);
+    when(connectionHandler.getServer()).thenReturn(server);
+    when(connectionHandler.getConnectionMetadata()).thenReturn(mock(ConnectionMetadata.class));
+    ShutdownHandler shutdownHandler = mock(ShutdownHandler.class);
+    when(server.getOrCreateShutdownHandler()).thenReturn(shutdownHandler);
+
+    String sql = "shutdown smart";
+    Statement originalStatement = Statement.of(sql);
+    ParsedStatement parsedStatement =
+        AbstractStatementParser.getInstance(Dialect.POSTGRESQL).parse(originalStatement);
+    ShutdownStatement statement =
+        new ShutdownStatement(
+            connectionHandler, options, /* name= */ "", parsedStatement, originalStatement);
+
+    statement.executeAsync(mock(BackendConnection.class));
+    statement.close();
+
+    // The shutdown mode from the SQL statement should be used.
+    // We need to use a timeout, as the shutdown handler runs async. The wait time is normally much
+    // less than the 1000 milliseconds that is used as the timeout value.
+    verify(shutdownHandler, timeout(1000L)).shutdown(ShutdownMode.SMART);
+  }
+
+  @Test
+  public void testShutdownStatement_returnsErrorIfNotEnabled() throws Exception {
+    OptionsMetadata options = mock(OptionsMetadata.class);
+    when(options.isAllowShutdownStatement()).thenReturn(false);
+    ConnectionHandler connectionHandler = mock(ConnectionHandler.class);
+    ProxyServer server = mock(ProxyServer.class);
+    when(connectionHandler.getServer()).thenReturn(server);
+    when(connectionHandler.getConnectionMetadata()).thenReturn(mock(ConnectionMetadata.class));
+
+    String sql = "shutdown";
+    Statement originalStatement = Statement.of(sql);
+    ParsedStatement parsedStatement =
+        AbstractStatementParser.getInstance(Dialect.POSTGRESQL).parse(originalStatement);
+    ShutdownStatement statement =
+        new ShutdownStatement(
+            connectionHandler, options, /* name= */ "", parsedStatement, originalStatement);
+
+    // Execute the statement and then get the result.
+    statement.executeAsync(mock(BackendConnection.class));
+    statement.close();
+    // The result should be an exception.
+    statement.initFutureResult(ResultNotReadyBehavior.FAIL);
+    assertNotNull(statement.getException());
+    assertEquals(
+        "SHUTDOWN [SMART | FAST | IMMEDIATE] statement is not enabled for this server. "
+            + "Start PGAdapter with --allow_shutdown_statement to enable the use of the SHUTDOWN statement.",
+        statement.getException().getMessage());
+
+    // The server should not be shut down.
+    verify(server, never()).stopServer(any(ShutdownMode.class));
+  }
+}
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 9cac0270..a5513ef5 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
@@ -97,7 +97,7 @@ public class StatementTest {
   private static final Runnable DO_NOTHING = () -> {};
   private static final DatabaseId DATABASE_ID = DatabaseId.of("p", "i", "d");
   private static final Attributes METRIC_ATTRIBUTES =
-      ExtendedQueryProtocolHandler.createMetricAttributes(DATABASE_ID, "test-connection");
+      ExtendedQueryProtocolHandler.createMetricAttributes(DATABASE_ID);
 
   private static ParsedStatement parse(String sql) {
     return PARSER.parse(Statement.of(sql));
@@ -521,7 +521,7 @@ public class StatementTest {
         new BackendConnection(
             NOOP_OTEL,
             NOOP_OTEL_METER,
-            ExtendedQueryProtocolHandler.createMetricAttributes(databaseId, "test-connection"),
+            ExtendedQueryProtocolHandler.createMetricAttributes(databaseId),
             UUID.randomUUID().toString(),
             DO_NOTHING,
             databaseId,
@@ -629,7 +629,7 @@ public class StatementTest {
         new BackendConnection(
             NOOP_OTEL,
             NOOP_OTEL_METER,
-            ExtendedQueryProtocolHandler.createMetricAttributes(databaseId, "test-connection"),
+            ExtendedQueryProtocolHandler.createMetricAttributes(databaseId),
             UUID.randomUUID().toString(),
             DO_NOTHING,
             databaseId,
@@ -688,7 +688,7 @@ public class StatementTest {
         new BackendConnection(
             NOOP_OTEL,
             NOOP_OTEL_METER,
-            ExtendedQueryProtocolHandler.createMetricAttributes(databaseId, "test-connection"),
+            ExtendedQueryProtocolHandler.createMetricAttributes(databaseId),
             UUID.randomUUID().toString(),
             DO_NOTHING,
             databaseId,
diff --git a/src/test/nodejs/node-postgres/package.json b/src/test/nodejs/node-postgres/package.json
index b511761e..4fd653a4 100644
--- a/src/test/nodejs/node-postgres/package.json
+++ b/src/test/nodejs/node-postgres/package.json
@@ -6,7 +6,7 @@
   "devDependencies": {
     "@types/node": "^22.1.0",
     "ts-node": "10.9.2",
-    "typescript": "5.6.2"
+    "typescript": "5.6.3"
   },
   "dependencies": {
     "pg": "^8.9.0",
diff --git a/src/test/nodejs/sequelize-tests/package.json b/src/test/nodejs/sequelize-tests/package.json
index 91fefbb4..73b15de9 100644
--- a/src/test/nodejs/sequelize-tests/package.json
+++ b/src/test/nodejs/sequelize-tests/package.json
@@ -6,7 +6,7 @@
   "devDependencies": {
     "@types/node": "^22.1.0",
     "ts-node": "10.9.2",
-    "typescript": "5.6.2"
+    "typescript": "5.6.3"
   },
   "dependencies": {
     "pg": "^8.11.3",
diff --git a/src/test/nodejs/typeorm/data-test/package.json b/src/test/nodejs/typeorm/data-test/package.json
index 93ce558c..19c135ee 100644
--- a/src/test/nodejs/typeorm/data-test/package.json
+++ b/src/test/nodejs/typeorm/data-test/package.json
@@ -6,7 +6,7 @@
    "devDependencies": {
       "ts-node": "10.9.2",
       "@types/node": "^22.1.0",
-      "typescript": "5.6.2"
+      "typescript": "5.6.3"
    },
    "dependencies": {
       "typeorm": "0.3.20",
diff --git a/wrappers/golang/pgadapter_test.go b/wrappers/golang/pgadapter_test.go
index 7ed8260b..1652faae 100644
--- a/wrappers/golang/pgadapter_test.go
+++ b/wrappers/golang/pgadapter_test.go
@@ -21,6 +21,7 @@ import (
 	"net"
 	"os"
 	"path/filepath"
+	"strings"
 	"testing"
 )
 
@@ -103,7 +104,13 @@ func TestStart(t *testing.T) {
 		}
 		err = pgadapter.Stop(context.Background())
 		if err != nil {
-			t.Fatalf("failed to stop PGAdapter: %v", err)
+			msg := err.Error()
+			if strings.Contains(msg, "removal of container") && strings.Contains(msg, "is already in progress") {
+				// warn and ignore
+				t.Logf("container already being removed: %v", err)
+			} else {
+				t.Fatalf("failed to stop PGAdapter: %v", err)
+			}
 		}
 	}
 }