Skip to content

feat: Add support for MATERIALIZED, EPHEMRAL and ALIAS expr columns in table definition #206

Description

@BrentonAD

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

  1. 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.
  2. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions