From ed51609aaf29de6d313eb1f85064fbfea3bad917 Mon Sep 17 00:00:00 2001
From: David Li
Date: Tue, 18 Aug 2026 13:48:43 +0900
Subject: [PATCH 1/9] test(c/driver/postgresql): validate against compatible
vendors
Closes #4693.
Assisted-by: GPT-5.6 Sol
---
.github/workflows/integration.yml | 236 ++++++++++++++----
.../type/bind/int32.txtcase | 29 +++
.../type/bind/timestamp_ns.txtcase | 44 ++++
.../type/bind/timestamptz_ns.txtcase | 50 ++++
.../type/literal/int32.txtcase | 29 +++
.../type/select/int32.txtcase | 29 +++
.../postgresql/validation/tests/conftest.py | 19 +-
.../postgresql/validation/tests/postgresql.py | 105 +++++++-
.../validation/tests/test_connection.py | 41 ++-
.../validation/tests/test_ingest.py | 3 +-
.../postgresql/validation/tests/test_query.py | 3 +-
.../validation/tests/test_statement.py | 3 +-
ci/scripts/validate.sh | 8 +-
compose.yaml | 123 +++++++++
14 files changed, 653 insertions(+), 69 deletions(-)
create mode 100644 c/driver/postgresql/validation/queries-cockroachdb/type/bind/int32.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cockroachdb/type/bind/timestamp_ns.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cockroachdb/type/bind/timestamptz_ns.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cockroachdb/type/literal/int32.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cockroachdb/type/select/int32.txtcase
diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
index 19199451f5..3abc340e6a 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -26,6 +26,7 @@ on:
- "ci/**"
- "go/**"
- "python/**"
+ - "compose.yaml"
- ".github/workflows/integration.yml"
push:
branches-ignore:
@@ -35,6 +36,7 @@ on:
- "ci/**"
- "go/**"
- "python/**"
+ - "compose.yaml"
- ".github/workflows/integration.yml"
concurrency:
@@ -172,8 +174,8 @@ jobs:
run: |
docker compose down
- postgresql:
- name: "PostgreSQL Integration Tests"
+ postgresql-build:
+ name: "PostgreSQL Build"
runs-on: ubuntu-latest
steps:
- name: Free up disk space
@@ -216,74 +218,204 @@ jobs:
run: |
./ci/scripts/cpp_build.sh "$(pwd)" "$(pwd)/build"
./ci/scripts/python_build.sh "$(pwd)" "$(pwd)/build"
- - name: Configure Integration Env Vars
+ # Artifact actions do not preserve symlinks, so archive the build tree and
+ # the generated Python extension/library files ourselves.
+ - name: Archive PostgreSQL build
run: |
- pip install python-dotenv[cli]
- python -m dotenv -f .env list --format simple | tee -a $GITHUB_ENV
- echo "ADBC_USE_ASAN=ON" >> $GITHUB_ENV
- echo "ADBC_USE_UBSAN=ON" >> $GITHUB_ENV
+ tar --create --gzip --file postgresql-build.tgz \
+ build \
+ python/adbc_driver_manager \
+ python/adbc_driver_postgresql
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: postgresql-build
+ retention-days: 3
+ path: postgresql-build.tgz
- - name: Test PostgreSQL Driver - postgres 14
- env:
- BUILD_ALL: "0"
- BUILD_DRIVER_POSTGRESQL: "1"
- PYTEST_ADDOPTS: "--error-for-skips"
+ postgresql-test:
+ name: "PostgreSQL (${{ matrix.name }})"
+ needs: postgresql-build
+ runs-on: ubuntu-latest
+ continue-on-error: ${{ matrix.experimental }}
+ strategy:
+ fail-fast: false
+ max-parallel: 2
+ matrix:
+ include:
+ - name: PostgreSQL 14
+ service: postgres-test
+ postgres-version: "14"
+ vendor: postgresql
+ uri: postgresql://localhost:5432/postgres?user=postgres&password=password
+ integration: true
+ validation: false
+ experimental: false
+ - name: PostgreSQL 15
+ service: postgres-test
+ postgres-version: "15"
+ vendor: postgresql
+ uri: postgresql://localhost:5432/postgres?user=postgres&password=password
+ integration: true
+ validation: false
+ experimental: false
+ - name: PostgreSQL 16
+ service: postgres-test
+ postgres-version: "16"
+ vendor: postgresql
+ uri: postgresql://localhost:5432/postgres?user=postgres&password=password
+ integration: true
+ validation: false
+ experimental: false
+ - name: PostgreSQL 17
+ service: postgres-test
+ postgres-version: "17"
+ vendor: postgresql
+ uri: postgresql://localhost:5432/postgres?user=postgres&password=password
+ integration: true
+ validation: false
+ experimental: false
+ - name: PostgreSQL 18
+ service: postgres-test
+ postgres-version: "18"
+ vendor: postgresql
+ uri: postgresql://localhost:5432/postgres?user=postgres&password=password
+ integration: true
+ validation: true
+ experimental: false
+ - name: CedarDB
+ service: cedardb-test
+ vendor: cedardb
+ uri: postgresql://localhost:5433/postgres?user=postgres&password=CedarDB2026%21
+ integration: false
+ validation: true
+ experimental: true
+ - name: Citus
+ service: citus-test
+ vendor: citus
+ uri: postgresql://localhost:5434/postgres?user=postgres&password=password
+ integration: false
+ validation: true
+ experimental: false
+ - name: CockroachDB
+ service: cockroachdb-test
+ vendor: cockroachdb
+ uri: postgresql://root@localhost:5435/postgres?sslmode=disable
+ integration: false
+ validation: true
+ experimental: false
+ - name: CrateDB
+ service: cratedb-test
+ vendor: cratedb
+ uri: postgresql://crate@localhost:5436/doc?sslmode=disable
+ integration: false
+ validation: true
+ experimental: true
+ - name: ParadeDB
+ service: paradedb-test
+ vendor: paradedb
+ uri: postgresql://localhost:5437/postgres?user=postgres&password=password
+ integration: false
+ validation: true
+ experimental: false
+ - name: TimescaleDB
+ service: timescaledb-test
+ vendor: timescaledb
+ uri: postgresql://localhost:5438/postgres?user=postgres&password=password
+ integration: false
+ validation: true
+ experimental: false
+ - name: YugabyteDB
+ service: yugabytedb-test
+ vendor: yugabytedb
+ uri: postgresql://localhost:5439/yugabyte?user=yugabyte&password=yugabyte
+ integration: false
+ validation: true
+ experimental: false
+ - name: AlloyDB Omni
+ service: alloydb-omni-test
+ vendor: alloydb-omni
+ uri: postgresql://localhost:5440/postgres?user=postgres&password=password
+ integration: false
+ validation: true
+ experimental: false
+ steps:
+ - name: Free up disk space
run: |
- env POSTGRES_VERSION=14 docker compose up --wait --detach postgres-test
- ./ci/scripts/cpp_test.sh "$(pwd)/build"
- ./ci/scripts/python_test.sh "$(pwd)" "$(pwd)/build"
- docker compose down
- docker compose rm -fsv
- - name: Test PostgreSQL Driver - postgres 15
- env:
- BUILD_ALL: "0"
- BUILD_DRIVER_POSTGRESQL: "1"
- PYTEST_ADDOPTS: "--error-for-skips"
+ # Preinstalled tools use a lot of disk space, free up some space
+ # https://github.com/actions/runner-images/issues/2840
+ sudo rm -rf "$AGENT_TOOLSDIRECTORY"
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+ with:
+ fetch-depth: 0
+ persist-credentials: false
+ - name: Get Date
+ id: get-date
run: |
- env POSTGRES_VERSION=15 docker compose up --wait --detach postgres-test
- ./ci/scripts/cpp_test.sh "$(pwd)/build"
- ./ci/scripts/python_test.sh "$(pwd)" "$(pwd)/build"
- docker compose down
- docker compose rm -fsv
- - name: Test PostgreSQL Driver - postgres 16
+ echo "today=$(/bin/date -u '+%Y%m%d')" >> $GITHUB_OUTPUT
+ - name: Cache Conda
+ uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
+ with:
+ path: ~/conda_pkgs_dir
+ key: conda-${{ runner.os }}-${{ steps.get-date.outputs.today }}-${{ env.CACHE_NUMBER }}-${{ hashFiles('ci/**') }}
+ - uses: conda-incubator/setup-miniconda@8ee1f361103df19b6f8c8655fd3967a8ecb162d5 # v4.0.1
+ with:
+ miniforge-version: latest
+ use-only-tar-bz2: false
+ use-mamba: true
+ - name: Install Dependencies
+ run: |
+ ./ci/scripts/remamba.sh install -c conda-forge \
+ --file ci/conda_env_cpp.txt \
+ --file ci/conda_env_python.txt
+ pip install pytest-error-for-skips
+ - name: Work around ASAN issue (GH-1617)
+ run: |
+ sudo sysctl vm.mmap_rnd_bits=28
+ - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: postgresql-build
+ - name: Extract PostgreSQL build
+ run: |
+ tar --extract --gzip --file postgresql-build.tgz
+ echo "PYTHONPATH=$(pwd)/python/adbc_driver_manager:$(pwd)/python/adbc_driver_postgresql" >> "$GITHUB_ENV"
+ - name: Start ${{ matrix.name }}
env:
- BUILD_ALL: "0"
- BUILD_DRIVER_POSTGRESQL: "1"
- PYTEST_ADDOPTS: "--error-for-skips"
+ POSTGRES_VERSION: ${{ matrix.postgres-version }}
run: |
- env POSTGRES_VERSION=16 docker compose up --wait --detach postgres-test
- ./ci/scripts/cpp_test.sh "$(pwd)/build"
- ./ci/scripts/python_test.sh "$(pwd)" "$(pwd)/build"
- docker compose down
- docker compose rm -fsv
- - name: Test PostgreSQL Driver - postgres 17
+ docker compose up --wait --detach "${{ matrix.service }}"
+ - name: Run PostgreSQL integration tests
+ if: matrix.integration
env:
+ ADBC_POSTGRESQL_TEST_URI: ${{ matrix.uri }}
+ ADBC_USE_ASAN: "ON"
+ ADBC_USE_UBSAN: "ON"
BUILD_ALL: "0"
BUILD_DRIVER_POSTGRESQL: "1"
PYTEST_ADDOPTS: "--error-for-skips"
run: |
- env POSTGRES_VERSION=17 docker compose up --wait --detach postgres-test
./ci/scripts/cpp_test.sh "$(pwd)/build"
./ci/scripts/python_test.sh "$(pwd)" "$(pwd)/build"
- docker compose down
- docker compose rm -fsv
- - name: Test PostgreSQL Driver - postgres 18
+ - name: Run validation suite
+ if: matrix.validation
env:
+ ADBC_POSTGRESQL_TEST_URI: ${{ matrix.uri }}
+ ADBC_USE_ASAN: "ON"
+ ADBC_USE_UBSAN: "ON"
BUILD_ALL: "0"
BUILD_DRIVER_POSTGRESQL: "1"
- PYTEST_ADDOPTS: "--error-for-skips"
run: |
- env POSTGRES_VERSION=18 docker compose up --wait --detach postgres-test
- ./ci/scripts/cpp_test.sh "$(pwd)/build"
- ./ci/scripts/python_test.sh "$(pwd)" "$(pwd)/build"
- docker compose down
- docker compose rm -fsv
- - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
- - name: Run PostgreSQL Validation Suite
+ uv --project=./c/driver/postgresql/validation/ run \
+ ci/scripts/validate.sh "$(pwd)" --vendor "${{ matrix.vendor }}"
+ - name: Capture ${{ matrix.name }} logs
+ if: failure()
run: |
- env POSTGRES_VERSION=18 docker compose up --wait --detach postgres-test
- env BUILD_ALL=0 BUILD_DRIVER_POSTGRESQL=1 uv --project=./c/driver/postgresql/validation/ run ci/scripts/validate.sh $(pwd)
- docker compose down
+ docker compose logs "${{ matrix.service }}"
+ - name: Stop ${{ matrix.name }}
+ if: always()
+ run: |
+ docker compose stop "${{ matrix.service }}"
+ docker compose rm --force --stop --volumes "${{ matrix.service }}"
flightsql_interop:
name: "FlightSQL C# Interop"
diff --git a/c/driver/postgresql/validation/queries-cockroachdb/type/bind/int32.txtcase b/c/driver/postgresql/validation/queries-cockroachdb/type/bind/int32.txtcase
new file mode 100644
index 0000000000..6087a83094
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cockroachdb/type/bind/int32.txtcase
@@ -0,0 +1,29 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: expected_schema
+
+{
+ "format": "+s",
+ "children": [
+ {
+ "name": "res",
+ "format": "l",
+ "flags": ["nullable"]
+ }
+ ]
+}
diff --git a/c/driver/postgresql/validation/queries-cockroachdb/type/bind/timestamp_ns.txtcase b/c/driver/postgresql/validation/queries-cockroachdb/type/bind/timestamp_ns.txtcase
new file mode 100644
index 0000000000..59e4544762
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cockroachdb/type/bind/timestamp_ns.txtcase
@@ -0,0 +1,44 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: setup_query
+
+CREATE TABLE test_timestamp (
+ idx INT,
+ res TIMESTAMP(6)
+);
+
+// part: expected_schema
+
+{
+ "format": "+s",
+ "children": [
+ {
+ "name": "res",
+ "format": "tsu:",
+ "flags": ["nullable"]
+ }
+ ]
+}
+
+// part: expected
+
+{"res": null}
+{"res": -9223372036854775}
+{"res": 946684800000000}
+{"res": 1684158330000000}
+{"res": 9223372036854775}
diff --git a/c/driver/postgresql/validation/queries-cockroachdb/type/bind/timestamptz_ns.txtcase b/c/driver/postgresql/validation/queries-cockroachdb/type/bind/timestamptz_ns.txtcase
new file mode 100644
index 0000000000..bd1634b808
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cockroachdb/type/bind/timestamptz_ns.txtcase
@@ -0,0 +1,50 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: setup_query
+
+CREATE TABLE test_timestamptz (
+ idx INT,
+ res TIMESTAMP(6) WITH TIME ZONE,
+ res2 TIMESTAMP(6) WITH TIME ZONE
+);
+
+// part: expected_schema
+
+{
+ "format": "+s",
+ "children": [
+ {
+ "name": "res",
+ "format": "tsu:UTC",
+ "flags": ["nullable"]
+ },
+ {
+ "name": "res2",
+ "format": "tsu:UTC",
+ "flags": ["nullable"]
+ }
+ ]
+}
+
+// part: expected
+
+{"res": null, "res2": null}
+{"res": -9223372036854775, "res2": -9223372036854775}
+{"res": 946684800000000, "res2": 946684800000000}
+{"res": 1684158330000000, "res2": 1684158330000000}
+{"res": 9223372036854775, "res2": 9223372036854775}
diff --git a/c/driver/postgresql/validation/queries-cockroachdb/type/literal/int32.txtcase b/c/driver/postgresql/validation/queries-cockroachdb/type/literal/int32.txtcase
new file mode 100644
index 0000000000..6087a83094
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cockroachdb/type/literal/int32.txtcase
@@ -0,0 +1,29 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: expected_schema
+
+{
+ "format": "+s",
+ "children": [
+ {
+ "name": "res",
+ "format": "l",
+ "flags": ["nullable"]
+ }
+ ]
+}
diff --git a/c/driver/postgresql/validation/queries-cockroachdb/type/select/int32.txtcase b/c/driver/postgresql/validation/queries-cockroachdb/type/select/int32.txtcase
new file mode 100644
index 0000000000..6087a83094
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cockroachdb/type/select/int32.txtcase
@@ -0,0 +1,29 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: expected_schema
+
+{
+ "format": "+s",
+ "children": [
+ {
+ "name": "res",
+ "format": "l",
+ "flags": ["nullable"]
+ }
+ ]
+}
diff --git a/c/driver/postgresql/validation/tests/conftest.py b/c/driver/postgresql/validation/tests/conftest.py
index 465b2eaca4..b7cc21df7b 100644
--- a/c/driver/postgresql/validation/tests/conftest.py
+++ b/c/driver/postgresql/validation/tests/conftest.py
@@ -19,6 +19,7 @@
from pathlib import Path
import adbc_drivers_validation.model
+import adbc_drivers_validation.tests.conftest
import pytest
from adbc_drivers_validation.tests.conftest import ( # noqa: F401
conn,
@@ -26,18 +27,26 @@
db_kwargs,
manual_test,
noci,
- pytest_addoption,
pytest_collection_modifyitems,
)
-from .postgresql import PostgreSQLQuirks
+from .postgresql import VENDORS, get_quirks
+
+
+def pytest_addoption(parser) -> None:
+ adbc_drivers_validation.tests.conftest.pytest_addoption(parser)
+ parser.addoption(
+ "--vendor",
+ choices=VENDORS,
+ default="postgresql",
+ help="PostgreSQL-compatible database vendor to validate",
+ )
@pytest.fixture(scope="session")
def driver(request) -> adbc_drivers_validation.model.DriverQuirks:
- driver = request.param
- assert driver.startswith("postgresql:")
- return PostgreSQLQuirks()
+ assert request.param.startswith("postgresql:")
+ return get_quirks(request.config.getoption("vendor"))
@pytest.fixture(scope="session")
diff --git a/c/driver/postgresql/validation/tests/postgresql.py b/c/driver/postgresql/validation/tests/postgresql.py
index 1ebd21ef84..554764e5d0 100644
--- a/c/driver/postgresql/validation/tests/postgresql.py
+++ b/c/driver/postgresql/validation/tests/postgresql.py
@@ -92,4 +92,107 @@ def split_statement(self, statement: str) -> list[str]:
return quirks.split_statement(statement)
-QUIRKS = [PostgreSQLQuirks()]
+class CedarDBQuirks(PostgreSQLQuirks):
+ vendor_version = re.compile(r"16[0-9]{4}")
+ short_version = "16"
+ setup = model.DriverSetup(
+ database={
+ "uri": model.FromEnv("ADBC_POSTGRESQL_TEST_URI"),
+ },
+ connection={},
+ statement={"adbc.postgresql.use_copy": "false"},
+ )
+
+
+class CitusQuirks(PostgreSQLQuirks):
+ vendor_name = "PostgreSQL"
+ vendor_version = re.compile(r"17[0-9]{4}")
+ short_version = "17"
+
+
+class CockroachDBQuirks(PostgreSQLQuirks):
+ vendor_version = re.compile(r"13[0-9]{4}")
+ short_version = "13"
+ features = PostgreSQLQuirks.features.model_copy(
+ update={"connection_get_table_schema": False}
+ )
+ setup = model.DriverSetup(
+ database={
+ "uri": model.FromEnv("ADBC_POSTGRESQL_TEST_URI"),
+ },
+ connection={},
+ statement={"adbc.postgresql.use_copy": "false"},
+ )
+
+ @property
+ def queries_paths(self) -> tuple[Path]:
+ return (
+ *super().queries_paths,
+ Path(__file__).parent.parent / "queries-cockroachdb",
+ )
+
+
+class CrateDBQuirks(PostgreSQLQuirks):
+ vendor_version = re.compile(r"14[0-9]{4}")
+ short_version = "14"
+ features = PostgreSQLQuirks.features.with_values(
+ connection_get_table_schema=False,
+ current_catalog="crate",
+ current_schema="doc",
+ )
+ setup = model.DriverSetup(
+ database={
+ "uri": model.FromEnv("ADBC_POSTGRESQL_TEST_URI"),
+ },
+ connection={},
+ statement={"adbc.postgresql.use_copy": "false"},
+ )
+
+
+class ParadeDBQuirks(PostgreSQLQuirks):
+ pass
+
+
+class TimescaleDBQuirks(PostgreSQLQuirks):
+ pass
+
+
+class YugabyteDBQuirks(PostgreSQLQuirks):
+ vendor_version = re.compile(r"15[0-9]{4}")
+ short_version = "15"
+ features = PostgreSQLQuirks.features.with_values(current_catalog="yugabyte")
+
+
+class AlloyDBOmniQuirks(PostgreSQLQuirks):
+ vendor_version = re.compile(r"17[0-9]{4}")
+ short_version = "17"
+
+
+VENDORS = (
+ "postgresql",
+ "alloydb-omni",
+ "cedardb",
+ "citus",
+ "cockroachdb",
+ "cratedb",
+ "paradedb",
+ "timescaledb",
+ "yugabytedb",
+)
+
+_QUIRKS = {
+ "postgresql": PostgreSQLQuirks,
+ "alloydb-omni": AlloyDBOmniQuirks,
+ "cedardb": CedarDBQuirks,
+ "citus": CitusQuirks,
+ "cockroachdb": CockroachDBQuirks,
+ "cratedb": CrateDBQuirks,
+ "paradedb": ParadeDBQuirks,
+ "timescaledb": TimescaleDBQuirks,
+ "yugabytedb": YugabyteDBQuirks,
+}
+
+
+def get_quirks(vendor: str) -> PostgreSQLQuirks:
+ """Get the PostgreSQL-compatible quirks for one vendor."""
+ return _QUIRKS[vendor]()
diff --git a/c/driver/postgresql/validation/tests/test_connection.py b/c/driver/postgresql/validation/tests/test_connection.py
index 89b1c15f62..aa42b8c4c9 100644
--- a/c/driver/postgresql/validation/tests/test_connection.py
+++ b/c/driver/postgresql/validation/tests/test_connection.py
@@ -15,13 +15,44 @@
# specific language governing permissions and limitations
# under the License.
-from adbc_drivers_validation.tests.connection import (
- TestConnection, # noqa: F401
- generate_tests,
-)
+import adbc_drivers_validation.tests.connection as test_connection
+import pytest
from . import postgresql
+class TestConnection(test_connection.TestConnection):
+ def test_get_objects_column_filter_table(
+ self, conn, driver, get_objects_table
+ ) -> None:
+ if isinstance(driver, postgresql.CockroachDBQuirks):
+ pytest.xfail(
+ "CockroachDB has an implicit rowid column and does not preserve "
+ "column order in GetObjects"
+ )
+ super().test_get_objects_column_filter_table(conn, driver, get_objects_table)
+
+ def test_get_objects_column_filter_table_name(
+ self, conn, driver, get_objects_table
+ ) -> None:
+ if isinstance(driver, postgresql.CockroachDBQuirks):
+ pytest.xfail(
+ "CockroachDB has an implicit rowid column and does not preserve "
+ "column order in GetObjects"
+ )
+ super().test_get_objects_column_filter_table_name(
+ conn, driver, get_objects_table
+ )
+
+ def test_get_objects_column_xdbc(self, conn, driver, get_objects_table) -> None:
+ if isinstance(driver, postgresql.CockroachDBQuirks):
+ pytest.xfail(
+ "CockroachDB has an implicit rowid column and does not preserve "
+ "column order in GetObjects"
+ )
+ super().test_get_objects_column_xdbc(conn, driver, get_objects_table)
+
+
def pytest_generate_tests(metafunc) -> None:
- return generate_tests(postgresql.QUIRKS, metafunc)
+ vendor = metafunc.config.getoption("vendor")
+ return test_connection.generate_tests([postgresql.get_quirks(vendor)], metafunc)
diff --git a/c/driver/postgresql/validation/tests/test_ingest.py b/c/driver/postgresql/validation/tests/test_ingest.py
index 9fded6f375..9a799db41c 100644
--- a/c/driver/postgresql/validation/tests/test_ingest.py
+++ b/c/driver/postgresql/validation/tests/test_ingest.py
@@ -24,4 +24,5 @@
def pytest_generate_tests(metafunc) -> None:
- return generate_tests(postgresql.QUIRKS, metafunc)
+ vendor = metafunc.config.getoption("vendor")
+ return generate_tests([postgresql.get_quirks(vendor)], metafunc)
diff --git a/c/driver/postgresql/validation/tests/test_query.py b/c/driver/postgresql/validation/tests/test_query.py
index a2f396497c..196762ba2d 100644
--- a/c/driver/postgresql/validation/tests/test_query.py
+++ b/c/driver/postgresql/validation/tests/test_query.py
@@ -24,4 +24,5 @@
def pytest_generate_tests(metafunc) -> None:
- return generate_tests(postgresql.QUIRKS, metafunc)
+ vendor = metafunc.config.getoption("vendor")
+ return generate_tests([postgresql.get_quirks(vendor)], metafunc)
diff --git a/c/driver/postgresql/validation/tests/test_statement.py b/c/driver/postgresql/validation/tests/test_statement.py
index ee33cd087b..7412df768e 100644
--- a/c/driver/postgresql/validation/tests/test_statement.py
+++ b/c/driver/postgresql/validation/tests/test_statement.py
@@ -24,4 +24,5 @@
def pytest_generate_tests(metafunc) -> None:
- return generate_tests(postgresql.QUIRKS, metafunc)
+ vendor = metafunc.config.getoption("vendor")
+ return generate_tests([postgresql.get_quirks(vendor)], metafunc)
diff --git a/ci/scripts/validate.sh b/ci/scripts/validate.sh
index 66ac0db47c..60ea4dd1b8 100755
--- a/ci/scripts/validate.sh
+++ b/ci/scripts/validate.sh
@@ -30,6 +30,7 @@ set -euo pipefail
test_project() {
local -r subdir="${1}"
local -r run=$(echo "${2}" | tr '[:upper:]' '[:lower:]')
+ shift 2
case "${run}" in
1|on)
@@ -59,15 +60,16 @@ test_project() {
fi
pushd "${subdir}"
- echo env ${options[@]} pytest -vvs --junit-xml=validation-report.xml -rfEsxX tests/
- env ${options[@]} pytest -vvs --junit-xml=validation-report.xml -rfEsxX tests/
+ echo env ${options[@]} pytest -vvs --junit-xml=validation-report.xml -rfEsxX tests/ "$@"
+ env ${options[@]} pytest -vvs --junit-xml=validation-report.xml -rfEsxX tests/ "$@"
popd
}
main() {
local -r source_dir="${1}"
+ shift
- test_project "${source_dir}/c/driver/postgresql/validation" "${BUILD_DRIVER_POSTGRESQL}"
+ test_project "${source_dir}/c/driver/postgresql/validation" "${BUILD_DRIVER_POSTGRESQL}" "$@"
}
main "$@"
diff --git a/compose.yaml b/compose.yaml
index ffacd6b779..66484bf7ab 100644
--- a/compose.yaml
+++ b/compose.yaml
@@ -355,6 +355,129 @@ services:
ports:
- "5432:5432"
+ cedardb-test:
+ container_name: adbc_cedardb_test
+ image: cedardb/cedardb:v2026-08-13
+ environment:
+ CEDAR_PASSWORD: CedarDB2026!
+ healthcheck:
+ test: ["CMD-SHELL", "PGPASSWORD='CedarDB2026!' pg_isready -U postgres -d postgres"]
+ interval: 10s
+ timeout: 5s
+ retries: 10
+ start_period: 10s
+ ports:
+ - "5433:5432"
+
+ citus-test:
+ container_name: adbc_citus_test
+ image: citusdata/citus:14.1.0-pg17
+ environment:
+ POSTGRES_USER: postgres
+ POSTGRES_PASSWORD: password
+ POSTGRES_DB: postgres
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
+ interval: 10s
+ timeout: 5s
+ retries: 10
+ ports:
+ - "5434:5432"
+
+ cockroachdb-test:
+ container_name: adbc_cockroachdb_test
+ image: cockroachdb/cockroach:v26.2.5
+ command: start-single-node --insecure
+ healthcheck:
+ test: ["CMD", "cockroach", "sql", "--insecure", "--host=localhost:26257", "--execute=SELECT 1"]
+ interval: 10s
+ timeout: 5s
+ retries: 10
+ start_period: 10s
+ ports:
+ - "5435:26257"
+
+ cratedb-test:
+ container_name: adbc_cratedb_test
+ image: crate:6.4.2
+ command:
+ - -Cdiscovery.type=single-node
+ - -Cgateway.expected_data_nodes=1
+ - -Cgateway.recover_after_data_nodes=1
+ environment:
+ CRATE_HEAP_SIZE: 1g
+ healthcheck:
+ test: ["CMD-SHELL", "curl --fail --silent --show-error --header 'Content-Type: application/json' --data '{\"stmt\":\"SELECT 1\"}' http://localhost:4200/_sql > /dev/null"]
+ interval: 10s
+ timeout: 5s
+ retries: 20
+ start_period: 20s
+ ports:
+ - "5436:5432"
+
+ paradedb-test:
+ container_name: adbc_paradedb_test
+ image: paradedb/paradedb:0.25.3-pg18
+ environment:
+ POSTGRES_USER: postgres
+ POSTGRES_PASSWORD: password
+ POSTGRES_DB: postgres
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
+ interval: 10s
+ timeout: 5s
+ retries: 10
+ ports:
+ - "5437:5432"
+
+ timescaledb-test:
+ container_name: adbc_timescaledb_test
+ image: timescale/timescaledb-ha:pg18.4-ts2.29.1-all-oss
+ environment:
+ POSTGRES_USER: postgres
+ POSTGRES_PASSWORD: password
+ POSTGRES_DB: postgres
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
+ interval: 10s
+ timeout: 5s
+ retries: 10
+ ports:
+ - "5438:5432"
+
+ yugabytedb-test:
+ container_name: adbc_yugabytedb_test
+ hostname: adbc-yugabytedb-test
+ image: yugabytedb/yugabyte:2026.1.1.0-b91
+ command: >-
+ bin/yugabyted start --background=false
+ --master_flags=reject_writes_when_disk_full=false
+ --tserver_flags=reject_writes_when_disk_full=false
+ healthcheck:
+ test: ["CMD-SHELL", "/home/yugabyte/bin/ysqlsh --host adbc-yugabytedb-test --username yugabyte --dbname yugabyte --command 'SELECT 1' > /dev/null"]
+ interval: 10s
+ timeout: 5s
+ retries: 20
+ start_period: 30s
+ ports:
+ - "5439:5433"
+
+ alloydb-omni-test:
+ container_name: adbc_alloydb_omni_test
+ image: google/alloydbomni:17.9.0
+ environment:
+ POSTGRES_USER: postgres
+ POSTGRES_PASSWORD: password
+ POSTGRES_DB: postgres
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
+ interval: 10s
+ timeout: 5s
+ retries: 10
+ start_period: 10s
+ ports:
+ - "5440:5432"
+
spiceai-test:
container_name: adbc-spiceai
build:
From bbadc4fb3bff57aa34810ba71a84df399cff1520 Mon Sep 17 00:00:00 2001
From: David Li
Date: Tue, 18 Aug 2026 15:27:23 +0900
Subject: [PATCH 2/9] refactor
---
.github/workflows/integration.yml | 173 +++++++++++++++---------------
1 file changed, 88 insertions(+), 85 deletions(-)
diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
index 3abc340e6a..c129438d99 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -233,6 +233,78 @@ jobs:
path: postgresql-build.tgz
postgresql-test:
+ name: "PostgreSQL (14-18)"
+ needs: postgresql-build
+ runs-on: ubuntu-latest
+ steps:
+ - name: Free up disk space
+ run: |
+ # Preinstalled tools use a lot of disk space, free up some space
+ # https://github.com/actions/runner-images/issues/2840
+ sudo rm -rf "$AGENT_TOOLSDIRECTORY"
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+ with:
+ fetch-depth: 0
+ persist-credentials: false
+ - name: Get Date
+ id: get-date
+ run: |
+ echo "today=$(/bin/date -u '+%Y%m%d')" >> $GITHUB_OUTPUT
+ - name: Cache Conda
+ uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
+ with:
+ path: ~/conda_pkgs_dir
+ key: conda-${{ runner.os }}-${{ steps.get-date.outputs.today }}-${{ env.CACHE_NUMBER }}-${{ hashFiles('ci/**') }}
+ - uses: conda-incubator/setup-miniconda@8ee1f361103df19b6f8c8655fd3967a8ecb162d5 # v4.0.1
+ with:
+ miniforge-version: latest
+ use-only-tar-bz2: false
+ use-mamba: true
+ - name: Install Dependencies
+ run: |
+ ./ci/scripts/remamba.sh install -c conda-forge \
+ --file ci/conda_env_cpp.txt \
+ --file ci/conda_env_python.txt
+ pip install pytest-error-for-skips
+ - name: Work around ASAN issue (GH-1617)
+ run: |
+ sudo sysctl vm.mmap_rnd_bits=28
+ - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: postgresql-build
+ - name: Extract PostgreSQL build
+ run: |
+ tar --extract --gzip --file postgresql-build.tgz
+ echo "PYTHONPATH=$(pwd)/python/adbc_driver_manager:$(pwd)/python/adbc_driver_postgresql" >> "$GITHUB_ENV"
+ - name: Run PostgreSQL 14-18 tests
+ env:
+ ADBC_POSTGRESQL_TEST_URI: postgresql://localhost:5432/postgres?user=postgres&password=password
+ ADBC_USE_ASAN: "ON"
+ ADBC_USE_UBSAN: "ON"
+ BUILD_ALL: "0"
+ BUILD_DRIVER_POSTGRESQL: "1"
+ PYTEST_ADDOPTS: "--error-for-skips"
+ run: |
+ for postgres_version in 14 15 16 17 18; do
+ echo "::group::PostgreSQL $postgres_version"
+ export POSTGRES_VERSION="$postgres_version"
+ docker compose up --wait --detach postgres-test
+ ./ci/scripts/cpp_test.sh "$(pwd)/build"
+ ./ci/scripts/python_test.sh "$(pwd)" "$(pwd)/build"
+ if [ "$postgres_version" = "18" ]; then
+ uv --project=./c/driver/postgresql/validation/ run \
+ ci/scripts/validate.sh "$(pwd)" --vendor postgresql
+ fi
+ docker compose stop postgres-test
+ docker compose rm --force --stop --volumes postgres-test
+ echo "::endgroup::"
+ done
+ - name: Capture PostgreSQL logs
+ if: failure()
+ run: |
+ docker compose logs postgres-test
+ postgresql-vendor-test:
name: "PostgreSQL (${{ matrix.name }})"
needs: postgresql-build
runs-on: ubuntu-latest
@@ -242,102 +314,48 @@ jobs:
max-parallel: 2
matrix:
include:
- - name: PostgreSQL 14
- service: postgres-test
- postgres-version: "14"
- vendor: postgresql
- uri: postgresql://localhost:5432/postgres?user=postgres&password=password
- integration: true
- validation: false
- experimental: false
- - name: PostgreSQL 15
- service: postgres-test
- postgres-version: "15"
- vendor: postgresql
- uri: postgresql://localhost:5432/postgres?user=postgres&password=password
- integration: true
- validation: false
- experimental: false
- - name: PostgreSQL 16
- service: postgres-test
- postgres-version: "16"
- vendor: postgresql
- uri: postgresql://localhost:5432/postgres?user=postgres&password=password
- integration: true
- validation: false
- experimental: false
- - name: PostgreSQL 17
- service: postgres-test
- postgres-version: "17"
- vendor: postgresql
- uri: postgresql://localhost:5432/postgres?user=postgres&password=password
- integration: true
- validation: false
- experimental: false
- - name: PostgreSQL 18
- service: postgres-test
- postgres-version: "18"
- vendor: postgresql
- uri: postgresql://localhost:5432/postgres?user=postgres&password=password
- integration: true
- validation: true
+ - name: AlloyDB Omni
+ service: alloydb-omni-test
+ vendor: alloydb-omni
+ uri: postgresql://localhost:5440/postgres?user=postgres&password=password
experimental: false
- - name: CedarDB
- service: cedardb-test
- vendor: cedardb
- uri: postgresql://localhost:5433/postgres?user=postgres&password=CedarDB2026%21
- integration: false
- validation: true
- experimental: true
- name: Citus
service: citus-test
vendor: citus
uri: postgresql://localhost:5434/postgres?user=postgres&password=password
- integration: false
- validation: true
experimental: false
- name: CockroachDB
service: cockroachdb-test
vendor: cockroachdb
uri: postgresql://root@localhost:5435/postgres?sslmode=disable
- integration: false
- validation: true
experimental: false
- - name: CrateDB
- service: cratedb-test
- vendor: cratedb
- uri: postgresql://crate@localhost:5436/doc?sslmode=disable
- integration: false
- validation: true
- experimental: true
- name: ParadeDB
service: paradedb-test
vendor: paradedb
uri: postgresql://localhost:5437/postgres?user=postgres&password=password
- integration: false
- validation: true
experimental: false
- name: TimescaleDB
service: timescaledb-test
vendor: timescaledb
uri: postgresql://localhost:5438/postgres?user=postgres&password=password
- integration: false
- validation: true
experimental: false
- name: YugabyteDB
service: yugabytedb-test
vendor: yugabytedb
uri: postgresql://localhost:5439/yugabyte?user=yugabyte&password=yugabyte
- integration: false
- validation: true
- experimental: false
- - name: AlloyDB Omni
- service: alloydb-omni-test
- vendor: alloydb-omni
- uri: postgresql://localhost:5440/postgres?user=postgres&password=password
- integration: false
- validation: true
experimental: false
+ # These two currently fail, but could be supported in the future.
+ # https://github.com/apache/arrow-adbc/issues/1755
+ # - name: CedarDB
+ # service: cedardb-test
+ # vendor: cedardb
+ # uri: postgresql://localhost:5433/postgres?user=postgres&password=CedarDB2026%21
+ # experimental: true
+ # - name: CrateDB
+ # service: cratedb-test
+ # vendor: cratedb
+ # uri: postgresql://crate@localhost:5436/doc?sslmode=disable
+ # experimental: true
steps:
- name: Free up disk space
run: |
@@ -380,24 +398,9 @@ jobs:
tar --extract --gzip --file postgresql-build.tgz
echo "PYTHONPATH=$(pwd)/python/adbc_driver_manager:$(pwd)/python/adbc_driver_postgresql" >> "$GITHUB_ENV"
- name: Start ${{ matrix.name }}
- env:
- POSTGRES_VERSION: ${{ matrix.postgres-version }}
run: |
docker compose up --wait --detach "${{ matrix.service }}"
- - name: Run PostgreSQL integration tests
- if: matrix.integration
- env:
- ADBC_POSTGRESQL_TEST_URI: ${{ matrix.uri }}
- ADBC_USE_ASAN: "ON"
- ADBC_USE_UBSAN: "ON"
- BUILD_ALL: "0"
- BUILD_DRIVER_POSTGRESQL: "1"
- PYTEST_ADDOPTS: "--error-for-skips"
- run: |
- ./ci/scripts/cpp_test.sh "$(pwd)/build"
- ./ci/scripts/python_test.sh "$(pwd)" "$(pwd)/build"
- name: Run validation suite
- if: matrix.validation
env:
ADBC_POSTGRESQL_TEST_URI: ${{ matrix.uri }}
ADBC_USE_ASAN: "ON"
From 028ea4b684e6c29570ab4d10306aaeb735e71b4b Mon Sep 17 00:00:00 2001
From: David Li
Date: Tue, 18 Aug 2026 16:19:25 +0900
Subject: [PATCH 3/9] Get CrateDB sort of working
---
.github/workflows/integration.yml | 14 +++---
c/driver/postgresql/validation/pyproject.toml | 2 +-
.../queries-cratedb/type/bind/binary.txtcase | 22 +++++++++
.../type/bind/binary_view.txtcase | 22 +++++++++
.../queries-cratedb/type/bind/date.txtcase | 20 ++++++++
.../type/bind/fixed_size_binary.txtcase | 22 +++++++++
.../queries-cratedb/type/bind/int64.txtcase | 34 +++++++++++++
.../type/bind/large_binary.txtcase | 22 +++++++++
.../queries-cratedb/type/bind/time_ms.txtcase | 22 +++++++++
.../queries-cratedb/type/bind/time_ns.txtcase | 22 +++++++++
.../queries-cratedb/type/bind/time_s.txtcase | 22 +++++++++
.../queries-cratedb/type/bind/time_us.txtcase | 22 +++++++++
.../type/bind/timestamp_ms.txtcase | 28 +++++++++++
.../type/bind/timestamp_ns.txtcase | 36 ++++++++++++++
.../type/bind/timestamp_s.txtcase | 28 +++++++++++
.../type/bind/timestamp_us.txtcase | 36 ++++++++++++++
.../type/bind/timestamptz_ms.txtcase | 29 +++++++++++
.../type/bind/timestamptz_ns.txtcase | 37 ++++++++++++++
.../type/bind/timestamptz_s.txtcase | 29 +++++++++++
.../type/bind/timestamptz_us.txtcase | 37 ++++++++++++++
.../queries-cratedb/type/bind/uuid.txtcase | 20 ++++++++
.../type/literal/binary.txtcase | 22 +++++++++
.../queries-cratedb/type/literal/time.txtcase | 22 +++++++++
.../queries-cratedb/type/literal/uuid.txtcase | 33 +++++++++++++
.../type/select/binary.txtcase | 22 +++++++++
.../queries-cratedb/type/select/date.txtcase | 20 ++++++++
.../queries-cratedb/type/select/int64.txtcase | 37 ++++++++++++++
.../queries-cratedb/type/select/json.txtcase | 20 ++++++++
.../queries-cratedb/type/select/jsonb.txtcase | 22 +++++++++
.../queries-cratedb/type/select/time.txtcase | 22 +++++++++
.../queries-cratedb/type/select/uuid.txtcase | 33 +++++++++++++
.../postgresql/validation/tests/postgresql.py | 27 +++++++++++
c/driver/postgresql/validation/uv.lock | 48 +++++++++----------
33 files changed, 822 insertions(+), 32 deletions(-)
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/bind/binary.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/bind/binary_view.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/bind/date.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/bind/fixed_size_binary.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/bind/int64.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/bind/large_binary.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/bind/time_ms.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/bind/time_ns.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/bind/time_s.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/bind/time_us.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/bind/timestamp_ms.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/bind/timestamp_ns.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/bind/timestamp_s.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/bind/timestamp_us.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_ms.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_ns.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_s.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_us.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/bind/uuid.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/literal/binary.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/literal/time.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/literal/uuid.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/select/binary.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/select/date.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/select/int64.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/select/json.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/select/jsonb.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/select/time.txtcase
create mode 100644 c/driver/postgresql/validation/queries-cratedb/type/select/uuid.txtcase
diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
index c129438d99..ec5335f5a6 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -284,14 +284,14 @@ jobs:
ADBC_USE_UBSAN: "ON"
BUILD_ALL: "0"
BUILD_DRIVER_POSTGRESQL: "1"
- PYTEST_ADDOPTS: "--error-for-skips"
run: |
for postgres_version in 14 15 16 17 18; do
echo "::group::PostgreSQL $postgres_version"
export POSTGRES_VERSION="$postgres_version"
docker compose up --wait --detach postgres-test
./ci/scripts/cpp_test.sh "$(pwd)/build"
- ./ci/scripts/python_test.sh "$(pwd)" "$(pwd)/build"
+ env PYTEST_ADDOPTS=--error-for-skips \
+ ./ci/scripts/python_test.sh "$(pwd)" "$(pwd)/build"
if [ "$postgres_version" = "18" ]; then
uv --project=./c/driver/postgresql/validation/ run \
ci/scripts/validate.sh "$(pwd)" --vendor postgresql
@@ -329,6 +329,11 @@ jobs:
vendor: cockroachdb
uri: postgresql://root@localhost:5435/postgres?sslmode=disable
experimental: false
+ - name: CrateDB
+ service: cratedb-test
+ vendor: cratedb
+ uri: postgresql://crate@localhost:5436/doc?sslmode=disable
+ experimental: true
- name: ParadeDB
service: paradedb-test
vendor: paradedb
@@ -351,11 +356,6 @@ jobs:
# vendor: cedardb
# uri: postgresql://localhost:5433/postgres?user=postgres&password=CedarDB2026%21
# experimental: true
- # - name: CrateDB
- # service: cratedb-test
- # vendor: cratedb
- # uri: postgresql://crate@localhost:5436/doc?sslmode=disable
- # experimental: true
steps:
- name: Free up disk space
run: |
diff --git a/c/driver/postgresql/validation/pyproject.toml b/c/driver/postgresql/validation/pyproject.toml
index 0d335574e7..d1e88d6738 100644
--- a/c/driver/postgresql/validation/pyproject.toml
+++ b/c/driver/postgresql/validation/pyproject.toml
@@ -24,4 +24,4 @@ dependencies = [
]
[tool.uv.sources]
-adbc-drivers-validation = { git = "https://github.com/adbc-drivers/validation", rev = "ffb8c9e9b76b2953525e67f5305497587ced1edd" }
+adbc-drivers-validation = { git = "https://github.com/adbc-drivers/validation", rev = "575a41bfd96b09d9d8a057d0ea1e66a27a315475" }
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/binary.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/binary.txtcase
new file mode 100644
index 0000000000..277afd82af
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/binary.txtcase
@@ -0,0 +1,22 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+# CrateDB does not have a binary data type:
+# https://cratedb.com/docs/crate/reference/en/6.4/general/ddl/data-types.html
+hide = true
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/binary_view.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/binary_view.txtcase
new file mode 100644
index 0000000000..277afd82af
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/binary_view.txtcase
@@ -0,0 +1,22 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+# CrateDB does not have a binary data type:
+# https://cratedb.com/docs/crate/reference/en/6.4/general/ddl/data-types.html
+hide = true
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/date.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/date.txtcase
new file mode 100644
index 0000000000..140fe01312
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/date.txtcase
@@ -0,0 +1,20 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+skip = "CrateDB supports DATE only as a type literal and cannot store DATE columns: https://cratedb.com/docs/crate/reference/en/6.4/general/ddl/data-types.html#date"
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/fixed_size_binary.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/fixed_size_binary.txtcase
new file mode 100644
index 0000000000..277afd82af
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/fixed_size_binary.txtcase
@@ -0,0 +1,22 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+# CrateDB does not have a binary data type:
+# https://cratedb.com/docs/crate/reference/en/6.4/general/ddl/data-types.html
+hide = true
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/int64.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/int64.txtcase
new file mode 100644
index 0000000000..46c92e00cb
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/int64.txtcase
@@ -0,0 +1,34 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: bind
+
+{"res": 42}
+{"res": 4294967296}
+{"res": 9223372036854775806}
+{"res": -9223372036854775807}
+{"res": 0}
+{"res": null}
+
+// part: expected
+
+{"res": null}
+{"res": -9223372036854775807}
+{"res": 0}
+{"res": 42}
+{"res": 4294967296}
+{"res": 9223372036854775806}
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/large_binary.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/large_binary.txtcase
new file mode 100644
index 0000000000..277afd82af
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/large_binary.txtcase
@@ -0,0 +1,22 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+# CrateDB does not have a binary data type:
+# https://cratedb.com/docs/crate/reference/en/6.4/general/ddl/data-types.html
+hide = true
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/time_ms.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/time_ms.txtcase
new file mode 100644
index 0000000000..7bd5d52fd4
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/time_ms.txtcase
@@ -0,0 +1,22 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+# CrateDB does not support TIME WITHOUT TIME ZONE or TIME columns:
+# https://cratedb.com/docs/crate/reference/en/6.4/general/ddl/data-types.html#time
+hide = true
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/time_ns.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/time_ns.txtcase
new file mode 100644
index 0000000000..7bd5d52fd4
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/time_ns.txtcase
@@ -0,0 +1,22 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+# CrateDB does not support TIME WITHOUT TIME ZONE or TIME columns:
+# https://cratedb.com/docs/crate/reference/en/6.4/general/ddl/data-types.html#time
+hide = true
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/time_s.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/time_s.txtcase
new file mode 100644
index 0000000000..7bd5d52fd4
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/time_s.txtcase
@@ -0,0 +1,22 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+# CrateDB does not support TIME WITHOUT TIME ZONE or TIME columns:
+# https://cratedb.com/docs/crate/reference/en/6.4/general/ddl/data-types.html#time
+hide = true
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/time_us.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/time_us.txtcase
new file mode 100644
index 0000000000..7bd5d52fd4
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/time_us.txtcase
@@ -0,0 +1,22 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+# CrateDB does not support TIME WITHOUT TIME ZONE or TIME columns:
+# https://cratedb.com/docs/crate/reference/en/6.4/general/ddl/data-types.html#time
+hide = true
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamp_ms.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamp_ms.txtcase
new file mode 100644
index 0000000000..d2943d938d
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamp_ms.txtcase
@@ -0,0 +1,28 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+[tags]
+sql-type-name = "TIMESTAMP"
+
+// part: setup_query
+
+CREATE TABLE test_timestamp (
+ idx INT,
+ res TIMESTAMP
+);
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamp_ns.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamp_ns.txtcase
new file mode 100644
index 0000000000..355d169e79
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamp_ns.txtcase
@@ -0,0 +1,36 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+[tags]
+sql-type-name = "TIMESTAMP"
+
+// part: setup_query
+
+CREATE TABLE test_timestamp (
+ idx INT,
+ res TIMESTAMP
+);
+
+// part: expected
+
+{"res": null}
+{"res": -9223372036854000}
+{"res": 946684800000000}
+{"res": 1684158330000000}
+{"res": 9223372036854000}
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamp_s.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamp_s.txtcase
new file mode 100644
index 0000000000..d2943d938d
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamp_s.txtcase
@@ -0,0 +1,28 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+[tags]
+sql-type-name = "TIMESTAMP"
+
+// part: setup_query
+
+CREATE TABLE test_timestamp (
+ idx INT,
+ res TIMESTAMP
+);
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamp_us.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamp_us.txtcase
new file mode 100644
index 0000000000..c08fab0eb4
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamp_us.txtcase
@@ -0,0 +1,36 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+[tags]
+sql-type-name = "TIMESTAMP"
+
+// part: setup_query
+
+CREATE TABLE test_timestamp (
+ idx INT,
+ res TIMESTAMP
+);
+
+// part: expected
+
+{"res": null}
+{"res": -62135596800000000}
+{"res": 946684800123000}
+{"res": 1684158330123000}
+{"res": 253402300799999000}
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_ms.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_ms.txtcase
new file mode 100644
index 0000000000..3b99fb72fe
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_ms.txtcase
@@ -0,0 +1,29 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+[tags]
+sql-type-name = "TIMESTAMP WITH TIME ZONE"
+
+// part: setup_query
+
+CREATE TABLE test_timestamptz (
+ idx INT,
+ res TIMESTAMP WITH TIME ZONE,
+ res2 TIMESTAMP WITH TIME ZONE
+);
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_ns.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_ns.txtcase
new file mode 100644
index 0000000000..49d9aa9a26
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_ns.txtcase
@@ -0,0 +1,37 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+[tags]
+sql-type-name = "TIMESTAMP WITH TIME ZONE"
+
+// part: setup_query
+
+CREATE TABLE test_timestamptz (
+ idx INT,
+ res TIMESTAMP WITH TIME ZONE,
+ res2 TIMESTAMP WITH TIME ZONE
+);
+
+// part: expected
+
+{"res": null, "res2": null}
+{"res": -9223372036854000, "res2": -9223372036854000}
+{"res": 946684800000000, "res2": 946684800000000}
+{"res": 1684158330000000, "res2": 1684158330000000}
+{"res": 9223372036854000, "res2": 9223372036854000}
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_s.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_s.txtcase
new file mode 100644
index 0000000000..3b99fb72fe
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_s.txtcase
@@ -0,0 +1,29 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+[tags]
+sql-type-name = "TIMESTAMP WITH TIME ZONE"
+
+// part: setup_query
+
+CREATE TABLE test_timestamptz (
+ idx INT,
+ res TIMESTAMP WITH TIME ZONE,
+ res2 TIMESTAMP WITH TIME ZONE
+);
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_us.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_us.txtcase
new file mode 100644
index 0000000000..a4ee59df49
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_us.txtcase
@@ -0,0 +1,37 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+[tags]
+sql-type-name = "TIMESTAMP WITH TIME ZONE"
+
+// part: setup_query
+
+CREATE TABLE test_timestamptz (
+ idx INT,
+ res TIMESTAMP WITH TIME ZONE,
+ res2 TIMESTAMP WITH TIME ZONE
+);
+
+// part: expected
+
+{"res": null, "res2": null}
+{"res": -14182940000000, "res2": -14182940000000}
+{"res": 946684800000000, "res2": 946684800000000}
+{"res": 1684158330000000, "res2": 1684158330000000}
+{"res": 253402300799999000, "res2": 253402300799999000}
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/uuid.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/uuid.txtcase
new file mode 100644
index 0000000000..a8266b9030
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/uuid.txtcase
@@ -0,0 +1,20 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+skip = "The PostgreSQL driver cannot resolve CrateDB's UUID type when binding Arrow UUID values"
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/literal/binary.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/literal/binary.txtcase
new file mode 100644
index 0000000000..277afd82af
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/literal/binary.txtcase
@@ -0,0 +1,22 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+# CrateDB does not have a binary data type:
+# https://cratedb.com/docs/crate/reference/en/6.4/general/ddl/data-types.html
+hide = true
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/literal/time.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/literal/time.txtcase
new file mode 100644
index 0000000000..fc245d9f23
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/literal/time.txtcase
@@ -0,0 +1,22 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+# CrateDB does not support TIME WITHOUT TIME ZONE:
+# https://cratedb.com/docs/crate/reference/en/6.4/general/ddl/data-types.html#time
+hide = true
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/literal/uuid.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/literal/uuid.txtcase
new file mode 100644
index 0000000000..ab6e94bc43
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/literal/uuid.txtcase
@@ -0,0 +1,33 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: expected_schema
+
+{
+ "format": "+s",
+ "children": [
+ {
+ "name": "res",
+ "format": "z",
+ "flags": ["nullable"],
+ "metadata": {
+ "ARROW:extension:name": "arrow.opaque",
+ "ARROW:extension:metadata": "{\"type_name\": \"uuid\", \"vendor_name\": \"PostgreSQL\"}"
+ }
+ }
+ ]
+}
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/select/binary.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/select/binary.txtcase
new file mode 100644
index 0000000000..277afd82af
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/select/binary.txtcase
@@ -0,0 +1,22 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+# CrateDB does not have a binary data type:
+# https://cratedb.com/docs/crate/reference/en/6.4/general/ddl/data-types.html
+hide = true
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/select/date.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/select/date.txtcase
new file mode 100644
index 0000000000..140fe01312
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/select/date.txtcase
@@ -0,0 +1,20 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+skip = "CrateDB supports DATE only as a type literal and cannot store DATE columns: https://cratedb.com/docs/crate/reference/en/6.4/general/ddl/data-types.html#date"
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/select/int64.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/select/int64.txtcase
new file mode 100644
index 0000000000..72f2433c0c
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/select/int64.txtcase
@@ -0,0 +1,37 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: setup_query
+
+CREATE TABLE test_int64 (
+ idx INTEGER,
+ res BIGINT
+);
+
+INSERT INTO test_int64 (idx, res) VALUES (1, 4294967296);
+INSERT INTO test_int64 (idx, res) VALUES (2, 9223372036854775806);
+INSERT INTO test_int64 (idx, res) VALUES (3, -9223372036854775807);
+INSERT INTO test_int64 (idx, res) VALUES (4, 0);
+INSERT INTO test_int64 (idx, res) VALUES (5, NULL);
+
+// part: expected
+
+{"res": 4294967296}
+{"res": 9223372036854775806}
+{"res": -9223372036854775807}
+{"res": 0}
+{"res": null}
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/select/json.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/select/json.txtcase
new file mode 100644
index 0000000000..e075fc10e7
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/select/json.txtcase
@@ -0,0 +1,20 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+skip = "CrateDB supports JSON for casts but cannot store JSON columns: https://cratedb.com/docs/crate/reference/en/6.4/general/ddl/data-types.html#json"
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/select/jsonb.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/select/jsonb.txtcase
new file mode 100644
index 0000000000..4c324af1b2
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/select/jsonb.txtcase
@@ -0,0 +1,22 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+# CrateDB does not have a JSONB data type:
+# https://cratedb.com/docs/crate/reference/en/6.4/general/ddl/data-types.html
+hide = true
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/select/time.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/select/time.txtcase
new file mode 100644
index 0000000000..7bd5d52fd4
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/select/time.txtcase
@@ -0,0 +1,22 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: metadata
+
+# CrateDB does not support TIME WITHOUT TIME ZONE or TIME columns:
+# https://cratedb.com/docs/crate/reference/en/6.4/general/ddl/data-types.html#time
+hide = true
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/select/uuid.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/select/uuid.txtcase
new file mode 100644
index 0000000000..ab6e94bc43
--- /dev/null
+++ b/c/driver/postgresql/validation/queries-cratedb/type/select/uuid.txtcase
@@ -0,0 +1,33 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: expected_schema
+
+{
+ "format": "+s",
+ "children": [
+ {
+ "name": "res",
+ "format": "z",
+ "flags": ["nullable"],
+ "metadata": {
+ "ARROW:extension:name": "arrow.opaque",
+ "ARROW:extension:metadata": "{\"type_name\": \"uuid\", \"vendor_name\": \"PostgreSQL\"}"
+ }
+ }
+ ]
+}
diff --git a/c/driver/postgresql/validation/tests/postgresql.py b/c/driver/postgresql/validation/tests/postgresql.py
index 554764e5d0..76058800ec 100644
--- a/c/driver/postgresql/validation/tests/postgresql.py
+++ b/c/driver/postgresql/validation/tests/postgresql.py
@@ -15,11 +15,15 @@
# specific language governing permissions and limitations
# under the License.
+import contextlib
import re
+import typing
from pathlib import Path
from adbc_drivers_validation import model, quirks
+import adbc_driver_manager.dbapi
+
class PostgreSQLQuirks(model.DriverQuirks):
name = "postgresql"
@@ -139,6 +143,7 @@ class CrateDBQuirks(PostgreSQLQuirks):
connection_get_table_schema=False,
current_catalog="crate",
current_schema="doc",
+ statement_bulk_ingest=False,
)
setup = model.DriverSetup(
database={
@@ -148,6 +153,28 @@ class CrateDBQuirks(PostgreSQLQuirks):
statement={"adbc.postgresql.use_copy": "false"},
)
+ @property
+ def queries_paths(self) -> tuple[Path]:
+ return (
+ *super().queries_paths,
+ Path(__file__).parent.parent / "queries-cratedb",
+ )
+
+ @contextlib.contextmanager
+ def setup_statement(
+ self,
+ query: model.Query | str,
+ cursor: adbc_driver_manager.dbapi.Cursor,
+ ) -> typing.Generator[None, None, None]:
+ with super().setup_statement(query, cursor):
+ if isinstance(query, model.Query):
+ if table_name := query.metadata().setup.drop:
+ cursor.adbc_statement.set_sql_query(
+ f"REFRESH TABLE {self.quote_identifier(table_name)}"
+ )
+ cursor.adbc_statement.execute_update()
+ yield
+
class ParadeDBQuirks(PostgreSQLQuirks):
pass
diff --git a/c/driver/postgresql/validation/uv.lock b/c/driver/postgresql/validation/uv.lock
index 40f7f13e46..574b582445 100644
--- a/c/driver/postgresql/validation/uv.lock
+++ b/c/driver/postgresql/validation/uv.lock
@@ -35,7 +35,7 @@ wheels = [
[[package]]
name = "adbc-drivers-validation"
version = "0.1"
-source = { git = "https://github.com/adbc-drivers/validation?rev=ffb8c9e9b76b2953525e67f5305497587ced1edd#ffb8c9e9b76b2953525e67f5305497587ced1edd" }
+source = { git = "https://github.com/adbc-drivers/validation?rev=575a41bfd96b09d9d8a057d0ea1e66a27a315475#575a41bfd96b09d9d8a057d0ea1e66a27a315475" }
dependencies = [
{ name = "adbc-driver-manager" },
{ name = "bidict" },
@@ -78,24 +78,24 @@ wheels = [
[[package]]
name = "duckdb"
-version = "1.5.3"
+version = "1.5.5"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/69/00/d579dcb2a536b6ea3a2563cdad6844f77d81a9b2d4b22a858097f2468acf/duckdb-1.5.3.tar.gz", hash = "sha256:df39428eb130faa35ae96fd35245bdeae6ecf43936250b116b5fead568eb9f16", size = 18026640, upload-time = "2026-05-20T11:55:31.901Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/7d/19/e57151753576373c6696a12022648546cca6038e8833fda2908ee2342d9b/duckdb-1.5.5.tar.gz", hash = "sha256:72f33ee57ca7595b23957671a2cc7f7fe2be0ecc2d68f63abedcfcaa3a5c1238", size = 18066741, upload-time = "2026-07-22T10:55:17.819Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/cc/9c/a528eb09d8be51954c485864bd06753e616939a080cbc3dd4417e8c94a57/duckdb-1.5.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e75a6122c12579a99848517f6f00a4e342aebda3590c30fe9b5cc5f39d5e6afc", size = 32626254, upload-time = "2026-05-20T11:54:53.65Z" },
- { url = "https://files.pythonhosted.org/packages/ec/3c/1534c0a6db347c05eb7d0f6ecfb7aefbe74cbff398e4892a8fd1903a20e8/duckdb-1.5.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fd3963c1cb9d9567777f4a898a9dbe388a2fe9724681801b1e7d6d93eecf1b76", size = 17300917, upload-time = "2026-05-20T11:54:56.628Z" },
- { url = "https://files.pythonhosted.org/packages/23/fa/beafb91e6e152d2161c4a9cbc472334c87607eb61ad7104b5a7fa8d8d7b1/duckdb-1.5.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3d5db8c0b55e072cf437948ebb5d7e23d7b9d03d905fa5f9145583e65aa447f7", size = 15449411, upload-time = "2026-05-20T11:54:59.089Z" },
- { url = "https://files.pythonhosted.org/packages/50/0a/49b6fe04e2fcd63729eb607dadd44818dde77342a4f5ce086c6c92f1dd4d/duckdb-1.5.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ce80aed7a538422129a57eaca9141e3afb51f8bf562b1908b1576c9725b5b22", size = 19333120, upload-time = "2026-05-20T11:55:01.727Z" },
- { url = "https://files.pythonhosted.org/packages/63/4c/0907c3f76adb9dd90e67610b31e0304a35814e65c4c41a354a262c09b885/duckdb-1.5.3-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:787df63824f07bf18022dbc3b8ca4b2bfab0ebe616464f55c6e8cd0f59ea762e", size = 21453266, upload-time = "2026-05-20T11:55:04.5Z" },
- { url = "https://files.pythonhosted.org/packages/6d/9c/d2f23a7803ddbbd9413f7572ecf66a15120ed5ced7ce5c73e698c1406b76/duckdb-1.5.3-cp313-cp313-win_amd64.whl", hash = "sha256:bb5bb5dcdd09d62ee60f0ddbbef918e71cce304ffe28428b1131949d39ffaabf", size = 13118640, upload-time = "2026-05-20T11:55:07.389Z" },
- { url = "https://files.pythonhosted.org/packages/27/d5/7ba2316415bcdab6edd765bbbe35c2ca8a3800f2fe695cd70e3cdb997f09/duckdb-1.5.3-cp313-cp313-win_arm64.whl", hash = "sha256:2fa17ecdd5d3db122836cb71bb93601c2106a3be883c17dffddc02fbf3fa7888", size = 13926409, upload-time = "2026-05-20T11:55:10.166Z" },
- { url = "https://files.pythonhosted.org/packages/a5/c2/d4b6f8a5e4d3bc25773be6da76a99d9661ebbf3552c007c460d2dd59dbf8/duckdb-1.5.3-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:4bfa9a4dadf71e83e2c4eaca2f9421c82a54defecc1b0b4c0be95e2389dec4fe", size = 32636685, upload-time = "2026-05-20T11:55:13.158Z" },
- { url = "https://files.pythonhosted.org/packages/42/58/e835c8298979d29db7a62cb5acc29e9b57aeaca7cdde2fcd3ac980f5cb18/duckdb-1.5.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:aea7baf67ad7e1829ac76f67d7dcbd7fb1f57c3eb179d55ac30952df4709ae30", size = 17308134, upload-time = "2026-05-20T11:55:16.194Z" },
- { url = "https://files.pythonhosted.org/packages/c9/46/617b51363f5613418c8b224b3cce16b58e6dde80904566bec232579c1d4e/duckdb-1.5.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b0b4f088a65d77e1217ce5d7eff889e63fedc44281200d899ff47c84d8ff836", size = 15449891, upload-time = "2026-05-20T11:55:18.687Z" },
- { url = "https://files.pythonhosted.org/packages/b3/72/354146656e8d9ba3853d3a5ee80a481b8c5f70edfc3d5ae80a8c4479c967/duckdb-1.5.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fe8d0c1f6a120aa03fa6e0d03897c71a1842e6cf7afd31d181348391f7108fe1", size = 19338499, upload-time = "2026-05-20T11:55:21.34Z" },
- { url = "https://files.pythonhosted.org/packages/56/8f/65fc623b51448f2bfba1a9ec6ab3debb4664c0876c0113a5e782600b53ac/duckdb-1.5.3-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0405eae18ec6e8210a471c97dbfe87a7e4d605274b7fe572a1f276e92158f13", size = 21455828, upload-time = "2026-05-20T11:55:23.847Z" },
- { url = "https://files.pythonhosted.org/packages/2b/db/d0274cbe9f5fe219f77c0bdf900ac77103569e83c102a4225ce04cbc607d/duckdb-1.5.3-cp314-cp314-win_amd64.whl", hash = "sha256:33ae08b3e818d7613d8936744b67718c2062c2f530376895bfd89efb51b81538", size = 13640011, upload-time = "2026-05-20T11:55:26.276Z" },
- { url = "https://files.pythonhosted.org/packages/07/5d/8f1899b8bef291caf953992fcd6c24df9f29387a35645e58c2504a5ca473/duckdb-1.5.3-cp314-cp314-win_arm64.whl", hash = "sha256:746433e49bbc667b4df283153415fbe37e9083e0eff6c3cd6e54de7536869cd4", size = 14411554, upload-time = "2026-05-20T11:55:29.037Z" },
+ { url = "https://files.pythonhosted.org/packages/47/37/4a38116e7700720fd152c666292214fd3abdf916496991296d8d1f66efbf/duckdb-1.5.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:cd98829b67788609017e65c761bd42a5dd0f9129441bed8bda4d6881ccf819f0", size = 32754294, upload-time = "2026-07-22T10:54:29.822Z" },
+ { url = "https://files.pythonhosted.org/packages/66/42/7d392f1ba1eee0eaf4ab4c8c7a604bfe3536cd63f979cf5c98798664f807/duckdb-1.5.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:feead93c56679b79592d437c62975d39cb67adedffa7592c763baf8160ac7366", size = 17368211, upload-time = "2026-07-22T10:54:33.359Z" },
+ { url = "https://files.pythonhosted.org/packages/9f/a5/0a6f4fa60562faa615e55e15bd1953a2f2b17a8edd8105e5cda215e43457/duckdb-1.5.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:49c963d9469373d7aba8d750d9ea565ab823e94166efed953f184dd9b169b98c", size = 15509136, upload-time = "2026-07-22T10:54:36.369Z" },
+ { url = "https://files.pythonhosted.org/packages/e4/cb/023c89f51978545b9fab318581bba0c457a58e7530d2d933e54ae7d8647c/duckdb-1.5.5-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a736217825461732b5442d05a220f3da2e23a0dae114efbf08c9bf171b53098a", size = 19392147, upload-time = "2026-07-22T10:54:39.551Z" },
+ { url = "https://files.pythonhosted.org/packages/3e/c5/41bef391fb8b23dbc133c9f2ba016e7a7a8124513d2cc1b430f1897d87e4/duckdb-1.5.5-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:078e6a60dd8eedde5832f45422ca5c4a6b8c837aeabd8a56ca0b7d933f588053", size = 21511060, upload-time = "2026-07-22T10:54:42.788Z" },
+ { url = "https://files.pythonhosted.org/packages/07/9f/c44dfc1f924ac29b3252dc1b91393c01d009dbfe9f8ed33f10b986151bd1/duckdb-1.5.5-cp313-cp313-win_amd64.whl", hash = "sha256:6826504277dba513c0c5d71d828456c94d729c9d2482f94b2e289f90a9167e28", size = 13168028, upload-time = "2026-07-22T10:54:46.127Z" },
+ { url = "https://files.pythonhosted.org/packages/ca/88/591384b2cd59abddd6f5dc175e60374f9abae6064429f0c4402854c10f44/duckdb-1.5.5-cp313-cp313-win_arm64.whl", hash = "sha256:baa9c5702002fabb559ded2a39008f9f421fcbc7237d388b8213eff1e08858de", size = 13989955, upload-time = "2026-07-22T10:54:49.262Z" },
+ { url = "https://files.pythonhosted.org/packages/3e/56/12c65bfa2d2605b81981b264788891bcf11ec72227889554cead5d8d13b9/duckdb-1.5.5-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8e6413dd40facb7b8ab21bd844450cd8f549b29e138635be9cf090ef4d2049e2", size = 32761946, upload-time = "2026-07-22T10:54:53.412Z" },
+ { url = "https://files.pythonhosted.org/packages/b9/46/682ce155f17e0d2822d4f13ee3db9ca4b5b7c2da61b841b2629035e1f4bc/duckdb-1.5.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:64078acfd16541132ac6e191eb81b2845554444a0305cc1aa581ba107e514aa8", size = 17375069, upload-time = "2026-07-22T10:54:57.269Z" },
+ { url = "https://files.pythonhosted.org/packages/39/ce/a24bcbd3289c8f305a430759c5fc12242740b4af3e17f7593f3a34e333d2/duckdb-1.5.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8c11775cc99a447618d5f1840126db17f2652f3eae05529df4f81f40e2df7151", size = 15519791, upload-time = "2026-07-22T10:55:00.681Z" },
+ { url = "https://files.pythonhosted.org/packages/d9/76/3a01afbc615c1d418c0de58a6b68ac5ce2a8563232c0464bfbc2ce552398/duckdb-1.5.5-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77bbc1e6ba12e1e06f9020117bdf848627ecfdf36f907550e62e008e6109dece", size = 19398251, upload-time = "2026-07-22T10:55:04.168Z" },
+ { url = "https://files.pythonhosted.org/packages/a1/43/3a5e81d1728f4d234c79bfe385808ee7c04834f7c37a4b5c257459c25614/duckdb-1.5.5-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fbf0f2d48b43c6c304d00463b463c27ead6c4b01c3c1816b750f728decf71afe", size = 21513851, upload-time = "2026-07-22T10:55:07.864Z" },
+ { url = "https://files.pythonhosted.org/packages/91/41/fc7c829172c60ca22485251eab285f4f1a0d87b486a024c726f21471d86e/duckdb-1.5.5-cp314-cp314-win_amd64.whl", hash = "sha256:9dc826c4b50e64f6c4e4d07a3a9cb075ef70ba3899dc43ec5493dc3d7b04b353", size = 13691858, upload-time = "2026-07-22T10:55:11.181Z" },
+ { url = "https://files.pythonhosted.org/packages/e1/2c/95d9216b79e9273689d7ebce125a54503ed0c9bd7da931f0265888e99779/duckdb-1.5.5-cp314-cp314-win_arm64.whl", hash = "sha256:63e48d4b74b15aeacd688976432a7225163df8c226eddeb8536bba2d4d4ff433", size = 14470180, upload-time = "2026-07-22T10:55:14.445Z" },
]
[[package]]
@@ -207,7 +207,7 @@ dependencies = [
]
[package.metadata]
-requires-dist = [{ name = "adbc-drivers-validation", git = "https://github.com/adbc-drivers/validation?rev=ffb8c9e9b76b2953525e67f5305497587ced1edd" }]
+requires-dist = [{ name = "adbc-drivers-validation", git = "https://github.com/adbc-drivers/validation?rev=575a41bfd96b09d9d8a057d0ea1e66a27a315475" }]
[[package]]
name = "pyarrow"
@@ -327,7 +327,7 @@ wheels = [
[[package]]
name = "pytest"
-version = "9.0.3"
+version = "9.1.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "colorama", marker = "sys_platform == 'win32'" },
@@ -336,18 +336,18 @@ dependencies = [
{ name = "pluggy" },
{ name = "pygments" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c", size = 1572165, upload-time = "2026-04-07T17:16:18.027Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" },
+ { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" },
]
[[package]]
name = "sqlglot"
-version = "30.10.0"
+version = "30.17.0"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/84/23/68932577cac288a0b7267ab8cea3e0e8a90809ed52a37b8514a795ea0433/sqlglot-30.10.0.tar.gz", hash = "sha256:be915f765813ba7ec7c6037732a738cb36811737b5ea6258ba99268043ef74a6", size = 5888815, upload-time = "2026-06-09T10:10:05.661Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/56/d4/da49abcc81beebbb25f29ddf87f2980c63c949569d7f2da40c06d95fa415/sqlglot-30.17.0.tar.gz", hash = "sha256:2d6b8def93304fa300f4d20f48e3909e7f436fda56ca1fafd8975f6c561ef62c", size = 5999019, upload-time = "2026-08-12T19:36:50.587Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/d0/09/4f82db061c866e1bc3b620f852a1516881683ffce76c33180a5b6a0a6a34/sqlglot-30.10.0-py3-none-any.whl", hash = "sha256:540e5dfee4c6b65a3b5d93517a2573bb7546681e95d530d0e4e1702415d8835e", size = 696535, upload-time = "2026-06-09T10:10:03.437Z" },
+ { url = "https://files.pythonhosted.org/packages/f3/bc/2a07cef49046e6cf5d1a8b1de553aaef8491b4170dbfe254c8687c764408/sqlglot-30.17.0-py3-none-any.whl", hash = "sha256:84435ac283a60173da31b5fd7d11a725037a1c3fd6ed1e21fb065de74ddb579f", size = 741795, upload-time = "2026-08-12T19:36:48.699Z" },
]
[[package]]
From 5b78cb9128baf0da19a355a8b46aa3160763bf21 Mon Sep 17 00:00:00 2001
From: David Li
Date: Tue, 18 Aug 2026 17:27:33 +0900
Subject: [PATCH 4/9] update cases
---
.../validation/queries/ingest/decimal.txtcase | 14 +++--
.../decimal_scale_equals_precision.txtcase | 47 +++++++++++++++
.../ingest/decimal_scale_negative.txtcase | 47 +++++++++++++++
.../queries/ingest/decimal_scale_zero.txtcase | 57 +++++++++++++++++++
4 files changed, 159 insertions(+), 6 deletions(-)
create mode 100644 c/driver/postgresql/validation/queries/ingest/decimal_scale_equals_precision.txtcase
create mode 100644 c/driver/postgresql/validation/queries/ingest/decimal_scale_negative.txtcase
create mode 100644 c/driver/postgresql/validation/queries/ingest/decimal_scale_zero.txtcase
diff --git a/c/driver/postgresql/validation/queries/ingest/decimal.txtcase b/c/driver/postgresql/validation/queries/ingest/decimal.txtcase
index a4d079ab35..7b21a0b791 100644
--- a/c/driver/postgresql/validation/queries/ingest/decimal.txtcase
+++ b/c/driver/postgresql/validation/queries/ingest/decimal.txtcase
@@ -38,9 +38,11 @@
// part: expected
-{"idx": 0, "value": "0"}
-{"idx": 1, "value": "123.45"}
-{"idx": 2, "value": "-123.45"}
-{"idx": 3, "value": "9999999.99"}
-{"idx": 4, "value": "-9999999.99"}
-{"idx": 5, "value": null}
+{"idx": 0, "value": null}
+{"idx": 1, "value": "0"}
+{"idx": 2, "value": "123.45"}
+{"idx": 3, "value": "-123.45"}
+{"idx": 4, "value": "9999999.99"}
+{"idx": 5, "value": "-9999999.99"}
+{"idx": 6, "value": "99999999.99"}
+{"idx": 7, "value": "-99999999.99"}
diff --git a/c/driver/postgresql/validation/queries/ingest/decimal_scale_equals_precision.txtcase b/c/driver/postgresql/validation/queries/ingest/decimal_scale_equals_precision.txtcase
new file mode 100644
index 0000000000..cf39915edf
--- /dev/null
+++ b/c/driver/postgresql/validation/queries/ingest/decimal_scale_equals_precision.txtcase
@@ -0,0 +1,47 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: expected_schema
+
+{
+ "format": "+s",
+ "children": [
+ {
+ "name": "idx",
+ "format": "l",
+ "flags": ["nullable"]
+ },
+ {
+ "name": "value",
+ "format": "u",
+ "flags": ["nullable"],
+ "metadata": {
+ "ARROW:extension:name": "arrow.opaque",
+ "ARROW:extension:metadata": "{\"type_name\": \"numeric\", \"vendor_name\": \"PostgreSQL\"}"
+ }
+ }
+ ]
+}
+
+// part: expected
+
+{"idx": 0, "value": null}
+{"idx": 1, "value": "0"}
+{"idx": 2, "value": "0.99"}
+{"idx": 3, "value": "-0.99"}
+{"idx": 4, "value": "0.1"}
+{"idx": 5, "value": "-0.1"}
diff --git a/c/driver/postgresql/validation/queries/ingest/decimal_scale_negative.txtcase b/c/driver/postgresql/validation/queries/ingest/decimal_scale_negative.txtcase
new file mode 100644
index 0000000000..a965a58e5f
--- /dev/null
+++ b/c/driver/postgresql/validation/queries/ingest/decimal_scale_negative.txtcase
@@ -0,0 +1,47 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: expected_schema
+
+{
+ "format": "+s",
+ "children": [
+ {
+ "name": "idx",
+ "format": "l",
+ "flags": ["nullable"]
+ },
+ {
+ "name": "value",
+ "format": "u",
+ "flags": ["nullable"],
+ "metadata": {
+ "ARROW:extension:name": "arrow.opaque",
+ "ARROW:extension:metadata": "{\"type_name\": \"numeric\", \"vendor_name\": \"PostgreSQL\"}"
+ }
+ }
+ ]
+}
+
+// part: expected
+
+{"idx": 0, "value": null}
+{"idx": 1, "value": "0"}
+{"idx": 2, "value": "9900"}
+{"idx": 3, "value": "-9900"}
+{"idx": 4, "value": "1000"}
+{"idx": 5, "value": "-1000"}
diff --git a/c/driver/postgresql/validation/queries/ingest/decimal_scale_zero.txtcase b/c/driver/postgresql/validation/queries/ingest/decimal_scale_zero.txtcase
new file mode 100644
index 0000000000..31621a79ce
--- /dev/null
+++ b/c/driver/postgresql/validation/queries/ingest/decimal_scale_zero.txtcase
@@ -0,0 +1,57 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+// part: expected_schema
+
+{
+ "format": "+s",
+ "children": [
+ {
+ "name": "idx",
+ "format": "l",
+ "flags": ["nullable"]
+ },
+ {
+ "name": "value",
+ "format": "u",
+ "flags": ["nullable"],
+ "metadata": {
+ "ARROW:extension:name": "arrow.opaque",
+ "ARROW:extension:metadata": "{\"type_name\": \"numeric\", \"vendor_name\": \"PostgreSQL\"}"
+ }
+ }
+ ]
+}
+
+// part: expected
+
+{"idx": 0, "value": null}
+{"idx": 1, "value": "0"}
+{"idx": 2, "value": "12345"}
+{"idx": 3, "value": "-12345"}
+{"idx": 4, "value": "999999999"}
+{"idx": 5, "value": "-999999999"}
+{"idx": 6, "value": "1"}
+{"idx": 7, "value": "10"}
+{"idx": 8, "value": "100"}
+{"idx": 9, "value": "1000"}
+{"idx": 10, "value": "10000"}
+{"idx": 11, "value": "100000"}
+{"idx": 12, "value": "1000000"}
+{"idx": 13, "value": "10000000"}
+{"idx": 14, "value": "100000000"}
+{"idx": 15, "value": "1000000000"}
From 1bb3a2d195acfeb72325ab458ecef336bceb2e2b Mon Sep 17 00:00:00 2001
From: David Li
Date: Wed, 19 Aug 2026 12:58:26 +0900
Subject: [PATCH 5/9] update for cratedb
---
.../type/bind/timestamptz_ms.txtcase | 2 ++
.../type/bind/timestamptz_ns.txtcase | 2 ++
.../type/bind/timestamptz_s.txtcase | 2 ++
.../type/bind/timestamptz_us.txtcase | 2 ++
.../postgresql/validation/tests/postgresql.py | 2 ++
.../validation/tests/test_connection.py | 8 ++++++++
.../validation/tests/test_statement.py | 18 +++++++++++++-----
7 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_ms.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_ms.txtcase
index 3b99fb72fe..3a077b3d9b 100644
--- a/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_ms.txtcase
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_ms.txtcase
@@ -17,6 +17,8 @@
// part: metadata
+skip = "CrateDB does not expose the PostgreSQL TIMEZONE session setting required by this binding path"
+
[tags]
sql-type-name = "TIMESTAMP WITH TIME ZONE"
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_ns.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_ns.txtcase
index 49d9aa9a26..73374b90b8 100644
--- a/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_ns.txtcase
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_ns.txtcase
@@ -17,6 +17,8 @@
// part: metadata
+skip = "CrateDB does not expose the PostgreSQL TIMEZONE session setting required by this binding path"
+
[tags]
sql-type-name = "TIMESTAMP WITH TIME ZONE"
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_s.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_s.txtcase
index 3b99fb72fe..3a077b3d9b 100644
--- a/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_s.txtcase
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_s.txtcase
@@ -17,6 +17,8 @@
// part: metadata
+skip = "CrateDB does not expose the PostgreSQL TIMEZONE session setting required by this binding path"
+
[tags]
sql-type-name = "TIMESTAMP WITH TIME ZONE"
diff --git a/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_us.txtcase b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_us.txtcase
index a4ee59df49..f27b7099cf 100644
--- a/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_us.txtcase
+++ b/c/driver/postgresql/validation/queries-cratedb/type/bind/timestamptz_us.txtcase
@@ -17,6 +17,8 @@
// part: metadata
+skip = "CrateDB does not expose the PostgreSQL TIMEZONE session setting required by this binding path"
+
[tags]
sql-type-name = "TIMESTAMP WITH TIME ZONE"
diff --git a/c/driver/postgresql/validation/tests/postgresql.py b/c/driver/postgresql/validation/tests/postgresql.py
index 76058800ec..8999c53936 100644
--- a/c/driver/postgresql/validation/tests/postgresql.py
+++ b/c/driver/postgresql/validation/tests/postgresql.py
@@ -141,8 +141,10 @@ class CrateDBQuirks(PostgreSQLQuirks):
short_version = "14"
features = PostgreSQLQuirks.features.with_values(
connection_get_table_schema=False,
+ connection_transactions=False,
current_catalog="crate",
current_schema="doc",
+ get_objects=False,
statement_bulk_ingest=False,
)
setup = model.DriverSetup(
diff --git a/c/driver/postgresql/validation/tests/test_connection.py b/c/driver/postgresql/validation/tests/test_connection.py
index aa42b8c4c9..961003efd8 100644
--- a/c/driver/postgresql/validation/tests/test_connection.py
+++ b/c/driver/postgresql/validation/tests/test_connection.py
@@ -22,6 +22,14 @@
class TestConnection(test_connection.TestConnection):
+ def test_current_catalog(self, conn, driver) -> None:
+ if isinstance(driver, postgresql.CrateDBQuirks):
+ pytest.xfail(
+ "CrateDB has a fixed crate catalog, but libpq reports the doc "
+ "startup database/schema value as the current catalog"
+ )
+ super().test_current_catalog(driver, conn)
+
def test_get_objects_column_filter_table(
self, conn, driver, get_objects_table
) -> None:
diff --git a/c/driver/postgresql/validation/tests/test_statement.py b/c/driver/postgresql/validation/tests/test_statement.py
index 7412df768e..eb18de8ee7 100644
--- a/c/driver/postgresql/validation/tests/test_statement.py
+++ b/c/driver/postgresql/validation/tests/test_statement.py
@@ -15,14 +15,22 @@
# specific language governing permissions and limitations
# under the License.
-from adbc_drivers_validation.tests.statement import (
- TestStatement, # noqa: F401
- generate_tests,
-)
+import adbc_drivers_validation.tests.statement as test_statement
+import pytest
from . import postgresql
+class TestStatement(test_statement.TestStatement):
+ def test_rows_affected(self, driver, conn) -> None:
+ if isinstance(driver, postgresql.CrateDBQuirks):
+ pytest.xfail(
+ "CrateDB does not make writes immediately visible, and the upstream "
+ "test provides no REFRESH TABLE hook"
+ )
+ super().test_rows_affected(driver, conn)
+
+
def pytest_generate_tests(metafunc) -> None:
vendor = metafunc.config.getoption("vendor")
- return generate_tests([postgresql.get_quirks(vendor)], metafunc)
+ return test_statement.generate_tests([postgresql.get_quirks(vendor)], metafunc)
From 8410c28e37784a5ae91600977d397e8ab5bbfa9c Mon Sep 17 00:00:00 2001
From: David Li
Date: Wed, 19 Aug 2026 13:37:07 +0900
Subject: [PATCH 6/9] more cratedb overrides
---
.../postgresql/validation/tests/test_connection.py | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/c/driver/postgresql/validation/tests/test_connection.py b/c/driver/postgresql/validation/tests/test_connection.py
index 961003efd8..e29253e20a 100644
--- a/c/driver/postgresql/validation/tests/test_connection.py
+++ b/c/driver/postgresql/validation/tests/test_connection.py
@@ -30,6 +30,16 @@ def test_current_catalog(self, conn, driver) -> None:
)
super().test_current_catalog(driver, conn)
+ def test_get_objects_catalog(self, conn, driver) -> None:
+ if isinstance(driver, postgresql.CrateDBQuirks):
+ pytest.skip("GetObjects is marked unsupported for CrateDB")
+ super().test_get_objects_catalog(conn, driver)
+
+ def test_get_objects_table_not_exist(self, conn, driver) -> None:
+ if isinstance(driver, postgresql.CrateDBQuirks):
+ pytest.skip("GetObjects is marked unsupported for CrateDB")
+ super().test_get_objects_table_not_exist(conn, driver)
+
def test_get_objects_column_filter_table(
self, conn, driver, get_objects_table
) -> None:
From cafac6bf85955ca95d073369e16a3ea2b47da935 Mon Sep 17 00:00:00 2001
From: David Li
Date: Wed, 19 Aug 2026 13:37:29 +0900
Subject: [PATCH 7/9] fix comment
---
.github/workflows/integration.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
index ec5335f5a6..3f78a6dfbc 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -349,7 +349,7 @@ jobs:
vendor: yugabytedb
uri: postgresql://localhost:5439/yugabyte?user=yugabyte&password=yugabyte
experimental: false
- # These two currently fail, but could be supported in the future.
+ # Currently fails, but could be supported in the future.
# https://github.com/apache/arrow-adbc/issues/1755
# - name: CedarDB
# service: cedardb-test
From 9a0ba51a2bdfd300bda2132f066ee613fdd749b4 Mon Sep 17 00:00:00 2001
From: David Li
Date: Wed, 19 Aug 2026 14:03:51 +0900
Subject: [PATCH 8/9] bump version
---
compose.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/compose.yaml b/compose.yaml
index 66484bf7ab..dcfd78f594 100644
--- a/compose.yaml
+++ b/compose.yaml
@@ -448,7 +448,7 @@ services:
yugabytedb-test:
container_name: adbc_yugabytedb_test
hostname: adbc-yugabytedb-test
- image: yugabytedb/yugabyte:2026.1.1.0-b91
+ image: yugabytedb/yugabyte:2026.1.1.1-b2
command: >-
bin/yugabyted start --background=false
--master_flags=reject_writes_when_disk_full=false
From 28332ee38c0a161cb1c389b7b84b8d28b0a53566 Mon Sep 17 00:00:00 2001
From: David Li
Date: Wed, 19 Aug 2026 14:06:58 +0900
Subject: [PATCH 9/9] no need to stop
---
.github/workflows/integration.yml | 5 -----
1 file changed, 5 deletions(-)
diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
index 3f78a6dfbc..6da4e55588 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -414,11 +414,6 @@ jobs:
if: failure()
run: |
docker compose logs "${{ matrix.service }}"
- - name: Stop ${{ matrix.name }}
- if: always()
- run: |
- docker compose stop "${{ matrix.service }}"
- docker compose rm --force --stop --volumes "${{ matrix.service }}"
flightsql_interop:
name: "FlightSQL C# Interop"