Skip to content

_find_dataset_for_col resolves the wrong semantic_model for SUM_BOOLEAN metrics over qualified columns #265

Description

@AmirF194

OSIToMSIConverter._find_dataset_for_col picks the wrong semantic_model for a SUM_BOOLEAN metric whose condition references a qualified column, because it re-parses the whole aggregation expression instead of just the column reference.

Root cause

converters/dbt/src/ossie_dbt/osi_to_msi.py:361-387, _find_dataset_for_col:

raw_inner = _get_raw_inner_col(raw_expr_str)
if raw_inner and "." in raw_inner:
    ds_name, _ = raw_inner.rsplit(".", 1)
    return ds_name

raw_expr_str is the entire metric expression, not the bare column. For a simple SUM(orders.amount), _get_raw_inner_col (expression_utils.py:136) returns orders.amount and the rsplit correctly yields orders. But for the SUM(CASE WHEN <qualified column> THEN 1 ELSE 0 END) shape that _extract_agg_info (expression_utils.py:63-73) recognizes as AggregationType.SUM_BOOLEAN, _get_raw_inner_col returns the entire rendered CASE WHEN expression (since tree.this of a Sum node is the Case node itself), and rsplit(".", 1) then slices through the CASE WHEN keywords instead of the dataset qualifier.

Repro (current HEAD 8c410f904c9bb20f683ef31292442e7bc432a8f6), driven through the real OSIToMSIConverter.convert() entry point, not the helper directly:

import sys
sys.path.insert(0, "converters/dbt/src")
sys.path.insert(0, "converters/dbt")
sys.path.insert(0, "python/src")

from ossie_dbt.osi_to_msi import OSIToMSIConverter
from tests.helpers import _osi_dataset, _osi_doc, _osi_field, _osi_metric

doc = _osi_doc(
    datasets=[_osi_dataset("orders", fields=[_osi_field("order_id")])],
    metrics=[_osi_metric("has_order", "SUM(CASE WHEN orders.order_id IS NOT NULL THEN 1 ELSE 0 END)")],
)
result = OSIToMSIConverter().convert(doc).output
print(result.metrics[0].type_params.metric_aggregation_params.semantic_model)

Run from converters/dbt/ with metricflow>=0.209.0, sqlglot>=20.0, jinja2>=3.0, PyYAML>=6.0, pydantic>=2.0 installed.

Observed: semantic_model is 'CASE WHEN NOT orders'.
Expected: 'orders'.

The resulting PydanticMetric points at a semantic model name that doesn't exist in the manifest, which the MetricFlow validator downstream would reject (or silently fail to resolve if a coincidentally-named model exists).

tests/test_osi_to_msi.py has no case exercising SUM_BOOLEAN over a qualified column, so this shape isn't covered.

Happy to send a PR (the fix is a small, scoped change to _find_dataset_for_col) if that's useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions