Skip to content

Commit 9d77cbb

Browse files
fix(macros): resolve_template fails in audits when this_model is a subquery
Signed-off-by: sravankumarkunadi <sravankumarkunadi@users.noreply.github.com>
1 parent 61082a6 commit 9d77cbb

3 files changed

Lines changed: 54 additions & 1 deletion

File tree

sqlmesh/core/macros.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1402,7 +1402,13 @@ def resolve_template(
14021402
"'s3://data-bucket/prod/test_catalog/sqlmesh__test/test__test_model__2517971505'"
14031403
"""
14041404
if "this_model" in evaluator.locals:
1405-
this_model = exp.to_table(evaluator.locals["this_model"], dialect=evaluator.dialect)
1405+
this_model_expr = evaluator.locals["this_model"]
1406+
if isinstance(this_model_expr, exp.Subquery):
1407+
# Audits on models with a time column render @this_model as a subquery that filters the
1408+
# physical table on the audited time range, so extract the table it selects from
1409+
this_model_expr = this_model_expr.find(exp.Table) or this_model_expr
1410+
1411+
this_model = exp.to_table(this_model_expr, dialect=evaluator.dialect)
14061412
template_str: str = template.this
14071413
result = (
14081414
template_str.replace("@{catalog_name}", this_model.catalog)

tests/core/test_audit.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,30 @@ def test_macro(model: Model):
413413
assert model.render_audit_query(audit_jinja).sql() == expected_query
414414

415415

416+
def test_resolve_template(model_default_catalog: Model):
417+
# @this_model is rendered as a subquery for models with a time column, but @resolve_template
418+
# should still resolve to the underlying physical table
419+
audit = ModelAudit(
420+
name="test_audit",
421+
query="SELECT * FROM @resolve_template('@{catalog_name}.@{schema_name}.@{table_name}$partitions', mode := 'table') WHERE a IS NULL",
422+
)
423+
424+
assert (
425+
model_default_catalog.render_audit_query(audit).sql()
426+
== """SELECT * FROM "test_catalog"."db"."test_model$partitions" AS "test_model$partitions" WHERE "a" IS NULL"""
427+
)
428+
429+
literal_audit = ModelAudit(
430+
name="test_audit",
431+
query="SELECT @resolve_template('s3://bucket/@{catalog_name}/@{schema_name}/@{table_name}') AS path FROM @this_model",
432+
)
433+
434+
assert (
435+
model_default_catalog.render_audit_query(literal_audit).sql()
436+
== """SELECT 's3://bucket/test_catalog/db/test_model' AS "path" FROM (SELECT * FROM "test_catalog"."db"."test_model" AS "test_model" WHERE "ds" BETWEEN '1970-01-01' AND '1970-01-01') AS "_0\""""
437+
)
438+
439+
416440
def test_load_with_defaults(model, assert_exp_eq):
417441
expressions = parse(
418442
"""

tests/core/test_macros.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,29 @@ def test_resolve_template_table():
11381138
)
11391139

11401140

1141+
def test_resolve_template_subquery():
1142+
# Audits on models with a time column render @this_model as a subquery that filters the
1143+
# physical table on the time range, so the underlying table needs to be extracted from it
1144+
parsed_sql = parse_one(
1145+
"SELECT * FROM @resolve_template('@{catalog_name}.@{schema_name}.@{table_name}$partitions', mode := 'table')"
1146+
)
1147+
1148+
evaluator = MacroEvaluator(runtime_stage=RuntimeStage.EVALUATING)
1149+
evaluator.locals.update(
1150+
{
1151+
"this_model": exp.select("*")
1152+
.from_(exp.to_table("test_catalog.sqlmesh__test.test__test_model__2517971505"))
1153+
.where(exp.column("ds").between("2020-01-01", "2020-01-02"))
1154+
.subquery()
1155+
}
1156+
)
1157+
1158+
assert (
1159+
evaluator.transform(parsed_sql).sql(identify=True)
1160+
== 'SELECT * FROM "test_catalog"."sqlmesh__test"."test__test_model__2517971505$partitions"'
1161+
)
1162+
1163+
11411164
def test_macro_with_spaces():
11421165
evaluator = MacroEvaluator()
11431166
evaluator.evaluate(d.parse_one(""" @DEF(x, "a b") """))

0 commit comments

Comments
 (0)