Skip to content

OrionBelt converter renames a calculated field to its expression on the way back to Ossie #601

Open

Description

@kayemkim

A field whose expression is not a plain column comes back from an OBML round trip with the expression as its name. On current main (64a1ae4), a dataset with two fields, amount (amount) and amount_with_tax (amount * 1.1, ANSI_SQL), exported with ossie-orionbelt ossie-to-obml and imported again with obml-to-ossie returns the second field as name: amount * 1.1, with amount_with_tax left in description, in ai_context.synonyms and in the ORIONBELT extension as obml_column_name.

The document passes validate.py, and a second trip to OBML restores the column key from that stash, so the converter's own round trip looks lossless while every other consumer of the Ossie document sees a field named by its SQL.

Two steps combine:

  • ossie_to_obml.py _convert_field writes the field's ANSI_SQL expression into the OBML column code whatever its shape. The committed fixture tests/fixtures/tpcds_as_obml.yaml carries the same form (customer_full_name: code: c_first_name || ' ' || c_last_name), so this half may be the intended OBML representation of a calculated column.
  • obml_to_ossie.py _convert_column names the Ossie field by code and keeps the column key only as obml_column_name. That is the right reading when code is the physical column an OBML author put behind a display name, and the wrong one when code is an expression the export put there.

Keeping the column key as the field name when code does not read as a single identifier would fix the Ossie-first trip without touching the OBML-first one. The round-trip tests in test_ossie_converter_datatype.py start from OBML only, so an Ossie-first case with one calculated field would also be worth adding.

Found while running the #596 fixtures through the converters. The other eight return the field under its own name.

Activity

  1. ralfbecher commented on Oct 17, 2026

    @ralfbecher
    Contributor

    Thanks for the precise report, confirmed. The root cause is on the export side: obml_to_ossie named each field by the OBML column code, which after an Ossie import can hold a calculated field's SQL.

    We fixed it in the in-repo converter (ralforion/orionbelt-semantic-layer#586) slightly differently from the suggestion here. Instead of falling back to the column key only when code is not a single identifier, the field name is now always the OBML column name and code is always its expression. That matches what an Ossie field is (a logical name plus a physical expression) and needs no guessing about what an identifier looks like. It also fixes two related issues of the same kind:

    • metric SQL referenced fields as <dataset>.<code>, so a metric over a calculated field pointed at a field that does not exist;
    • the import matched primary_key against the physical code rather than the field name, so a field named id with expression order_id lost its key.

    The trade-off is that an OBML-first export now names fields by column name (Customer Name instead of NAME), so it ships as a minor version (0.5.0). Documents exported by older versions still import, including their unique keys and preserved metrics.

    While testing, we also found that the import lifted aggregates out of a subquery inside a metric's SQL into measures (ralforion/orionbelt-semantic-layer#587); such metrics are now preserved verbatim.

    If this direction works for you, I'll port both changes to converters/orionbelt in one PR.

  2. kayemkim commented on Oct 18, 2026

    @kayemkim
    ContributorAuthor

    That direction is better than my suggestion. Naming the field by the column and keeping the expression in code is the distinction an Ossie field already makes, and it removes the guess about what counts as an identifier. Please go ahead with the port, and I will run the #596 M1 fixture and the TPC-DS fixture through it when the PR is up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triageIssue needs triage by a maintainer

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions