Summary
The schema DSL has no way to declare a column with a MATERIALIZED expression. ClickHouse allows DEFAULT | MATERIALIZED | EPHEMERAL | ALIAS expr per column (docs). Currently only DEFAULT is supported.
MATERIALIZED is not interchangeable with DEFAULT:
MATERIALIZED — always computed and stored; cannot be supplied on INSERT.
DEFAULT — applied only when the value is omitted; can be overridden.
So there is currently no way to express a derived, insert-immutable column, e.g. Date Date MATERIALIZED toDate(Datetime).
Like-wise for EPHEMERAL and ALIAS
Current Behaviour:
Embedding it in the type str as a workaround:
{"name": "Date", "type": "Date MATERIALIZED toDate(Datetime)"}
emits valid DDL on the first migrate, but does not round-trip:
introspect captures a column's default expression only when default_kind == "DEFAULT". A live MATERIALIZED column reports default_kind == "MATERIALIZED", so the expression is dropped and type is read back as the base Date.
- generate / drift then compare schema "Date MATERIALIZED toDate(Datetime)" vs live "Date" and an ALTER MODIFY COLUMN is emitted on every run.
Net: the workaround silently breaks drift detection for that column.
Proposed
- Add
default_kind: Literal["DEFAULT", "MATERIALIZED", "ALIAS", "EPHEMERAL"] = "DEFAULT" (alias defaultKind) to ColumnDefinition. default holds the expression.
- Render as
`col` <type> <default_kind> <expr>
- Drop introspect's default_kind == "DEFAULT" filter so all kinds round-trip.
Caveats
- Expressions must render unquoted. MATERIALIZED/ALIAS/EPHEMERAL values are SQL expressions, hence they need the raw-expression path, or
toDate(Datetime) gets emitted as a quoted string.
- Keep existing snapshots stable. Introducing the kind into a column's comparison identity would make the first diff after upgrade rewrite every existing column. Treat an absent/
DEFAULT kind as identical to today so unchanged columns don't churn.
Version chkit-py 0.2.0
Summary
The schema DSL has no way to declare a column with a
MATERIALIZEDexpression. ClickHouse allowsDEFAULT | MATERIALIZED | EPHEMERAL | ALIAS exprper column (docs). Currently onlyDEFAULTis supported.MATERIALIZEDis not interchangeable withDEFAULT:MATERIALIZED— always computed and stored; cannot be supplied onINSERT.DEFAULT— applied only when the value is omitted; can be overridden.So there is currently no way to express a derived, insert-immutable column, e.g.
Date Date MATERIALIZED toDate(Datetime).Like-wise for
EPHEMERALandALIASCurrent Behaviour:
Embedding it in the type str as a workaround:
{"name": "Date", "type": "Date MATERIALIZED toDate(Datetime)"}emits valid DDL on the first migrate, but does not round-trip:
introspectcaptures a column's default expression only whendefault_kind== "DEFAULT". A liveMATERIALIZEDcolumn reports default_kind == "MATERIALIZED", so the expression is dropped and type is read back as the base Date.Net: the workaround silently breaks drift detection for that column.
Proposed
default_kind: Literal["DEFAULT", "MATERIALIZED", "ALIAS", "EPHEMERAL"] = "DEFAULT"(aliasdefaultKind) toColumnDefinition.defaultholds the expression.`col` <type> <default_kind> <expr>Caveats
toDate(Datetime)gets emitted as a quoted string.DEFAULTkind as identical to today so unchanged columns don't churn.Version chkit-py 0.2.0