Repository navigation
Closed
Labels
enhancementNew feature or requestNew feature or request
Description
Sub-issue of #660 — feature-parity tracking for the ClickHouse adapter in dbt Core 2.0 / Fusion versus the Python dbt-clickhouse adapter.
Covers the materialized_view materialization, separated by (EX)plicit and (IM)plicit target variants. Creation paths (base create, derivative, catchup, refreshable clause, external targets, multi-MV create, MODIFY QUERY updates) and the re-run intelligence (refresh-schedule updates, MV-target protection, multi-MV update/rename, on_schema_change, refreshable: false) work on main (dbt-labs/dbt#15507, #16200): the materialization is done for v1 parity. The proper upstream multi-MV design and the refreshable catch-up ordering fix are ⚪️ future work (#731).
Status legend:
- ✅ implemented — merged and working on dbt-core 2.0 origin/main
- 🟡 partial — partly working on origin/main; Notes say what works vs fails
- 🚧 in progress — implemented in an open PR (linked in Notes)
- 🔴 not started — not working anywhere
- ⚪️ future work — explicitly deferred, not being solved now (also listed in the future-work sub-issue)
| Feature | Subfeatures / details | Status | Notes (PR) |
|---|---|---|---|
Materialization: materialized_view |
(overall) | ✅ | dbt-labs/dbt#15507 (create paths, MODIFY QUERY, refreshable clause, catchup, external targets) + dbt-labs/dbt#16200 (refresh-schedule updates, target protection, multi-MV updates, on_schema_change, refreshable: false). Deferred: refreshable catch-up ordering (#731) |
| Base create (MV + target table) | Creates the MV and its target in implicit mode | ✅ | dbt-labs/dbt#15507 |
(IM)relation.derivative(suffix, type, …) |
Rust relation method used to derive the <model>_mv relation |
✅ | dbt-labs/dbt#15507, with unit tests |
catchup config |
Default/True backfill; False = empty target + live trigger | ✅ | dbt-labs/dbt#15507. catchup=false on a model that also declares projections via dbt-labs/dbt#16200 |
refreshable config (map form) |
{interval, randomize, append, depends_on, depends_on_validation} → REFRESH clause at CREATE time |
✅ | dbt-labs/dbt#15507. Changing the schedule of an existing MV is the lifecycle row below |
refreshable.depends_on_validation |
Existence check of dependencies via system.view_refreshes |
✅ | validate_refreshable_mv_existence |
| MV update/replace on re-run | ALTER TABLE … MODIFY QUERY for a changed SELECT; drop+create fallback |
✅ | dbt-labs/dbt#15507. Refresh parameters and mv_on_schema_change/repopulate are the rows below |
| External target table | materialization_target_table(ref(...)) |
✅ | Create, MODIFY QUERY re-run, live propagation and catchup insert work; changing the TO target errors with a --full-refresh hint. Target-change validation and query-only updates via mvs_pointing_to_it + can_exchange (dbt-labs/dbt#16200) |
| Auto-drop of auto-created MV on materialization switch | Model changes from materialized_view to view → leftover <model>_mv dropped, non-dbt MVs get a warning |
✅ | clickhouse__drop_associated_mv_if_it_was_automatically_created, called from view.sql. Same limitations as v1: single-MV, current database only |
| Refreshable MV re-run lifecycle | ALTER TABLE … MODIFY REFRESH on re-run (upstream #611); errors for in-place regular↔refreshable and APPEND↔non-APPEND transitions |
✅ | dbt-labs/dbt#16200 (clickhouse__modify_mv_refresh + is_refreshable/refreshable_append relation state) |
refreshable: false (bare bool form) |
false behaves exactly like omitting the key; bare true must keep erroring "must be a dictionary" (v1 parity) |
✅ | dbt-labs/dbt#16200 (RefreshableConfig bool|map + the macro guard) |
| Refreshable MV catch-up vs the first refresh | With catchup: true (the default) dbt's backfill insert and the view's initial refresh write the target at the same time |
⚪️ | Deferred (#731). A non-APPEND refreshable view can lose the backfilled rows (or fail with TABLE_IS_READ_ONLY on Cloud) and an APPEND view holds every row twice; workaround: catchup: false and let the first refresh fill the target |
Related to Implicit target feature |
✅ | ||
| Multiple MVs per model | --<name>:begin / --<name>:end SQL splitting → one <model>_<name> MV each |
✅ | Fresh create of N MVs (dbt-labs/dbt#15507); update/rename flows (marker parsing, rename detection via mvs_pointing_to_it) in dbt-labs/dbt#16200. The upstream-design-dependent proper fix is ⚪️ future work (#731) |
| Stale/renamed-MV detection | Warn about MVs pointing at the target that are no longer in the model; recognize dbt-managed (incl. aliased) MVs | ✅ | Warning on replace (clickhouse__search_associated_mvs_to_target); alias-aware recognition via mvs_pointing_to_it (dbt-labs/dbt#16200) |
| Robust multi-MV marker parsing | clickhouse__extract_mv_views (single-token marker names, upstream #683) |
✅ | dbt-labs/dbt#16200 |
on_schema_change support |
append / sync / fail on the MV target | ✅ | Adapter method check_incremental_schema_changes(…, materialization='materialized view') in dbt-labs/dbt#16090; the MV-side wiring in dbt-labs/dbt#16200 |
Related to Explicit target feature |
✅ | ||
| Target table protection | mv_on_schema_change (defaults to fail when a dbt MV points at the table) + repopulate_from_mvs_on_full_refresh via relation.mvs_pointing_to_it |
✅ | Config keys registered (dbt-labs/dbt#15507) and consumer macro merged; catalog stamping of mvs_pointing_to_it and the table.sql behaviour in dbt-labs/dbt#16200 |
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request
Activity
koletzilla commentedon Sep 8, 2026
Closing: the materialized_view materialization is at v1 parity on dbt Core 2.0 main (refresh-schedule updates, MV-target protection, multi-MV update/rename, on_schema_change and refreshable: false landed with dbt-labs/dbt#16200). The proper upstream multi-MV design stays as future work in #731; remaining gaps are cross-materialization (#711).