@@ -3731,3 +3731,60 @@ def _set_config(_gateway: str, config: Config) -> None:
37313731 "incremental_model" ,
37323732 "seed_model" ,
37333733 ]
3734+
3735+
3736+ def test_materialized_view_evaluation (ctx : TestContext ):
3737+ adapter = ctx .engine_adapter
3738+ dialect = ctx .dialect
3739+ if not adapter .SUPPORTS_MATERIALIZED_VIEWS :
3740+ pytest .skip (f"Skipping engine { dialect } as it does not support materialized views" )
3741+
3742+ elif dialect == "snowflake" :
3743+ pytest .skip (
3744+ f"Skipping Snowflake as it requires an enterprise account for materialized views"
3745+ )
3746+
3747+ model_name = ctx .table ("test_tbl" )
3748+ mview_name = ctx .table ("test_mview" )
3749+
3750+ sqlmesh = ctx .create_context ()
3751+
3752+ sqlmesh .upsert_model (
3753+ load_sql_based_model (
3754+ d .parse (
3755+ f"""
3756+ MODEL (name { model_name } , kind FULL);
3757+
3758+ SELECT 1 AS col
3759+ """
3760+ )
3761+ )
3762+ )
3763+
3764+ sqlmesh .upsert_model (
3765+ load_sql_based_model (
3766+ d .parse (
3767+ f"""
3768+ MODEL (name { mview_name } , kind VIEW (materialized true));
3769+
3770+ SELECT * FROM { model_name }
3771+ """
3772+ )
3773+ )
3774+ )
3775+
3776+ # Case 1: Ensure that plan is successful and we can query the materialized view
3777+ sqlmesh .plan (auto_apply = True , no_prompts = True )
3778+
3779+ df = adapter .fetchdf (f"SELECT * FROM { mview_name .sql (dialect = dialect )} " )
3780+ assert df ["col" ][0 ] == 1
3781+
3782+ # Case 2: Ensure that we can change the underlying table and the materialized view is recreated
3783+ sqlmesh .upsert_model (
3784+ load_sql_based_model (d .parse (f"""MODEL (name { model_name } , kind FULL); SELECT 2 AS col""" ))
3785+ )
3786+
3787+ sqlmesh .plan (auto_apply = True , no_prompts = True )
3788+
3789+ df = adapter .fetchdf (f"SELECT * FROM { mview_name .sql (dialect = dialect )} " )
3790+ assert df ["col" ][0 ] == 2
0 commit comments