Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
7e332eb
fix(types): refuse a non-boolean unsigned when the type is rendered
vistart Oct 11, 2026
88b9e30
refactor(clickhouse): follow the statement and expression renames
vistart Oct 14, 2026
091a21a
refactor(clickhouse): migrate constraints onto the two-level branch n…
vistart Oct 14, 2026
38cc428
fix(clickhouse): converge the constraint switches onto the (self) pro…
vistart Oct 14, 2026
b62a829
refactor(clickhouse): split the wildcard by grammar position
vistart Oct 14, 2026
0ee1691
test(clickhouse): bring the roundtrip matrix up to the branch nodes a…
vistart Oct 14, 2026
b46dd7f
ci: point testsuite at the matching branch
vistart Oct 14, 2026
5b51d1b
fix(clickhouse): annotate the CTE override with the node it renders
vistart Oct 14, 2026
76e72a5
refactor(clickhouse): follow the core expression renames and word-for…
vistart Oct 16, 2026
10404f2
refactor(clickhouse): read declared fields instead of probing with ge…
vistart Oct 17, 2026
5103107
feat(clickhouse): adopt the typed value nodes with ClickHouse literal…
vistart Oct 17, 2026
fc59dc4
fix(clickhouse): follow the classed function entry points and the bar…
vistart Oct 18, 2026
15a4bf0
refactor(clickhouse): follow the literal architecture the core settled
vistart Oct 18, 2026
bebc428
test(clickhouse): reconcile the roundtrip matrix with the plain-JSON …
vistart Oct 19, 2026
b9742c4
refactor(clickhouse): audit the kinds this backend overrides and owns
vistart Oct 19, 2026
52372b0
test(clickhouse): move live-connection checks out of expression tests
vistart Oct 19, 2026
4d48232
test(clickhouse): reconcile the roundtrip matrix with the value and f…
vistart Oct 19, 2026
7e10233
fix(clickhouse): let the ADD COLUMN position clause reach the SQL
vistart Oct 19, 2026
8604c14
fix(clickhouse): gate the WITH DATA duo only when a spelling is reque…
vistart Oct 19, 2026
46d532d
fix(clickhouse): vendor the parse round-trip sweep beside the roundtr…
vistart Oct 19, 2026
be5fd18
fix(clickhouse): pass the LIKE operator as its enum, not the SQL keyword
vistart Oct 20, 2026
e336db1
refactor(clickhouse): build introspection queries from nodes, not text
vistart Oct 20, 2026
6443c8e
refactor(clickhouse): render SHOW through its own expressions
vistart Oct 20, 2026
dbf67d7
fix(clickhouse): import the status nodes from the package that holds …
vistart Oct 20, 2026
205d250
test(expression): re-measure the non-roundtrip pins after the core en…
vistart Oct 20, 2026
af308f3
chore: ignore .worktree/, the branch toolchain directories
vistart Oct 21, 2026
777f823
fix(clickhouse): refuse the ALTER DATABASE ... RENAME TO ClickHouse h…
vistart Oct 21, 2026
b2953f7
fix(clickhouse): the dialect surface, and the type positions it decides
vistart Oct 22, 2026
53eae61
refactor(expression)!: follow core's statement rename
vistart Oct 22, 2026
7740462
refactor(show)!: SHOW CREATE TABLE is a statement
vistart Oct 22, 2026
03c311c
feat(clickhouse)!: declare CREATE TABLE storage clauses as expression…
vistart Oct 22, 2026
7113d56
fix(clickhouse): build the fixture tables from the storage-clause nodes
vistart Oct 22, 2026
caa4aed
refactor(expression)!: name statement nodes, kinds and formatters alike
vistart Oct 23, 2026
6d13310
refactor(backend)!: call the core helpers by their public names
vistart Oct 23, 2026
c36404e
fix(introspection): take the cache from the manager, not the mixin
vistart Oct 23, 2026
38ab512
feat(introspection): read ClickHouse's partitions and a table's stora…
vistart Oct 23, 2026
ba8856a
docs(cli): say what introspect can ask about
vistart Oct 24, 2026
61ae8c4
refactor(cli): name the namespace after the engine, not after the slot
vistart Oct 24, 2026
4a7e017
fix(cli): stop offering the two families ClickHouse says it cannot an…
vistart Oct 24, 2026
bddabb8
feat(introspection): declare Firebird's catalogue capabilities
vistart Oct 24, 2026
3114142
revert(cli): let ClickHouse name its own introspection types
vistart Oct 24, 2026
2d4d91d
refactor(clickhouse)!: drop the underscores from the introspection co…
vistart Oct 25, 2026
abd02d1
feat(cli)!: the introspect table aggregate is gone
vistart Oct 26, 2026
ccce0d1
fix(introspection): report the relation kind and what the server answers
vistart Oct 27, 2026
39d5a02
fix(cli): introspect --async calls the methods the audit introspector…
vistart Oct 30, 2026
9645c58
feat(cli): a catalogue family takes an optional name
vistart Oct 30, 2026
44c4c78
feat(cli): the introspect types come with their capability switches
vistart Oct 30, 2026
4c66b93
docs(cli): seven introspect types, and what this engine does not have
vistart Oct 30, 2026
627f131
fix(cli): introspect --async refuses instead of raising out of the pl…
vistart Oct 30, 2026
c6295e1
ci: install core from the release branch now that #127 has merged
vistart Oct 30, 2026
ae42de3
docs(changelog): the fragments for #6
vistart Oct 31, 2026
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
20 changes: 3 additions & 17 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,24 +69,10 @@ jobs:
pip install -r requirements.txt
pip install -r requirements-dev.txt

- name: Check out activerecord and testsuite (release branches)
uses: actions/checkout@v6
with:
repository: rhosocial/python-activerecord
ref: release/v1.0.0.dev30
path: _activerecord

- name: Check out testsuite (release branch)
uses: actions/checkout@v6
with:
repository: rhosocial/python-activerecord-testsuite
ref: release/v1.0.0.dev17
path: _testsuite

- name: Install activerecord and testsuite (editable)
- name: Install activerecord and testsuite
run: |
pip install -e ./_activerecord
pip install -e ./_testsuite
pip install "rhosocial-activerecord @ git+https://github.com/rhosocial/python-activerecord.git@release/v1.0.0.dev30"
pip install "rhosocial-activerecord-testsuite @ git+https://github.com/rhosocial/python-activerecord-testsuite.git@fix/column-constraint-gates"

- name: Verify ClickHouse connectivity
run: |
Expand Down
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -213,4 +213,9 @@ tests/config/clickhouse_scenarios.yml

# Claude Code temporary files (local only)
.claude/tmp/
.claude/plan*/
.claude/plan*/
# Worktrees for feature/* and fix/* branches. Never tracked: a `git add -A`
# from the repo root would commit each branch's whole toolchain -- the venv, the
# build directory and the test artifacts -- and the directory disappears when the
# branch merges, so the history would keep a second copy of the source tree.
.worktree/
8 changes: 8 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ and raise `UnsupportedFeatureError` instead of being emulated:
- Mutations run with `mutations_sync=1`; `affected_rows` for UPDATE/DELETE is a
pre-count of rows matching the WHERE predicate.
- Optional model fields must map to `Nullable(T)` columns.
- The CLI's `introspect` offers exactly seven types — `tables`, `views`,
`columns`, `indexes`, `partitions`, `table-engine`, `database` — and each is
gated on a dialect `supports_*` switch (exit 2 when the connected server
answers False). `foreign-keys` / `triggers` are absent from the vocabulary
because the engine has neither, which is a different statement from a
capability switch. The SHOW passthrough (`introspector.show`, 19 methods) is
library-only and deliberately not wired into `introspect`: SHOW and
`system.*` are not equivalent, and every introspect type reads `system.*`.

## Python Version Support

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ from pydantic import Field
from rhosocial.activerecord.base import FieldProxy
from rhosocial.activerecord.backend.impl.clickhouse.backend import ClickHouseBackend
from rhosocial.activerecord.backend.impl.clickhouse.config import ClickHouseConnectionConfig
from rhosocial.activerecord.backend.expression import CreateTableExpression
from rhosocial.activerecord.backend.expression import CreateTableStatement
from rhosocial.activerecord.backend.expression.statements import ColumnDefinition
from rhosocial.activerecord.backend.expression.types import IntegerType, VarCharType
from rhosocial.activerecord.model import ActiveRecord
Expand Down Expand Up @@ -80,7 +80,7 @@ User.configure(
)

dialect = User.__backend__.dialect
User.__backend__.execute(*CreateTableExpression(
User.__backend__.execute(*CreateTableStatement(
dialect,
"users",
columns=[
Expand Down
1 change: 1 addition & 0 deletions changelog.d/6.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
`partitions` and `table-engine` on the introspect CLI, `views NAME`, and storage clauses (`ENGINE`, `ORDER BY`, `PARTITION BY`, `TTL`) as expression nodes.
1 change: 1 addition & 0 deletions changelog.d/6.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The introspect type list excludes `foreign-keys` and `triggers` because the engine has neither, and derives the rest from `_TYPE_CAPABILITIES`. `--async` is refused with a sentence rather than reached.
1 change: 1 addition & 0 deletions changelog.d/6.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The async introspect handler called five methods no introspector class has; the relation kind is reported as the server answers it.
1 change: 1 addition & 0 deletions changelog.d/6.internal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The CLI tests exercise every declared type in both paths, and CI installs core from `release/v1.0.0.dev30` now that core #127 has merged.
11 changes: 9 additions & 2 deletions docs/en_US/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,18 @@ Introspect the schema via `system.*` tables.
```bash
$ python -m rhosocial.activerecord.backend.impl.clickhouse introspect tables \
--host localhost --database test_db --user root --password password

$ python -m rhosocial.activerecord.backend.impl.clickhouse introspect views daily_totals \
--host localhost --database test_db --user root --password password
```

Positional argument (introspection type): `tables`/`views`/`table`/`columns`/`indexes`/`foreign-keys`/`triggers`/`database`. `foreign-keys`/`triggers` return empty for ClickHouse (not supported).
Positional argument (introspection type): `tables` / `views` / `columns` / `indexes` / `partitions` / `table-engine` / `database`.

`NAME` is a table for `columns` / `indexes` / `partitions` / `table-engine`, and the view itself for `views`. `tables` / `database` answer for the whole database and **refuse** a name (exit 2) rather than print a listing that looks narrowed. Exit 1 means the run failed — a connection or query error, or a view name that does not exist.

`foreign-keys` / `triggers` are not offered at all: ClickHouse has neither, so the type is absent from this backend's vocabulary instead of being answered with an empty list. Every offered type is gated on a dialect capability switch; a server that answers `False` for it is refused with exit 2 and `Error: <type> introspection is not supported by this server`. The backend's `show.*` SHOW passthrough is not exposed here either: `SHOW` and `system.*` are not equivalent, and every introspection type reads `system.*`.

Specific arguments: `--schema SCHEMA`, `--include-system` (include system tables).
Specific arguments: `--include-system` (include system tables).

## status — server status

Expand Down
149 changes: 104 additions & 45 deletions docs/en_US/ddl/table_engine.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

ClickHouse DDL consists of clauses such as `ENGINE`, `ORDER BY`, `PARTITION BY`, `TTL`, `PRIMARY KEY`, `SAMPLE BY`, and `SETTINGS`. This backend supports them natively at the dialect layer and can generate them through the core library's DDL expressions — **full SQL semantic coverage**, no hand-written SQL required.

> 📐 This backend inherits and extends the core library's `CreateTableExpression`: declaring ClickHouse clauses through the `storage_options` dictionary, with `to_sql()` generating complete native ClickHouse DDL.
> 📐 This backend extends the core library's `CreateTableStatement` with its own options node: the clauses are declared as **expression nodes** on `ClickHouseCreateTableOptions(table_storage_options=...)`, and `to_sql()` generates complete native ClickHouse DDL.

## MergeTree Family

Expand All @@ -29,16 +29,15 @@ The backend maps the model's `__primary_key__` to the `ORDER BY` sorting key.

## DDL Expression vs Raw SQL Comparison

Both approaches generate **exactly the same** ClickHouse DDL, demonstrating that the expressions cover all SQL semantics:
Both approaches produce the **same** ClickHouse DDL, demonstrating that the expressions cover the SQL semantics:

### Raw SQL

```sql
CREATE TABLE IF NOT EXISTS events (
ts DateTime64(6, 'UTC'),
ts DateTime64(6),
id Int64,
url String,
INDEX idx_url url TYPE bloom_filter GRANULARITY 4
url String
) ENGINE = MergeTree
PARTITION BY toYYYYMM(ts)
ORDER BY (ts, id)
Expand All @@ -49,52 +48,107 @@ SETTINGS enable_block_number_column = 1, enable_block_offset_column = 1;
### DDL Expression (equivalent)

```python
from rhosocial.activerecord.backend.expression.core import Column, FunctionCall
from rhosocial.activerecord.backend.expression.objects import Table
from rhosocial.activerecord.backend.expression.operators import RawSQL
from rhosocial.activerecord.backend.expression.statements import (
CreateTableExpression, ColumnDefinition, IndexDefinition,
ColumnDefinition,
CreateTableStatement,
)
from rhosocial.activerecord.backend.expression.parts import IndexType
from rhosocial.activerecord.backend.impl.clickhouse.expression import (
ClickHouseInt64Type, ClickHouseStringType, ClickHouseDateTime64Type,
ClickHouseCreateTableOptions,
ClickHouseDateTime64Type,
ClickHouseEngineSpec,
ClickHouseInt64Type,
ClickHouseSetting,
ClickHouseStorageOptionKind,
ClickHouseStringType,
ClickHouseTableStorageOption,
)

expr = CreateTableExpression(
dialect=dialect,
table="events",
columns=[
ColumnDefinition(name="ts", data_type=ClickHouseDateTime64Type(6)),
ColumnDefinition(name="id", data_type=ClickHouseInt64Type()),
ColumnDefinition(name="url", data_type=ClickHouseStringType()),
kind = ClickHouseStorageOptionKind

storage = [
ClickHouseTableStorageOption(
dialect, kind.ENGINE, value=ClickHouseEngineSpec(dialect, "MergeTree")
),
ClickHouseTableStorageOption(
dialect,
kind.PARTITION_BY,
value=[FunctionCall(dialect, "toYYYYMM", Column(dialect, "ts"))],
),
ClickHouseTableStorageOption(
dialect, kind.ORDER_BY, value=[Column(dialect, "ts"), Column(dialect, "id")]
),
ClickHouseTableStorageOption(
dialect, kind.TTL, value=RawSQL(dialect, "ts + INTERVAL 90 DAY DELETE")
),
ClickHouseTableStorageOption(
dialect,
kind.SETTINGS,
value=[
ClickHouseSetting(dialect, "enable_block_number_column", 1),
ClickHouseSetting(dialect, "enable_block_offset_column", 1),
],
),
]

expr = CreateTableStatement(
dialect,
Table(dialect, "events"),
[
ColumnDefinition(dialect, "ts", ClickHouseDateTime64Type(dialect, precision=6)),
ColumnDefinition(dialect, "id", ClickHouseInt64Type(dialect)),
ColumnDefinition(dialect, "url", ClickHouseStringType(dialect)),
],
indexes=[
IndexDefinition(name="idx_url", columns=["url"], index_type="bloom_filter",
dialect_options={"granularity": 4}),
],
storage_options={
"ENGINE": "MergeTree",
"PARTITION BY": "toYYYYMM(ts)",
"ORDER BY": ["ts", "id"],
"TTL": "ts + INTERVAL 90 DAY DELETE",
"SETTINGS": "enable_block_number_column = 1, enable_block_offset_column = 1",
},
if_not_exists=True,
table_options=ClickHouseCreateTableOptions(dialect, table_storage_options=storage),
)
sql, _ = expr.to_sql() # 与上方原始 SQL 等价
dialect.execute(sql)
sql, params = expr.to_sql()
dialect.execute(sql, params)
```

Generated SQL (one line; ClickHouse accepts either form):

```sql
CREATE TABLE IF NOT EXISTS `events` (`ts` DateTime64(6), `id` Int64, `url` String)
ENGINE = MergeTree PARTITION BY TOYYYYMM(`ts`) ORDER BY (`ts`, `id`)
TTL ts + INTERVAL 90 DAY DELETE
SETTINGS enable_block_number_column = 1, enable_block_offset_column = 1
```

### Supported `storage_options` keys
## Storage Clause Nodes

One clause is one `ClickHouseTableStorageOption`. Which payload shape it takes is decided by its `option` member, and the renderer owns the keyword — the caller never writes SQL text for a clause:

| `option` | `value` | renders as |
|-----|--------|--------|
| `ENGINE` | `ClickHouseEngineSpec` | `ENGINE = MergeTree`, `ENGINE = ReplacingMergeTree(version)` |
| `PRIMARY KEY` | list of expression nodes | `PRIMARY KEY (a, b)` |
| `PARTITION BY` | list of expression nodes | `PARTITION BY toYYYYMM(ts)` |
| `ORDER BY` | list of expression nodes | `ORDER BY (ts, id)` |
| `SAMPLE BY` | one expression node | `SAMPLE BY cityHash64(user_id)` |
| `TTL` | one expression node | `TTL ts + INTERVAL 90 DAY DELETE` |
| `SETTINGS` | list of `ClickHouseSetting` | `SETTINGS index_granularity = 8192` |

`format_table_engine_clauses` accepts (case/underscore insensitive, values inserted as-is):
Three rules the renderer enforces:

| key | renders as |
|-----|--------|
| `ENGINE` | `ENGINE = <value>` |
| `ORDER BY` | `ORDER BY (col1, col2)` |
| `PARTITION BY` | `PARTITION BY <expr>` |
| `PRIMARY KEY` | `PRIMARY KEY (...)` |
| `SAMPLE BY` | `SAMPLE BY <expr>` |
| `TTL` | `TTL <expr>` |
| `SETTINGS` | `SETTINGS k = v, ...` |
- **Canonical order.** Clauses are emitted in ClickHouse's grammar order (`ENGINE` → `PRIMARY KEY` → `PARTITION BY` → `ORDER BY` → `SAMPLE BY` → `TTL` → `SETTINGS`) regardless of the order you declared them in.
- **One clause, once.** Declaring the same `option` twice raises `ValueError` at construction instead of rendering a statement ClickHouse would reject.
- **A single node needs no parentheses.** `ORDER BY id` and `ORDER BY (ts, id)` are both valid; the renderer parenthesises only when there is more than one expression.

`ON CLUSTER` is not a storage clause: it sits between the table name and the column list, so it is declared on the options node next to the clauses:

```python
table_options=ClickHouseCreateTableOptions(
dialect,
on_cluster="analytics_cluster",
table_storage_options=storage,
)
# CREATE TABLE `events` ON CLUSTER `analytics_cluster` (...) ENGINE = MergeTree ...
```

> ⚠️ The core `CreateTableStatement(storage_options=...)` slot is **refused by name** in this backend: ClickHouse has no generic `WITH (...)` storage-options clause, and accepting the dict would render a statement that silently differs from what the caller wrote. The error names `ClickHouseCreateTableOptions` as the replacement.

> 💡 *AI prompt: "`ReplacingMergeTree` dedup is eventually consistent; how does the caller ensure it reads the latest version when querying? What is the cost of the `FINAL` keyword?"*

Expand All @@ -119,17 +173,22 @@ Expired data is automatically deleted; commonly used for log/event tables.
This backend supports `ALTER TABLE` ADD/DROP COLUMN (including `IF EXISTS`/`IF NOT EXISTS`), MODIFY COLUMN, etc.:

```python
from rhosocial.activerecord.backend.expression.objects import Table
from rhosocial.activerecord.backend.expression.statements import (
AlterTableExpression, AlterColumn, ColumnAlterOperation,
AddColumnAction, AlterTableStatement, ColumnDefinition,
)
from rhosocial.activerecord.backend.impl.clickhouse.expression import ClickHouseStringType

expr = AlterTableStatement(
dialect,
Table(dialect, "events"),
[AddColumnAction(dialect, ColumnDefinition(dialect, "country", ClickHouseStringType(dialect)))],
)
expr = AlterTableExpression(dialect, "users", [
AlterColumn("col", ColumnAlterOperation.SET_DEFAULT, new_value="ABC"),
])
sql, _ = expr.to_sql()
# ALTER TABLE users ALTER COLUMN col SET DEFAULT 'ABC'
# ALTER TABLE `events` ADD COLUMN `country` String
```

See the DDL comparison in [First CRUD application](../getting_started/first_crud.md).
See the DDL comparison in [First CRUD application](../getting_started/first_crud.md), and [Skip indexes](skip_indexes.md) for inline `INDEX` clauses.

## Next steps

Expand Down
6 changes: 3 additions & 3 deletions docs/en_US/getting_started/first_crud.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,22 +44,22 @@ User.configure(config, ClickHouseBackend)
## 2. Create the table (DDL expression vs raw SQL)

ClickHouse does not auto-create tables. This backend **inherits and extends** the
core library's DDL expressions: `CreateTableExpression` can generate complete
core library's DDL expressions: `CreateTableStatement` can generate complete
native ClickHouse DDL. The two approaches are equivalent:

### Approach A: DDL expression (recommended, type-safe, serializable)

```python
from rhosocial.activerecord.backend.expression.statements import (
CreateTableExpression, ColumnDefinition, DropTableExpression,
CreateTableStatement, ColumnDefinition, DropTableStatement,
)
from rhosocial.activerecord.backend.impl.clickhouse.expression import (
ClickHouseInt64Type, ClickHouseStringType, ClickHouseInt32Type,
ClickHouseNullableType, ClickHouseDateTime64Type,
)

# Declare ENGINE / ORDER BY / PARTITION BY / TTL / SETTINGS via storage_options
expr = CreateTableExpression(
expr = CreateTableStatement(
dialect=User.__dialect__,
table="users",
columns=[
Expand Down
2 changes: 1 addition & 1 deletion docs/en_US/getting_started/quick_start.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ SETTINGS enable_block_number_column = 1, enable_block_offset_column = 1;
> mutations by default. See [Mutations (UPDATE/DELETE)](../capabilities/mutations.md).
>
> You can also generate the equivalent DDL via a DDL expression
> (`CreateTableExpression` + `storage_options`); see
> (`CreateTableStatement` + `storage_options`); see
> [First CRUD application](first_crud.md#2-create-the-table-ddl-expression-vs-raw-sql).

## Key points
Expand Down
11 changes: 9 additions & 2 deletions docs/zh_CN/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,18 @@ $ python -m rhosocial.activerecord.backend.impl.clickhouse info \
```bash
$ python -m rhosocial.activerecord.backend.impl.clickhouse introspect tables \
--host localhost --database test_db --user root --password password

$ python -m rhosocial.activerecord.backend.impl.clickhouse introspect views daily_totals \
--host localhost --database test_db --user root --password password
```

位置参数(自省类型):`tables`/`views`/`table`/`columns`/`indexes`/`foreign-keys`/`triggers`/`database`。`foreign-keys`/`triggers` 对 ClickHouse 返回空(不支持)。
位置参数(自省类型):`tables` / `views` / `columns` / `indexes` / `partitions` / `table-engine` / `database`。

`NAME` 对 `columns` / `indexes` / `partitions` / `table-engine` 是表名,对 `views` 是视图本身。`tables` / `database` 回答的是整个数据库,因此**拒绝**名字(退出 2),不会打印一份看起来被收窄过的列表。退出 1 表示运行失败——连接或查询出错,或指定的视图不存在。

`foreign-keys` / `triggers` 根本不提供:ClickHouse 既没有外键也没有触发器,所以这两个类型不在本后端的词汇表里,而不是返回空列表。每个提供的类型都挂在 dialect 的能力开关上;服务端对该开关回答 `False` 时以退出 2 拒绝,并输出 `Error: <type> introspection is not supported by this server`。后端的 `show.*`(SHOW 直通)同样不从这里暴露:`SHOW` 与 `system.*` 并不等价,而所有自省类型都读 `system.*`。

专属参数:`--schema SCHEMA`、`--include-system`(含系统表)。
专属参数:`--include-system`(含系统表)。

## status — 服务器状态

Expand Down
Loading
Loading