Skip to content

default_value on dimension links doesn't work for non-string columns #2377

Description

@shangyian

Background

A default_value on a dimension join link wraps the projected dimension column in COALESCE(column, default_value), so rows where a LEFT JOIN found no match render a fallback instead of NULL.

Problem

However, this setting only works when the dimension column is a string:

  • The field is typed str at every layer, so default_value: 0 fails validation and you have to write "0".
  • The literal is always wrapped in single quotes, so "0" against an integer column produces COALESCE(col, '0')

The above mean that the feature is unusable on any non-string dimension column -- you can't author the correct value, and the workaround generates invalid SQL.

Reproduction

Link a fact to a dimension whose attribute is an integer, with a numeric default:

dimension_links:
  - type: join
    dimension_node: my_dim
    join_type: left
    join_on: my_fact.dim_id = my_dim.dim_id
    default_value: 0          # rejected at validation — must be "0"

Then query a metric grouped by that integer attribute. With default_value: "0", the generated SQL contains:

COALESCE(t2.some_int_col, '0') AS some_int_col

which fails at execution.

Root cause

Typed as a string throughout:

  • DimensionLink.default_valuedatabase/dimensionlink.py:87 (Mapped[Optional[str]])
  • API models — models/dimensionlink.py:73,88
  • Deploy spec — models/deployment.py:226

And emission hardcodes string quoting in build_dimension_col_expr (construction/build_v3/measures.py:1049-1056):

if default_value is not None:
    coalesce_func = ast.Function(
        ast.Name("COALESCE"),
        args=[col_ref, ast.String(f"'{default_value}'")],
    )

The legacy v2 path has the same pattern (construction/build_v2.py:~1934).

Suggested fix

Make emission type-aware by building the literal from the target dimension column's type, or cast it, rather than assuming string. Widening the authored type is the second half, so default_value: 0 no longer needs quoting.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions