`mode=cluster`'s `ON CLUSTER` injection doesn't apply to dev-database schema materialization — breaks the `{uuid}` macro in replicated engine paths
Versions
- Atlas CLI:
v1.3.1-629a976-canary - ClickHouse server:
26.7.3.19(official build) - Topology: two independent 2-node ClickHouse clusters (both named
main, 1 shard / 2 replicas, each with its own ClickHouse Keeper) — one used asdev, one asurl
atlas.hcl
env "local" {
src = "file://schema"
dev = "clickhouse://default@dev-host:9000/imports?mode=cluster"
url = "clickhouse://default@target-host:9000/imports?mode=cluster"
}schema.sql
CREATE TABLE t_local (
id UInt64
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{cluster}/{shard}/{uuid}', '{replica}')
ORDER BY id;Command
atlas schema lint --env local
(Same result with atlas schema apply --env local.)
Actual result
Error: schema.sql:2: code: 36, message: Macro 'uuid' in engine arguments is only
supported when the UUID is explicitly specified, used within an ON CLUSTER query,
or when using the Replicated database engineExpected result
Either the statement applies cleanly (per docs, mode=cluster is documented to handle "replicated engines" on a clustered dev database), or the limitation is documented.
What we found
The error is a genuine ClickHouse exception (code: 36, BAD_ARGUMENTS), not an Atlas-side validation error — Atlas is relaying it. Comparing system.query_log on both dev nodes for an ordinary table (no {uuid}), applied repeatedly:
The dev-node connection receives the CREATE TABLE verbatim from the schema file — no ON CLUSTER clause, not even the {cluster} macro form, every time. The second dev node never receives the statement at all.
So under mode=cluster, ON CLUSTER injection appears to apply only to the DDL Atlas ultimately generates against url (target) — never to the statements it runs against dev to materialize/inspect schema state for lint and for diff computation during apply. Since ClickHouse only allows a bare {uuid} macro in engine arguments when the statement is explicit-UUID'd, ON CLUSTER'd, or using the Replicated database engine, the un-wrapped dev-side statement is rejected before target-side plan generation (where ON CLUSTER is correctly present) is ever reached.
Workaround found
Writing ON CLUSTER {cluster} explicitly in the schema file's CREATE TABLE (redundant with what mode=cluster injects for target) passes through unmodified to dev too, where ClickHouse's own distributed-DDL mechanism then satisfies the requirement. No double-ON CLUSTER was observed when both the explicit clause and mode=cluster's injection were in play simultaneously — but this shouldn't be necessary given the documented behavior of mode=cluster.
Source: ariga/atlas