|
18 | 18 | from sqlmesh.dbt.test import TestConfig |
19 | 19 | from sqlmesh.utils.yaml import YAML |
20 | 20 | from sqlmesh.utils.date import to_ds |
| 21 | +import typing as t |
21 | 22 |
|
22 | 23 | pytestmark = pytest.mark.dbt |
23 | 24 |
|
@@ -1028,3 +1029,58 @@ def test_ephemeral_model_ignores_grants() -> None: |
1028 | 1029 |
|
1029 | 1030 | assert sqlmesh_model.kind.is_embedded |
1030 | 1031 | assert sqlmesh_model.grants is None # grants config is skipped for ephemeral / embedded models |
| 1032 | + |
| 1033 | + |
| 1034 | +def test_conditional_ref_in_unexecuted_branch(copy_to_temp_path: t.Callable): |
| 1035 | + path = copy_to_temp_path("tests/fixtures/dbt/sushi_test") |
| 1036 | + temp_project = path[0] |
| 1037 | + |
| 1038 | + models_dir = temp_project / "models" |
| 1039 | + models_dir.mkdir(parents=True, exist_ok=True) |
| 1040 | + |
| 1041 | + test_model_content = """ |
| 1042 | +{{ config( |
| 1043 | + materialized='table', |
| 1044 | +) }} |
| 1045 | +
|
| 1046 | +{% if true %} |
| 1047 | + WITH source AS ( |
| 1048 | + SELECT * |
| 1049 | + FROM {{ ref('simple_model_a') }} |
| 1050 | + ) |
| 1051 | +{% else %} |
| 1052 | + WITH source AS ( |
| 1053 | + SELECT * |
| 1054 | + FROM {{ ref('nonexistent_model') }} -- this doesn't exist but is in unexecuted branch |
| 1055 | + ) |
| 1056 | +{% endif %} |
| 1057 | +
|
| 1058 | +SELECT * FROM source |
| 1059 | +""".strip() |
| 1060 | + |
| 1061 | + (models_dir / "conditional_ref_model.sql").write_text(test_model_content) |
| 1062 | + sushi_context = Context(paths=[str(temp_project)]) |
| 1063 | + |
| 1064 | + # the model should load successfully without raising MissingModelError |
| 1065 | + model = sushi_context.get_model("sushi.conditional_ref_model") |
| 1066 | + assert model is not None |
| 1067 | + |
| 1068 | + # Verify only the executed ref is in the dependencies |
| 1069 | + assert len(model.depends_on) == 1 |
| 1070 | + assert '"memory"."sushi"."simple_model_a"' in model.depends_on |
| 1071 | + |
| 1072 | + # Also the model can be rendered successfully with the executed ref |
| 1073 | + rendered = model.render_query() |
| 1074 | + assert rendered is not None |
| 1075 | + assert ( |
| 1076 | + rendered.sql() |
| 1077 | + == 'WITH "source" AS (SELECT "simple_model_a"."a" AS "a" FROM "memory"."sushi"."simple_model_a" AS "simple_model_a") SELECT "source"."a" AS "a" FROM "source" AS "source"' |
| 1078 | + ) |
| 1079 | + |
| 1080 | + # And run plan with this conditional model for good measure |
| 1081 | + plan = sushi_context.plan(select_models=["sushi.conditional_ref_model", "sushi.simple_model_a"]) |
| 1082 | + sushi_context.apply(plan) |
| 1083 | + upstream_ref = sushi_context.engine_adapter.fetchone("SELECT * FROM sushi.simple_model_a") |
| 1084 | + assert upstream_ref == (1,) |
| 1085 | + result = sushi_context.engine_adapter.fetchone("SELECT * FROM sushi.conditional_ref_model") |
| 1086 | + assert result == (1,) |
0 commit comments