Skip to content

Commit d782e48

Browse files
authored
Merge branch 'main' into chore/ci-dbt-1.11
2 parents 2b19288 + 3667124 commit d782e48

2 files changed

Lines changed: 79 additions & 8 deletions

File tree

sqlmesh/core/model/meta.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -321,17 +321,19 @@ def _column_descriptions_validator(
321321
if isinstance(vs, (exp.Tuple, exp.Array)):
322322
vs = vs.expressions
323323

324-
raw_col_descriptions = (
325-
vs
324+
# Normalize each part while it is still an identifier, so that a quoted
325+
# column keeps its case on dialects where quoting makes it significant.
326+
col_descriptions = (
327+
{normalize_identifiers(k, dialect=dialect).name: v for k, v in vs.items()}
326328
if isinstance(vs, dict)
327-
else {".".join([part.this for part in v.this.parts]): v.expression.name for v in vs}
329+
else {
330+
".".join(
331+
normalize_identifiers(part, dialect=dialect).name for part in v.this.parts
332+
): v.expression.name
333+
for v in vs
334+
}
328335
)
329336

330-
col_descriptions = {
331-
normalize_identifiers(k, dialect=dialect).name: v
332-
for k, v in raw_col_descriptions.items()
333-
}
334-
335337
columns_to_types = data.get("columns_to_types_")
336338
if columns_to_types:
337339
from sqlmesh.core.console import get_console

tests/core/test_model.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,6 +1000,75 @@ def test_column_descriptions(sushi_context, assert_exp_eq):
10001000
assert model.column_descriptions == {"id": "primary key", "foo": "bar"}
10011001

10021002

1003+
def test_column_descriptions_quoted_identifier():
1004+
expressions = d.parse(
1005+
"""
1006+
MODEL (
1007+
name db.table,
1008+
kind FULL,
1009+
dialect snowflake,
1010+
column_descriptions (
1011+
"myColumn" = 'a case-sensitive column',
1012+
other_column = 'an unquoted column'
1013+
)
1014+
);
1015+
1016+
SELECT 1 AS "myColumn", 2 AS other_column
1017+
"""
1018+
)
1019+
model = load_sql_based_model(expressions, dialect="snowflake")
1020+
1021+
# A quoted key keeps its case, an unquoted one is still normalized.
1022+
assert model.column_descriptions == {
1023+
"myColumn": "a case-sensitive column",
1024+
"OTHER_COLUMN": "an unquoted column",
1025+
}
1026+
assert set(model.column_descriptions) <= set(model.columns_to_types)
1027+
1028+
1029+
def test_column_descriptions_dotted_identifier():
1030+
# A nested field is looked up by its dotted path, so every part normalizes on its own.
1031+
expressions = d.parse(
1032+
"""
1033+
MODEL (
1034+
name db.table,
1035+
kind FULL,
1036+
dialect bigquery,
1037+
column_descriptions (
1038+
record.`myField` = 'a nested field'
1039+
)
1040+
);
1041+
1042+
SELECT STRUCT(1 AS `myField`) AS record
1043+
"""
1044+
)
1045+
model = load_sql_based_model(expressions, dialect="bigquery")
1046+
1047+
assert model.column_descriptions == {"record.myfield": "a nested field"}
1048+
1049+
expressions = d.parse(
1050+
"""
1051+
MODEL (
1052+
name db.table,
1053+
kind FULL,
1054+
dialect snowflake,
1055+
column_descriptions (
1056+
nested.field = 'an unquoted path',
1057+
"MyStruct"."myField" = 'a quoted path'
1058+
)
1059+
);
1060+
1061+
SELECT 1 AS c
1062+
"""
1063+
)
1064+
model = load_sql_based_model(expressions, dialect="snowflake")
1065+
1066+
assert model.column_descriptions == {
1067+
"NESTED.FIELD": "an unquoted path",
1068+
"MyStruct.myField": "a quoted path",
1069+
}
1070+
1071+
10031072
def test_model_jinja_macro_reference_extraction():
10041073
@macro()
10051074
def test_macro(**kwargs) -> None:

0 commit comments

Comments
 (0)