Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,11 @@ jobs:
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
experimental: false
- name: Citus
service: citus-test
vendor: citus
Expand Down Expand Up @@ -412,11 +417,6 @@ jobs:
vendor: yugabytedb
uri: postgresql://localhost:5439/yugabyte?user=yugabyte&password=yugabyte
experimental: false
- name: CedarDB
service: cedardb-test
vendor: cedardb
uri: postgresql://localhost:5433/postgres?user=postgres&password=CedarDB2026%21
experimental: false
steps:
- name: Free up disk space
run: |
Expand Down
1 change: 1 addition & 0 deletions c/driver/postgresql/validation/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ version = "0.1.0"
requires-python = ">=3.13"
dependencies = [
"adbc-drivers-validation",
"hypothesis>=6.168.3",
]

[tool.uv.sources]
Expand Down
10 changes: 4 additions & 6 deletions c/driver/postgresql/validation/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ def pytest_addoption(parser) -> None:

@pytest.fixture(scope="session")
def driver(request) -> adbc_drivers_validation.model.DriverQuirks:
assert request.param.startswith("postgresql:")
return get_quirks(request.config.getoption("vendor"))


Expand All @@ -61,15 +60,14 @@ def driver_path(driver: adbc_drivers_validation.model.DriverQuirks) -> str:

possible_paths = [
# 1. c/build/driver/postgresql/ (CMake build from c/ directory)
base.parent.parent
/ f"build/driver/{driver.name}/libadbc_driver_{driver.name}.{ext}",
base.parent.parent / f"build/driver/postgresql/libadbc_driver_postgresql.{ext}",
# 2. <repo-root>/build/driver/postgresql/ (CI build location)
base.parent.parent.parent
/ f"build/driver/{driver.name}/libadbc_driver_{driver.name}.{ext}",
/ f"build/driver/postgresql/libadbc_driver_postgresql.{ext}",
# 3. c/driver/postgresql/build/ (local CMake build from driver dir)
base / f"build/libadbc_driver_{driver.name}.{ext}",
base / f"build/libadbc_driver_postgresql.{ext}",
# 4. c/driver/postgresql/ (direct build output in driver dir)
base / f"libadbc_driver_{driver.name}.{ext}",
base / f"libadbc_driver_postgresql.{ext}",
]

for path in possible_paths:
Expand Down
5 changes: 5 additions & 0 deletions c/driver/postgresql/validation/tests/postgresql.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ def split_statement(self, statement: str) -> list[str]:


class CedarDBQuirks(PostgreSQLQuirks):
name = "cedardb"
vendor_version = re.compile(r"16[0-9]{4}")
short_version = "16"
setup = model.DriverSetup(
Expand All @@ -125,6 +126,10 @@ class CedarDBQuirks(PostgreSQLQuirks):
statement={"adbc.postgresql.use_copy": "false"},
)

@property
def field_metadata_prefix(self) -> str:
return "POSTGRESQL"

@property
def queries_paths(self) -> tuple[Path, ...]:
return (
Expand Down
64 changes: 63 additions & 1 deletion c/driver/postgresql/validation/tests/test_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@
# specific language governing permissions and limitations
# under the License.

import decimal

import adbc_drivers_validation.utils
import hypothesis
import hypothesis.strategies as st
import pyarrow
import pytest
from adbc_drivers_validation.tests.query import (
TestQuery, # noqa: F401
generate_tests,
Expand All @@ -25,4 +32,59 @@

def pytest_generate_tests(metafunc) -> None:
vendor = metafunc.config.getoption("vendor")
return generate_tests([postgresql.get_quirks(vendor)], metafunc)
quirks = [postgresql.get_quirks(vendor)]
if not metafunc.definition.name.startswith("test_hypothesis_"):
return generate_tests(quirks, metafunc)
return adbc_drivers_validation.utils.generate_tests_by_marks(quirks, metafunc)


@st.composite
def st_decimal(draw, precision, scale) -> decimal.Decimal:
bound = 10**precision - 1
min_value = -bound
max_value = bound
unscaled = draw(st.integers(min_value=min_value, max_value=max_value))
return decimal.Decimal(unscaled).scaleb(-scale, context=decimal.Context(40))


@pytest.mark.parametrize(
"ps",
[
(1, 0),
(10, 5),
(38, 0),
(38, 10),
(38, 37),
],
ids=lambda ps: f"precision_{ps[0]:02}_scale_{ps[1]:02}",
)
@hypothesis.given(data=st.data())
@hypothesis.settings(deadline=5000)
@pytest.mark.requires_features(["statement_bulk_ingest"])
def test_hypothesis_decimal128(driver, conn, ps: tuple[int, int], data) -> None:
if driver.name == "cedardb" and ps[0] == 38:
# Not confirmed, but it appears CedarDB overflows internally when
# parsing large decimal values
pytest.skip("apparent bug in CedarDB with precision = 38")

dec = data.draw(st_decimal(*ps))
arr = pyarrow.array([dec], type=pyarrow.decimal128(ps[0], ps[1]))
arr.validate(full=True)
assert arr[0].as_py() == dec
tbl = pyarrow.Table.from_arrays([arr], names=["col"])

temp_table = "temp_decimal128"
with conn.cursor() as cur:
if driver.name == "cedardb":
# the driver doesn't add precision/scale when ingesting, but
# CedarDB defaults to (38, 6) apparently which trips up tests
cur.execute("DROP TABLE IF EXISTS temp_decimal128")
cur.execute(f"CREATE TABLE temp_decimal128 (col DECIMAL({ps[0]}, {ps[1]}))")
cur.adbc_ingest(temp_table, tbl, mode="append")
else:
cur.adbc_ingest(temp_table, tbl, mode="replace")
cur.execute(f"SELECT col FROM {temp_table}")
res = cur.fetchallarrow()

assert res.num_rows == 1
assert decimal.Decimal(res["col"][0].as_py()) == dec
10 changes: 5 additions & 5 deletions c/driver/postgresql/validation/tests/test_statement.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
from . import postgresql


def pytest_generate_tests(metafunc) -> None:
vendor = metafunc.config.getoption("vendor")
return test_statement.generate_tests([postgresql.get_quirks(vendor)], metafunc)


class TestStatement(test_statement.TestStatement):
def test_rows_affected(self, driver, conn) -> None:
if isinstance(driver, postgresql.CrateDBQuirks):
Expand All @@ -29,8 +34,3 @@ def test_rows_affected(self, driver, conn) -> None:
"test provides no REFRESH TABLE hook"
)
super().test_rows_affected(driver, conn)


def pytest_generate_tests(metafunc) -> None:
vendor = metafunc.config.getoption("vendor")
return test_statement.generate_tests([postgresql.get_quirks(vendor)], metafunc)
Loading
Loading