Skip to content

Commit 6d97967

Browse files
committed
Force mview creation again in RW
1 parent 3f51d13 commit 6d97967

File tree

3 files changed

+21
-19
lines changed

3 files changed

+21
-19
lines changed

.circleci/continue_config.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -310,10 +310,10 @@ workflows:
310310
- athena
311311
- fabric
312312
- gcp-postgres
313-
filters:
314-
branches:
315-
only:
316-
- main
313+
# filters:
314+
# branches:
315+
# only:
316+
# - main
317317
- ui_style
318318
- ui_test
319319
- vscode_test

sqlmesh/core/snapshot/evaluator.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2282,11 +2282,14 @@ def insert(
22822282
render_kwargs: t.Dict[str, t.Any],
22832283
**kwargs: t.Any,
22842284
) -> None:
2285-
# For all engines that support materialized views (except RisingWave) we recreate it.
2286-
# This is because case if upstream tables were recreated (e.g FULL models), the mview would be invalidated as well.
2287-
# RisingWave is an exception as it doesn't support CREATE OR REPLACE, so upstream models don't recreate their physical tables.
2288-
# Standard views still follow the same logic depending on VIEW_BINDING flag.
2289-
must_recreate_view = not self.adapter.HAS_VIEW_BINDING
2285+
# We should always recreate materialized views across supported engines (Snowflake, BigQuery etc) because
2286+
# if upstream tables were recreated (e.g FULL models), the MVs would be silently invalidated.
2287+
# The only exception to that rule is RisingWave, which doesn't support CREATE OR REPLACE, so upstream
2288+
# models don't recreate their physical tables for the MVs to be invalidated.
2289+
# However, even for RW we still want to recreate MVs to avoid stale references
2290+
is_materialized_view = self._is_materialized_view(model)
2291+
must_recreate_view = not self.adapter.HAS_VIEW_BINDING or is_materialized_view
2292+
22902293
if self.adapter.table_exists(table_name) and not must_recreate_view:
22912294
logger.info("Skipping creation of the view '%s'", table_name)
22922295
return

tests/core/engine_adapter/integration/test_integration.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3745,7 +3745,7 @@ def test_materialized_view_evaluation(ctx: TestContext, mocker: MockerFixture):
37453745
pytest.skip(f"Skipping {dialect} as they're not enabled on standard accounts")
37463746

37473747
model_name = ctx.table("test_tbl")
3748-
mview_name = ctx.table("test_mview")
3748+
mview_name = ctx.table("test_mview1")
37493749

37503750
sqlmesh = ctx.create_context()
37513751

@@ -3772,12 +3772,15 @@ def test_materialized_view_evaluation(ctx: TestContext, mocker: MockerFixture):
37723772
)
37733773
)
37743774
)
3775+
3776+
def _assert_mview_value(value: int):
3777+
df = adapter.fetchdf(f"SELECT * FROM {mview_name.sql(dialect=dialect)}")
3778+
assert df["col"][0] == value
37753779

37763780
# Case 1: Ensure that plan is successful and we can query the materialized view
37773781
sqlmesh.plan(auto_apply=True, no_prompts=True)
37783782

3779-
df = adapter.fetchdf(f"SELECT * FROM {mview_name.sql(dialect=dialect)}")
3780-
assert df["col"][0] == 1
3783+
_assert_mview_value(value=1)
37813784

37823785
# Case 2: Ensure that we can change the underlying table and the materialized view is recreated
37833786
sqlmesh.upsert_model(
@@ -3789,11 +3792,7 @@ def test_materialized_view_evaluation(ctx: TestContext, mocker: MockerFixture):
37893792
with mock.patch.object(logger, "info") as mock_logger:
37903793
sqlmesh.plan(auto_apply=True, no_prompts=True)
37913794

3792-
# RisingWave does not need to recreate the mview, all other engines do
3793-
recreate_view = (
3794-
"Skipping creation of the view" if dialect == "risingwave" else "Replacing view"
3795-
)
3796-
assert any(recreate_view in call[0][0] for call in mock_logger.call_args_list)
3795+
assert any("Replacing view" in call[0][0] for call in mock_logger.call_args_list)
3796+
37973797

3798-
df = adapter.fetchdf(f"SELECT * FROM {mview_name.sql(dialect=dialect)}")
3799-
assert df["col"][0] == 2
3798+
_assert_mview_value(value=2)

0 commit comments

Comments
 (0)