feat: support TRIGGER ON UPDATE and SCHEDULE EVERY for MV and ST#1434
Conversation
Adds the full Databricks refresh-schedule grammar on materialized views and streaming tables: SCHEDULE CRON, SCHEDULE EVERY, and TRIGGER ON UPDATE [AT MOST EVERY INTERVAL ...]. - RefreshConfig is a discriminated config with parse-time validation on the new modes. - Idempotent runs no longer emit spurious ALTERs across user/server unit differences. - Auto-REFRESH is suppressed for every/on_update modes. Coverage: - Unit tests for parser, validator, diff, and refresh-schedule macros. - Functional round-trip tests per mode for both MV and ST. - Functional lifecycle tests walking each relation through every mode transition plus a non-refresh-component change.
Coverage reportClick to see where and how coverage changed
This report was generated by python-coverage-comment-action |
||||||||||||||||||||||||||||||
Drop log-line and SQL-emission assertions, keep only mode-value checks on the resulting relation. Remove tests that only inspected dbt logs.
This comment was marked as duplicate.
This comment was marked as duplicate.
1 similar comment
|
/integration-test |
|
Integration tests dispatched for PR #1434 by @tejassp-db. Track progress in the Actions tab. |
|
Integration results for PR #1434 — UC cluster ❌ cancelled · SQL warehouse ❌ cancelled · All-purpose cluster ❌ failure |
|
/integration-test |
|
Integration tests dispatched for PR #1434 by @sd-db. Track progress in the Actions tab. |
|
Integration results for PR #1434 — UC cluster ⏩ skipped · SQL warehouse ⏩ skipped · All-purpose cluster ⏩ skipped · Shard coverage ⏩ skipped |
|
/integration-test |
|
Integration tests dispatched for PR #1434 by @sd-db. Track progress in the Actions tab. |
|
Integration results for PR #1434 — UC cluster ✅ success · SQL warehouse ✅ success · All-purpose cluster ✅ success · Shard coverage ✅ success |
When a user sets `schedule = {'cron': '...'}` without `time_zone_value`,
the warehouse stores it as `Etc/UTC` in `DESCRIBE EXTENDED`. Previously
`RefreshConfig.__eq__` compared `"UTC" != "ETC/UTC"`, so dbt emitted a
no-op `ALTER` on every subsequent run.
Adds `_canonical_tz()` mapping None / UTC / Etc/UTC to the same value;
`__eq__` and `__hash__` use it on the CRON branch.
Test coverage:
- New EVERY-input matrix test per file (MV + ST) walks one relation
through HOUR / DAY / WEEK via `on_configuration_change: apply`,
asserting each round-trips against the warehouse.
- The existing CRON lifecycle step now uses a no-TZ fixture so the
`Etc/UTC` round-trip is exercised on the existing CRON path.
- Unit tests cover the equivalence + parametrized server-emitted shapes
(TRIGGER intervals normalized to SECOND, EVERY plural forms).
…trigger-schedule-syntax # Conflicts: # tests/functional/adapter/materialized_view_tests/fixtures.py
The schedule-mode test files inlined six SQL constants each
(ST_EVERY_2_HOURS, ST_ON_UPDATE_BARE, ST_CRON, etc.) — out of line with
the convention used elsewhere in `streaming_tables/fixtures.py` and
`materialized_view_tests/fixtures.py` (`streaming_table`,
`complex_streaming_table`, `materialized_view`).
Moved each to its respective fixtures.py with snake_case names and
deduped two cases:
- `ST_NO_SCHEDULE` is now the pre-existing `fixtures.streaming_table`.
- `ST_EVERY_2_HOURS` / `MV_EVERY_2_HOURS` are now defined via the
`streaming_table_with_every("2 HOURS")` / `materialized_view_with_every`
helper added in the previous commit.
- Added `materialized_view_no_schedule` (the existing `materialized_view`
fixture has cron + tblproperties, so it can't double as the no-schedule
case).
No behavioral change to the tests.
`test_every_mode_roundtrip` only asserted `refresh.mode.value == "every"`
for `EVERY 2 HOURS`. The `TestStreamingTableEveryAcceptedInputs` matrix
test (added previously) now walks HOUR / DAY / WEEK with strict equality
+ no-diff checks — strictly stronger coverage.
Remove the redundant test and the `streaming_table_every_2_hours` /
`materialized_view_every_2_hours` fixtures; the few remaining call sites
in the lifecycle and drop-and-readd tests use the
`streaming_table_with_every("2 HOURS")` / `materialized_view_with_every`
helper inline.
Both removed cases assert exactly what the lifecycle test already does: - `TestStreamingTableManualMode` / `TestMaterializedViewManualMode` — identical to lifecycle's first step (CREATE no-schedule → assert manual). - `test_on_update_rate_limited_mode_roundtrip` — same `"900" in refresh.at_most_every` assertion as the lifecycle ON_UPDATE step. Leaves `test_on_update_bare_mode_roundtrip` (only coverage for bare TRIGGER ON UPDATE on fresh CREATE; lifecycle doesn't include a bare on_update transition).
Summary
Adds the full Databricks refresh-schedule grammar on materialized views and streaming tables: `SCHEDULE CRON`, `SCHEDULE EVERY`, and `TRIGGER ON UPDATE [AT MOST EVERY INTERVAL ...]`.
Closes #1293.
User-facing config:
Test plan