This is an automated email from the ASF dual-hosted git repository.
lidavidm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-adbc.git
The following commit(s) were added to refs/heads/main by this push:
new 6abfb8513 test(c/driver/postgresql): add Materialize to test matrix
(#4794)
6abfb8513 is described below
commit 6abfb851369a179bbc56ad72469a5b2ed1a200ae
Author: David Li <[email protected]>
AuthorDate: Sat Sep 19 18:34:20 2026 +0900
test(c/driver/postgresql): add Materialize to test matrix (#4794)
Closes #3690.
Assisted-by: GPT-6 Astra <[email protected]>
---
.github/workflows/integration.yml | 7 ++++-
.../queries-materialize/type/bind/decimal.txtcase | 24 +++++++++++++++
.../queries-materialize/type/bind/time_us.txtcase | 23 +++++++++++++++
.../type/bind/timestamp_ns.txtcase | 23 +++++++++++++++
.../type/bind/timestamptz_ns.txtcase | 24 +++++++++++++++
.../type/select/decimal.txtcase | 24 +++++++++++++++
.../type/select/float32.txtcase | 30 +++++++++++++++++++
.../type/select/float64.txtcase | 30 +++++++++++++++++++
.../queries-materialize/type/select/json.txtcase | 33 +++++++++++++++++++++
.../queries-materialize/type/select/jsonb.txtcase | 28 ++++++++++++++++++
c/driver/postgresql/validation/tests/postgresql.py | 34 ++++++++++++++++++----
.../postgresql/validation/tests/test_connection.py | 9 ++++++
compose.yaml | 12 ++++++++
docs/source/driver/postgresql.rst | 3 +-
14 files changed, 297 insertions(+), 7 deletions(-)
diff --git a/.github/workflows/integration.yml
b/.github/workflows/integration.yml
index d1c9db29f..43fcb7fd9 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -337,6 +337,11 @@ jobs:
vendor: cratedb
uri: postgresql://crate@localhost:5436/doc?sslmode=disable
experimental: true
+ - name: Materialize
+ service: materialize-test
+ vendor: materialize
+ uri:
postgresql://materialize@localhost:5441/materialize?sslmode=disable
+ experimental: false
- name: ParadeDB
service: paradedb-test
vendor: paradedb
@@ -356,7 +361,7 @@ jobs:
service: cedardb-test
vendor: cedardb
uri:
postgresql://localhost:5433/postgres?user=postgres&password=CedarDB2026%21
- experimental: true
+ experimental: false
steps:
- name: Free up disk space
run: |
diff --git
a/c/driver/postgresql/validation/queries-materialize/type/bind/decimal.txtcase
b/c/driver/postgresql/validation/queries-materialize/type/bind/decimal.txtcase
new file mode 100644
index 000000000..53180edff
--- /dev/null
+++
b/c/driver/postgresql/validation/queries-materialize/type/bind/decimal.txtcase
@@ -0,0 +1,24 @@
+// 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
+
+{"res": null}
+{"res": "-999.99"}
+{"res": "0"}
+{"res": "123.45"}
+{"res": "9999999.99"}
diff --git
a/c/driver/postgresql/validation/queries-materialize/type/bind/time_us.txtcase
b/c/driver/postgresql/validation/queries-materialize/type/bind/time_us.txtcase
new file mode 100644
index 000000000..dcb6e22da
--- /dev/null
+++
b/c/driver/postgresql/validation/queries-materialize/type/bind/time_us.txtcase
@@ -0,0 +1,23 @@
+// 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_time (
+ idx INT,
+ res TIME
+);
diff --git
a/c/driver/postgresql/validation/queries-materialize/type/bind/timestamp_ns.txtcase
b/c/driver/postgresql/validation/queries-materialize/type/bind/timestamp_ns.txtcase
new file mode 100644
index 000000000..56e335653
--- /dev/null
+++
b/c/driver/postgresql/validation/queries-materialize/type/bind/timestamp_ns.txtcase
@@ -0,0 +1,23 @@
+// 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)
+);
diff --git
a/c/driver/postgresql/validation/queries-materialize/type/bind/timestamptz_ns.txtcase
b/c/driver/postgresql/validation/queries-materialize/type/bind/timestamptz_ns.txtcase
new file mode 100644
index 000000000..8db0d3b99
--- /dev/null
+++
b/c/driver/postgresql/validation/queries-materialize/type/bind/timestamptz_ns.txtcase
@@ -0,0 +1,24 @@
+// 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
+);
diff --git
a/c/driver/postgresql/validation/queries-materialize/type/select/decimal.txtcase
b/c/driver/postgresql/validation/queries-materialize/type/select/decimal.txtcase
new file mode 100644
index 000000000..29fdc061c
--- /dev/null
+++
b/c/driver/postgresql/validation/queries-materialize/type/select/decimal.txtcase
@@ -0,0 +1,24 @@
+// 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
+
+{"res": "123.45"}
+{"res": "0"}
+{"res": "-999.99"}
+{"res": "9999999.99"}
+{"res": null}
diff --git
a/c/driver/postgresql/validation/queries-materialize/type/select/float32.txtcase
b/c/driver/postgresql/validation/queries-materialize/type/select/float32.txtcase
new file mode 100644
index 000000000..b6e9ad856
--- /dev/null
+++
b/c/driver/postgresql/validation/queries-materialize/type/select/float32.txtcase
@@ -0,0 +1,30 @@
+// 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_float32 (
+ idx INTEGER,
+ res REAL
+);
+
+INSERT INTO test_float32 (idx, res) VALUES (1, CAST('3.14' AS REAL));
+INSERT INTO test_float32 (idx, res) VALUES (2, CAST('0.0' AS REAL));
+INSERT INTO test_float32 (idx, res) VALUES (3, CAST('-3.4e38' AS REAL));
+INSERT INTO test_float32 (idx, res) VALUES (4, CAST('3.4e38' AS REAL));
+INSERT INTO test_float32 (idx, res) VALUES (5, CAST('1.175494351e-38' AS
REAL));
+INSERT INTO test_float32 (idx, res) VALUES (6, NULL);
diff --git
a/c/driver/postgresql/validation/queries-materialize/type/select/float64.txtcase
b/c/driver/postgresql/validation/queries-materialize/type/select/float64.txtcase
new file mode 100644
index 000000000..4db8390f9
--- /dev/null
+++
b/c/driver/postgresql/validation/queries-materialize/type/select/float64.txtcase
@@ -0,0 +1,30 @@
+// 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_float64 (
+ idx INTEGER,
+ res DOUBLE PRECISION
+);
+
+INSERT INTO test_float64 (idx, res) VALUES (1, CAST('3.14159265358979' AS
DOUBLE PRECISION));
+INSERT INTO test_float64 (idx, res) VALUES (2, CAST('0.0' AS DOUBLE
PRECISION));
+INSERT INTO test_float64 (idx, res) VALUES (3, CAST('-1.7976931348623157e308'
AS DOUBLE PRECISION));
+INSERT INTO test_float64 (idx, res) VALUES (4, CAST('1.7976931348623157e308'
AS DOUBLE PRECISION));
+INSERT INTO test_float64 (idx, res) VALUES (5, CAST('2.2250738585072014e-308'
AS DOUBLE PRECISION));
+INSERT INTO test_float64 (idx, res) VALUES (6, NULL);
diff --git
a/c/driver/postgresql/validation/queries-materialize/type/select/json.txtcase
b/c/driver/postgresql/validation/queries-materialize/type/select/json.txtcase
new file mode 100644
index 000000000..e61171d1b
--- /dev/null
+++
b/c/driver/postgresql/validation/queries-materialize/type/select/json.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: metadata
+
+[tags]
+sql-type-name = "jsonb"
+
+// part: expected
+
+{"res": null}
+{"res": "null"}
+{"res": "\"foobar\""}
+{"res": "1"}
+{"res": "true"}
+{"res": "[]"}
+{"res": "[\"spam\",\"eggs\",2.5,false]"}
+{"res": "{\"a\":12345,\"b\":\"hello\",\"c\":[1,2,3],\"d\":{\"e\":\"nested\"}}"}
+{"res": "[{\"id\":1,\"name\":\"Alice\"},{\"id\":2,\"name\":\"Bob\"}]"}
diff --git
a/c/driver/postgresql/validation/queries-materialize/type/select/jsonb.txtcase
b/c/driver/postgresql/validation/queries-materialize/type/select/jsonb.txtcase
new file mode 100644
index 000000000..a301f733a
--- /dev/null
+++
b/c/driver/postgresql/validation/queries-materialize/type/select/jsonb.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: expected
+
+{"res": null}
+{"res": "null"}
+{"res": "\"foobar\""}
+{"res": "1"}
+{"res": "true"}
+{"res": "[]"}
+{"res": "[\"spam\",\"eggs\",2.5,false]"}
+{"res": "{\"a\":12345,\"b\":\"hello\",\"c\":[1,2,3],\"d\":{\"e\":\"nested\"}}"}
+{"res": "[{\"id\":1,\"name\":\"Alice\"},{\"id\":2,\"name\":\"Bob\"}]"}
diff --git a/c/driver/postgresql/validation/tests/postgresql.py
b/c/driver/postgresql/validation/tests/postgresql.py
index 0dee33afc..85f99c1f7 100644
--- a/c/driver/postgresql/validation/tests/postgresql.py
+++ b/c/driver/postgresql/validation/tests/postgresql.py
@@ -69,7 +69,7 @@ class PostgreSQLQuirks(model.DriverQuirks):
)
@property
- def queries_paths(self) -> tuple[Path]:
+ def queries_paths(self) -> tuple[Path, ...]:
return (Path(__file__).parent.parent / "queries",)
def bind_parameter(self, index: int) -> str:
@@ -113,7 +113,7 @@ class CedarDBQuirks(PostgreSQLQuirks):
)
@property
- def queries_paths(self) -> tuple[Path]:
+ def queries_paths(self) -> tuple[Path, ...]:
return (
*super().queries_paths,
Path(__file__).parent.parent / "queries-cedardb",
@@ -139,7 +139,7 @@ class CockroachDBQuirks(PostgreSQLQuirks):
)
@property
- def queries_paths(self) -> tuple[Path]:
+ def queries_paths(self) -> tuple[Path, ...]:
return (
*super().queries_paths,
Path(__file__).parent.parent / "queries-cockroachdb",
@@ -164,8 +164,8 @@ class CrateDBQuirks(PostgreSQLQuirks):
)
@property
- def queries_paths(self) -> tuple[Path]:
- extra_paths: tuple[str] = ()
+ def queries_paths(self) -> tuple[Path, ...]:
+ extra_paths: tuple[Path, ...] = ()
if os.environ.get("POSTGRES_TYPE_RESOLVER_MODE") != "builtin":
extra_paths = (
Path(__file__).parent.parent / "queries-cratedb-typeresolver",
@@ -192,6 +192,28 @@ class CrateDBQuirks(PostgreSQLQuirks):
yield
+class MaterializeQuirks(PostgreSQLQuirks):
+ vendor_version = re.compile(r"905[0-9]{2}")
+ short_version = "9.5"
+ features = PostgreSQLQuirks.features.with_values(
+ # Materialize cannot decode the driver's text parameter as regclass.
+ connection_get_table_schema=False,
+ current_catalog="materialize",
+ # The table metadata query fails with "function unnest(text) does not
exist".
+ get_objects=False,
+ # COPY FROM only supports TEXT and CSV, while ingestion uses binary
COPY.
+ # https://materialize.com/docs/sql/copy-from/
+ statement_bulk_ingest=False,
+ )
+
+ @property
+ def queries_paths(self) -> tuple[Path, ...]:
+ return (
+ *super().queries_paths,
+ Path(__file__).parent.parent / "queries-materialize",
+ )
+
+
class ParadeDBQuirks(PostgreSQLQuirks):
pass
@@ -218,6 +240,7 @@ VENDORS = (
"citus",
"cockroachdb",
"cratedb",
+ "materialize",
"paradedb",
"timescaledb",
"yugabytedb",
@@ -230,6 +253,7 @@ _QUIRKS = {
"citus": CitusQuirks,
"cockroachdb": CockroachDBQuirks,
"cratedb": CrateDBQuirks,
+ "materialize": MaterializeQuirks,
"paradedb": ParadeDBQuirks,
"timescaledb": TimescaleDBQuirks,
"yugabytedb": YugabyteDBQuirks,
diff --git a/c/driver/postgresql/validation/tests/test_connection.py
b/c/driver/postgresql/validation/tests/test_connection.py
index e29253e20..5fb9cb649 100644
--- a/c/driver/postgresql/validation/tests/test_connection.py
+++ b/c/driver/postgresql/validation/tests/test_connection.py
@@ -33,11 +33,20 @@ class TestConnection(test_connection.TestConnection):
def test_get_objects_catalog(self, conn, driver) -> None:
if isinstance(driver, postgresql.CrateDBQuirks):
pytest.skip("GetObjects is marked unsupported for CrateDB")
+ if isinstance(driver, postgresql.MaterializeQuirks):
+ pytest.skip("GetObjects is marked unsupported for Materialize")
super().test_get_objects_catalog(conn, driver)
+ def test_get_objects_schema(self, conn, driver) -> None:
+ if isinstance(driver, postgresql.MaterializeQuirks):
+ pytest.skip("GetObjects is marked unsupported for Materialize")
+ super().test_get_objects_schema(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")
+ if isinstance(driver, postgresql.MaterializeQuirks):
+ pytest.skip("GetObjects is marked unsupported for Materialize")
super().test_get_objects_table_not_exist(conn, driver)
def test_get_objects_column_filter_table(
diff --git a/compose.yaml b/compose.yaml
index 2d02cb5a8..28d356b8d 100644
--- a/compose.yaml
+++ b/compose.yaml
@@ -479,6 +479,18 @@ services:
ports:
- "5440:5432"
+ materialize-test:
+ container_name: adbc_materialize_test
+ image: materialize/materialized:v26.41.1
+ healthcheck:
+ test: ["CMD", "curl", "--fail", "http://localhost:6878/api/readyz"]
+ interval: 10s
+ timeout: 5s
+ retries: 20
+ start_period: 60s
+ ports:
+ - "5441:6875"
+
spiceai-test:
container_name: adbc-spiceai
build:
diff --git a/docs/source/driver/postgresql.rst
b/docs/source/driver/postgresql.rst
index 002bfa223..0fb23cea5 100644
--- a/docs/source/driver/postgresql.rst
+++ b/docs/source/driver/postgresql.rst
@@ -359,6 +359,7 @@ the PostgreSQL wire protocol:
- CockroachDB
- CrateDB
- Google AlloyDB Omni
+- Materialize
- ParadeDB
- TimescaleDB
- YugabyteDB
@@ -372,7 +373,7 @@ vendors:
- CedarDB v2026-8-13 (unless the "builtin" type resolver is used, see above)
-The driver is not and will not support the following vendors:
+The driver does not and will not support the following vendors:
- Amazon Redshift (note that a dedicated driver is available for Redshift from
a third party, see :ref:`driver-table`)