You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ossie.apache.org by jb...@apache.org on 2026/10/01 16:23:49 UTC

(ossie) branch main updated: fix(wisdom): read OSSIE_SQL_2026 metric expressions (#449)

This is an automated email from the ASF dual-hosted git repository.

jbonofre pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ossie.git


The following commit(s) were added to refs/heads/main by this push:
     new 2dd03cd2 fix(wisdom): read OSSIE_SQL_2026 metric expressions (#449)
2dd03cd2 is described below

commit 2dd03cd2a55858e10d4e918d313e2b194ec0cb55
Author: Chris Eubank <10...@users.noreply.github.com>
AuthorDate: Thu Oct 1 09:23:40 2026 -0700

    fix(wisdom): read OSSIE_SQL_2026 metric expressions (#449)
    
    OSSIE_SQL_2026 (core-spec #439, Python enum #440) is an ANSI-SQL-compatible
    portable dialect, but the wisdom converter's _pick_expression() fell back only
    through the dataset dialect and then ANSI_SQL. A field or metric expressed only
    in OSSIE_SQL_2026 raised a spurious MISSING_DIALECT_EXPRESSION issue, even though
    the converter still used the first listed expression as a fallback.
    
    Add OSSIE_SQL_2026 to the fallback chain, treating it as an ANSI_SQL-equivalent,
    so an OSSIE_SQL_2026-only field or metric is exported without the spurious issue.
    Add regression tests covering a field-only and a metric-only OSSIE_SQL_2026
    expression, the ANSI_SQL and native-dialect precedence over it, and a genuinely
    unusable dialect that still reports MISSING_DIALECT_EXPRESSION.
    
    Partial fix for #442 (wisdom converter only).
    
    Co-authored-by: Isaac <no...@databricks.com>
---
 .../wisdom/src/ossie_wisdom/ossie_to_wisdom.py     |   3 +
 converters/wisdom/tests/test_ossie_to_wisdom.py    | 121 +++++++++++++++++++++
 2 files changed, 124 insertions(+)

diff --git a/converters/wisdom/src/ossie_wisdom/ossie_to_wisdom.py b/converters/wisdom/src/ossie_wisdom/ossie_to_wisdom.py
index b7be440e..75e10137 100644
--- a/converters/wisdom/src/ossie_wisdom/ossie_to_wisdom.py
+++ b/converters/wisdom/src/ossie_wisdom/ossie_to_wisdom.py
@@ -284,6 +284,9 @@ class OssieToWisdomConverter:
             return by_dialect[dialect]
         if OssieDialect.ANSI_SQL in by_dialect:
             return by_dialect[OssieDialect.ANSI_SQL]
+        # OSSIE_SQL_2026 is ANSI-SQL-compatible; treat it as an ANSI_SQL-equivalent fallback.
+        if OssieDialect.OSSIE_SQL_2026 in by_dialect:
+            return by_dialect[OssieDialect.OSSIE_SQL_2026]
         issues.append(
             ConverterIssue(issue_type=ConverterIssueType.MISSING_DIALECT_EXPRESSION, element_name=element_name)
         )
diff --git a/converters/wisdom/tests/test_ossie_to_wisdom.py b/converters/wisdom/tests/test_ossie_to_wisdom.py
index bfee1bad..655e2a25 100644
--- a/converters/wisdom/tests/test_ossie_to_wisdom.py
+++ b/converters/wisdom/tests/test_ossie_to_wisdom.py
@@ -38,6 +38,15 @@ def _snowflake(expression):
     return OssieExpression(dialects=[OssieDialectExpression(dialect=OssieDialect.SNOWFLAKE, expression=expression)])
 
 
+def _expr(*dialect_expressions):
+    return OssieExpression(
+        dialects=[
+            OssieDialectExpression(dialect=dialect, expression=expression)
+            for dialect, expression in dialect_expressions
+        ]
+    )
+
+
 @pytest.fixture(scope="module")
 def ossie_document():
     export = json.loads(FIXTURE.read_text())
@@ -211,3 +220,115 @@ def test_unresolved_metric_attaches_to_first_dataset():
     assert [issue.element_name for issue in _issues_of(result, ConverterIssueType.METRIC_TABLE_UNRESOLVED)] == [
         "row_count"
     ]
+
+
+def test_field_only_ossie_sql_2026_is_exported_without_missing_issue():
+    """A field expressed only in OSSIE_SQL_2026 is exported, with no spurious
+    MISSING_DIALECT_EXPRESSION issue (#442)."""
+    document = OssieDocument(
+        name="m",
+        datasets=[
+            OssieDataset(
+                name="orders",
+                source="analytics.sales.orders",
+                fields=[OssieField(name="region", expression=_expr((OssieDialect.OSSIE_SQL_2026, "o_region")))],
+            )
+        ],
+    )
+    result = OssieToWisdomConverter().convert(document, exported_at="2026-07-10T00:00:00+00:00")
+    formulas = {formula["name"]: formula["expression"] for formula in _table(result.output, "orders").get("formulas", [])}
+    assert formulas == {"region": "o_region"}
+    assert _issues_of(result, ConverterIssueType.MISSING_DIALECT_EXPRESSION) == []
+
+
+def test_metric_only_ossie_sql_2026_is_exported_without_missing_issue():
+    """A metric expressed only in OSSIE_SQL_2026 is exported as a measure, with no
+    spurious MISSING_DIALECT_EXPRESSION issue (#442)."""
+    from ossie import OssieMetric
+
+    document = OssieDocument(
+        name="m",
+        datasets=[OssieDataset(name="orders", source="analytics.sales.orders")],
+        metrics=[
+            OssieMetric(name="total_amount", expression=_expr((OssieDialect.OSSIE_SQL_2026, "SUM(orders.amount)")))
+        ],
+    )
+    result = OssieToWisdomConverter().convert(document, exported_at="2026-07-10T00:00:00+00:00")
+    measures = {measure["name"]: measure["expression"] for measure in _table(result.output, "orders").get("measures", [])}
+    assert measures == {"total_amount": "SUM(orders.amount)"}
+    assert _issues_of(result, ConverterIssueType.MISSING_DIALECT_EXPRESSION) == []
+
+
+def test_ansi_sql_preferred_over_ossie_sql_2026():
+    """ANSI_SQL wins over OSSIE_SQL_2026 when both are present."""
+    document = OssieDocument(
+        name="m",
+        datasets=[
+            OssieDataset(
+                name="orders",
+                source="analytics.sales.orders",
+                fields=[
+                    OssieField(
+                        name="region",
+                        expression=_expr(
+                            (OssieDialect.OSSIE_SQL_2026, "portable_region"),
+                            (OssieDialect.ANSI_SQL, "ansi_region"),
+                        ),
+                    )
+                ],
+            )
+        ],
+    )
+    result = OssieToWisdomConverter().convert(document, exported_at="2026-07-10T00:00:00+00:00")
+    formulas = {formula["name"]: formula["expression"] for formula in _table(result.output, "orders").get("formulas", [])}
+    assert formulas == {"region": "ansi_region"}
+
+
+def test_native_dialect_preferred_over_ossie_sql_2026():
+    """A native dialect (SNOWFLAKE) wins over OSSIE_SQL_2026 when both are present."""
+    document = OssieDocument(
+        name="m",
+        datasets=[
+            OssieDataset(
+                name="orders",
+                source="analytics.sales.orders",
+                fields=[
+                    OssieField(
+                        name="region",
+                        expression=_expr(
+                            (OssieDialect.OSSIE_SQL_2026, "portable_region"),
+                            (OssieDialect.SNOWFLAKE, "snow_region"),
+                        ),
+                    )
+                ],
+            )
+        ],
+    )
+    result = OssieToWisdomConverter().convert(document, exported_at="2026-07-10T00:00:00+00:00")
+    formulas = {formula["name"]: formula["expression"] for formula in _table(result.output, "orders").get("formulas", [])}
+    assert formulas == {"region": "snow_region"}
+
+
+def test_unusable_dialect_still_reports_missing_expression():
+    """A metric whose only dialect matches neither the dataset dialect, ANSI_SQL, nor
+    OSSIE_SQL_2026 still reports MISSING_DIALECT_EXPRESSION and falls back to the first
+    listed expression. Guards the fallback chain against silently accepting any dialect (#442)."""
+    from ossie import OssieMetric
+
+    document = OssieDocument(
+        name="m",
+        datasets=[
+            OssieDataset(
+                name="orders",
+                source="analytics.sales.orders",
+                fields=[OssieField(name="id", expression=_snowflake("id"))],
+            )
+        ],
+        metrics=[OssieMetric(name="row_count", expression=_expr((OssieDialect.BIGQUERY, "COUNT(orders.id)")))],
+    )
+    result = OssieToWisdomConverter().convert(document, exported_at="2026-07-10T00:00:00+00:00")
+    measures = {measure["name"]: measure["expression"] for measure in _table(result.output, "orders").get("measures", [])}
+    assert measures == {"row_count": "COUNT(orders.id)"}
+    assert [issue.element_name for issue in _issues_of(result, ConverterIssueType.MISSING_DIALECT_EXPRESSION)] == [
+        "row_count"
+    ]