Skip to content

Commit 9cdbb00

Browse files
committed
test(format): assert header formatting is idempotent
Rendering a dialect-specific type with the generic generator compounds across runs rather than merely looking different: tsql `DATETIME2` renders as `TIMESTAMP`, and tsql parses `TIMESTAMP` as ROWVERSION, so a second pass writes `VARBINARY`. Two runs of `sqlmesh format` silently turned a datetime into a binary type -- and for an SCD kind's `time_data_type` that is the physical type of the valid_from/valid_to columns. Covers columns, audits, nested kind properties, physical_properties and the SQLMesh-owned scalars. Signed-off-by: mday-io <mdaytn@gmail.com>
1 parent b1d7c25 commit 9cdbb00

1 file changed

Lines changed: 27 additions & 0 deletions

File tree

‎tests/core/test_dialect.py‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,33 @@ def test_format_model_expressions_meta_render_policy(dialect: str, audit_type: s
419419
)
420420

421421

422+
@pytest.mark.parametrize(
423+
"header",
424+
[
425+
"columns (ts DATETIME2(6))",
426+
"audits (my_audit(t := CAST('2024-01-01' AS DATETIME2)))",
427+
"kind SCD_TYPE_2_BY_COLUMN(unique_key id, columns (a, b), time_data_type DATETIME2(6))",
428+
"physical_properties (labels = (('env', 'prod')))",
429+
"allow_partials true, description 'my description'",
430+
],
431+
)
432+
def test_format_model_expressions_is_idempotent(header: str):
433+
"""Formatting an already-formatted model must be a no-op.
434+
435+
Rendering a dialect-specific type with the generic generator does not merely lose
436+
formatting, it compounds: tsql `DATETIME2` renders as `TIMESTAMP`, and tsql parses
437+
`TIMESTAMP` as ROWVERSION (a binary type), so a second pass writes `VARBINARY`. Two
438+
runs of `sqlmesh format` silently turned a datetime into a binary type -- and for
439+
`time_data_type` that is the physical type of the SCD valid_from/valid_to columns.
440+
"""
441+
source = f"MODEL (name a.b, dialect tsql, {header});\nSELECT 1 AS x"
442+
443+
once = format_model_expressions(parse(source, default_dialect="tsql"), dialect="tsql")
444+
twice = format_model_expressions(parse(once, default_dialect="tsql"), dialect="tsql")
445+
446+
assert once == twice
447+
448+
422449
def test_format_audit_expressions_meta_render_policy():
423450
"""AUDIT headers have their own meta model, and get the same split: `blocking` is
424451
SQLMesh's own boolean and must not become tsql's `(1 = 0)`, while `defaults` holds

0 commit comments

Comments
 (0)