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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.

.claude/
src/build/
src/generated/
target/
.doit.db
validation-report.xml
60 changes: 60 additions & 0 deletions src/docs/clickhouse.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
# Copyright (c) 2026 ADBC Drivers Contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
{}
---

{{ cross_reference|safe }}
# ClickHouse Driver {{ version }}

{{ heading|safe }}

This driver provides access to [ClickHouse][clickhouse], an open-source data warehouse and analytical database.

## Installation

The ClickHouse driver can be installed with [dbc](https://docs.columnar.tech/dbc):

```bash
dbc install clickhouse
```

## Connecting

To use the driver, provide the URI of a ClickHouse database as the `uri` option.

```python
from adbc_driver_manager import dbapi

conn = dbapi.connect(
driver="clickhouse",
db_kwargs={
"uri": "http://localhost:8123/",
}
)
```

Note: The example above is for Python using the [adbc-driver-manager](https://pypi.org/project/adbc-driver-manager) package but the process will be similar for other driver managers.

## Feature & Type Support

{{ features|safe }}

### Types

{{ types|safe }}

{{ footnotes|safe }}

[clickhouse]:
107 changes: 107 additions & 0 deletions src/validation/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<!--
Copyright (c) 2026 ADBC Drivers Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

# Validation Tests Guide

## Task

Get validation tests passing using `pixi run validate`. Use `-k` to run a single test or pattern, e.g., `pixi run validate -k type/select/string`.

## Handling Test Failures

### Query-based tests (type/select, type/literal, type/bind, ingest)

1. **Override queries**: If ClickHouse requires different SQL syntax, create override query files in `./validation/queries/` using the `.txtcase` format.

2. **Mark as broken**: If a test cannot pass due to driver or vendor limitations, add to the metadata section:
- `[tags] broken-driver = "reason"` - for driver limitations
- `[tags] broken-vendor = "reason"` - for ClickHouse limitations

3. **Hide tests**: Use `hide = true` in metadata to completely hide irrelevant tests.

### Non-query tests (connection, statement)

Subclass the test class and add `@pytest.mark.xfail(reason="...")` decorator to the method.

## Override Query Format (.txtcase)

Override files go in `./validation/queries/` mirroring the structure in `adbc-drivers-validation`. Only include the parts you need to override.

```
// Copyright (c) 2026 ADBC Drivers Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// ...

// part: metadata

[setup]
drop = "test_tablename"

[tags]
sql-type-name = "TYPE"

// part: setup_query

CREATE TABLE ...

// part: query

SELECT ...

// part: expected_schema

{ JSON schema }

// part: expected

{ JSON data rows }
```

Parts map to file extensions:
- `metadata` -> .toml
- `setup_query` -> .setup.sql
- `query` -> .sql
- `expected_schema` -> .schema.json
- `expected` -> .json
- `bind_query` -> .bind.sql
- `bind_schema` -> .bind.schema.json
- `bind` -> .bind.json

## ClickHouse-Specific SQL Requirements

1. **Nullable columns**: Use `Nullable(Type)` wrapper, e.g., `Nullable(Int32)`
2. **Table engine**: Add `ENGINE = MergeTree() ORDER BY idx`
3. **Types**: Use ClickHouse type names (Int32, Int64, Bool, etc.)

## Workflow

1. Run the specific test to see the failure: `pixi run validate -k "type/select/int32"`
2. Check expected data in `~/Code/adbc-drivers-validation/adbc_drivers_validation/queries/`
3. Create override .txtcase file with correct data matching expected output
4. Test the query after creating each file
5. Move to next failing test

## Copyright Header

All new files must include the Apache 2.0 license header with copyright year 2026:

```
// Copyright (c) 2026 ADBC Drivers Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// ...
```
25 changes: 25 additions & 0 deletions src/validation/pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copyright (c) 2026 ADBC Drivers Contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

[pytest]
junit_suite_name = validation
junit_duration_report = call
xfail_strict = true

markers =
feature: test for a driver-specific feature

filterwarnings =
error
ignore:record_property is incompatible with junit_family:pytest.PytestWarning
19 changes: 19 additions & 0 deletions src/validation/queries/type/literal/binary.txtcase
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) 2026 ADBC Drivers Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// part: metadata

# Ignore this test: we need a SET statement and ClickHouse doesn't support
# multi-statement queries. Rely on type/select/binary instead.
hide = true
17 changes: 17 additions & 0 deletions src/validation/queries/type/literal/date.txtcase
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) 2026 ADBC Drivers Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// part: query

SELECT CAST('2023-05-15' AS Date32) AS res
22 changes: 22 additions & 0 deletions src/validation/queries/type/literal/time.txtcase
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) 2026 ADBC Drivers Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// part: query

SELECT CAST('13:45:31' AS TIME) AS res

// part: metadata

[tags]
broken-vendor = "ClickHouse Time type is not supported in Arrow format export"
39 changes: 39 additions & 0 deletions src/validation/queries/type/literal/timestamp.txtcase
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) 2026 ADBC Drivers Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// part: metadata

[tags]
caveats = ["ClickHouse datetime without timezone is interpreted in **server** timezone"]

// part: query

SELECT CAST('2023-05-15 13:45:30' AS DateTime64(6)) AS res

// part: expected_schema

{
"format": "+s",
"children": [
{
"name": "res",
"format": "tsu:UTC",
"flags": []
}
]
}

// part: expected

{"res": 1684158330000000}
17 changes: 17 additions & 0 deletions src/validation/queries/type/literal/timestamptz.txtcase
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) 2026 ADBC Drivers Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// part: query

SELECT CAST('2023-05-15 13:45:30' AS DateTime64(6, 'UTC')) AS res
31 changes: 31 additions & 0 deletions src/validation/queries/type/select/binary.txtcase
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) 2026 ADBC Drivers Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// part: metadata

[tags]
broken-vendor = "ClickHouse has no dedicated bytestring type; it is the same as the string type, and by default all strings are treated as Arrow strings, meaning binary data in ClickHouse results in invalid string data in Arrow"

// part: setup_query

CREATE TABLE test_binary (
idx Int32,
res Nullable(String)
) ENGINE = MergeTree() ORDER BY idx;

INSERT INTO test_binary (idx, res) VALUES (1, unhex('e38193e38293e381abe381a1e381afe38081e4b896e7958cefbc81'));
INSERT INTO test_binary (idx, res) VALUES (2, unhex('00'));
INSERT INTO test_binary (idx, res) VALUES (3, unhex('deadbeef'));
INSERT INTO test_binary (idx, res) VALUES (4, unhex(''));
INSERT INTO test_binary (idx, res) VALUES (5, NULL);
24 changes: 24 additions & 0 deletions src/validation/queries/type/select/boolean.txtcase
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) 2026 ADBC Drivers Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// part: setup_query

CREATE TABLE test_boolean (
idx Int32,
res Nullable(Bool)
) ENGINE = MergeTree() ORDER BY idx;

INSERT INTO test_boolean (idx, res) VALUES (1, TRUE);
INSERT INTO test_boolean (idx, res) VALUES (2, FALSE);
INSERT INTO test_boolean (idx, res) VALUES (3, NULL);
Loading
Loading