Skip to content

Commit a52a218

Browse files
authored
Fix!: Support Paren expressions in EACH, REDUCE, etc macros (#5096)
1 parent 1097cef commit a52a218

File tree

4 files changed

+71
-3
lines changed

4 files changed

+71
-3
lines changed

examples/custom_materializations/pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,6 @@ custom_full_with_custom_kind = "custom_materializations.custom_kind:CustomFullWi
1414

1515
[tool.setuptools.packages.find]
1616
include = ["custom_materializations"]
17+
18+
[tool.setuptools_scm]
19+
fallback_version = "0.0.0"

sqlmesh/core/macros.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,13 @@ def substitute(
653653

654654
if len(items) == 1:
655655
item = items[0]
656-
expressions = item.expressions if isinstance(item, (exp.Array, exp.Tuple)) else item
656+
expressions = (
657+
item.expressions
658+
if isinstance(item, (exp.Array, exp.Tuple))
659+
else [item.this]
660+
if isinstance(item, exp.Paren)
661+
else item
662+
)
657663
else:
658664
expressions = items
659665

tests/core/test_context.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2198,13 +2198,13 @@ def test_plan_audit_intervals(tmp_path: pathlib.Path, caplog):
21982198

21992199
# Case 1: The timestamp audit should be in the inclusive range ['2025-02-01 00:00:00', '2025-02-01 23:59:59.999999']
22002200
assert (
2201-
f"""SELECT COUNT(*) FROM (SELECT ("timestamp_id") AS "timestamp_id" FROM (SELECT * FROM "sqlmesh__sqlmesh_audit"."sqlmesh_audit__timestamp_example__{timestamp_snapshot.version}" AS "sqlmesh_audit__timestamp_example__{timestamp_snapshot.version}" WHERE "timestamp_id" BETWEEN CAST('2025-02-01 00:00:00' AS TIMESTAMP) AND CAST('2025-02-01 23:59:59.999999' AS TIMESTAMP)) AS "_q_0" WHERE TRUE GROUP BY ("timestamp_id") HAVING COUNT(*) > 1) AS "audit\""""
2201+
f"""SELECT COUNT(*) FROM (SELECT "timestamp_id" AS "timestamp_id" FROM (SELECT * FROM "sqlmesh__sqlmesh_audit"."sqlmesh_audit__timestamp_example__{timestamp_snapshot.version}" AS "sqlmesh_audit__timestamp_example__{timestamp_snapshot.version}" WHERE "timestamp_id" BETWEEN CAST('2025-02-01 00:00:00' AS TIMESTAMP) AND CAST('2025-02-01 23:59:59.999999' AS TIMESTAMP)) AS "_q_0" WHERE TRUE GROUP BY "timestamp_id" HAVING COUNT(*) > 1) AS "audit\""""
22022202
in caplog.text
22032203
)
22042204

22052205
# Case 2: The date audit should be in the inclusive range ['2025-02-01', '2025-02-01']
22062206
assert (
2207-
f"""SELECT COUNT(*) FROM (SELECT ("date_id") AS "date_id" FROM (SELECT * FROM "sqlmesh__sqlmesh_audit"."sqlmesh_audit__date_example__{date_snapshot.version}" AS "sqlmesh_audit__date_example__{date_snapshot.version}" WHERE "date_id" BETWEEN CAST('2025-02-01' AS DATE) AND CAST('2025-02-01' AS DATE)) AS "_q_0" WHERE TRUE GROUP BY ("date_id") HAVING COUNT(*) > 1) AS "audit\""""
2207+
f"""SELECT COUNT(*) FROM (SELECT "date_id" AS "date_id" FROM (SELECT * FROM "sqlmesh__sqlmesh_audit"."sqlmesh_audit__date_example__{date_snapshot.version}" AS "sqlmesh_audit__date_example__{date_snapshot.version}" WHERE "date_id" BETWEEN CAST('2025-02-01' AS DATE) AND CAST('2025-02-01' AS DATE)) AS "_q_0" WHERE TRUE GROUP BY "date_id" HAVING COUNT(*) > 1) AS "audit\""""
22082208
in caplog.text
22092209
)
22102210

tests/core/test_model.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
create_seed_model,
5656
create_sql_model,
5757
load_sql_based_model,
58+
load_sql_based_models,
5859
model,
5960
)
6061
from sqlmesh.core.model.common import parse_expression
@@ -11096,3 +11097,61 @@ def test_render_query_optimize_query_false(assert_exp_eq, sushi_context):
1109611097
LIMIT 10
1109711098
""",
1109811099
)
11100+
11101+
11102+
def test_each_macro_with_paren_expression_arg(assert_exp_eq):
11103+
expressions = d.parse(
11104+
"""
11105+
MODEL (
11106+
name dataset.@table_name,
11107+
kind VIEW,
11108+
blueprints (
11109+
(
11110+
table_name := model1,
11111+
event_columns := (
11112+
'value' AS property1,
11113+
'value' AS property2
11114+
)
11115+
),
11116+
(
11117+
table_name := model2,
11118+
event_columns := (
11119+
'value' AS property1
11120+
)
11121+
)
11122+
),
11123+
);
11124+
11125+
SELECT @EACH(@event_columns, x -> x)
11126+
"""
11127+
)
11128+
11129+
models = load_sql_based_models(expressions, lambda _: {})
11130+
11131+
# Should generate 2 models from the blueprints
11132+
assert len(models) == 2
11133+
11134+
# Get the models sorted by name for consistent testing
11135+
model1 = next(m for m in models if "model1" in m.name)
11136+
model2 = next(m for m in models if "model2" in m.name)
11137+
11138+
# Verify model names
11139+
assert model1.name == "dataset.model1"
11140+
assert model2.name == "dataset.model2"
11141+
11142+
assert_exp_eq(
11143+
model1.render_query(),
11144+
"""
11145+
SELECT
11146+
'value' AS "property1",
11147+
'value' AS "property2"
11148+
""",
11149+
)
11150+
11151+
assert_exp_eq(
11152+
model2.render_query(),
11153+
"""
11154+
SELECT
11155+
'value' AS "property1"
11156+
""",
11157+
)

0 commit comments

Comments
 (0)