Skip to content

ThoughtSpot converter: a field's ANSI_SQL expression is dataset-qualified and resolves in neither namespace #459

Description

@djwaldo

The ThoughtSpot converter emits a field's portable ANSI_SQL expression as <dataset>.<warehouse column>. Both halves are real, but they come from different namespaces, so the pair resolves in neither.

What it emits

A ThoughtSpot column displayed as Region Name and stored as RGN_NM:

datasets:
- name: ORDERS
  source: SALES.PUBLIC.ORDERS
  fields:
  - name: region_name
    expression:
      dialects:
      - dialect: THOUGHTSPOT
        expression: "[ORDERS::Region Name]"
      - dialect: ANSI_SQL
        expression: ORDERS.RGN_NM      # <-- neither a field nor a warehouse reference

There is no RGN_NM among the declared fields (region_name), so it is not a resolvable logical reference. And the qualifier is the Ossie dataset name — ThoughtSpot's Table-object name — which need not be the warehouse table, so it is not runnable SQL either. A real example from the corpus:

dataset name : Dim_Customer
source       : NEWRETAIL.SMALLRETAIL.NewRetail_Customer_Dimension
emitted      : Dim_Customer.Customer_Name

There is no Dim_Customer table in that database. 44 of 164 datasets across 31 real models have a dataset name that differs from their warehouse table.

How often

Measured over 31 real ThoughtSpot models, counting case-insensitively:

dataset.X references in field expressions 612
naming nothing the document declares 211, in 20 of 31 models
same, in metric expressions 0

Every occurrence is in a field expression. It only shows when the display name differs from the warehouse column name — which is common in real models and absent from the converter's own fixtures, which is why nothing caught it.

validation/validate.py cannot catch it: it checks that an expression parses as SQL, and Dim_Customer.Customer_Name parses fine.

What the other converters do

For a field's own expression, every sibling emits the bare warehouse column, including when it differs from the field name:

Converter Field ANSI_SQL
databricks line_number l_linenumber
databricks sold_year d_year
nvidia customer_name name
gooddata / omni / orionbelt (identity-mapped) bare column

The physical column is not the problem — that is the convention. The qualifier is.

Proposed fix

Emit the bare warehouse column for a field, and keep the dataset qualifier for a metric. The asymmetry is scope, not inconsistency: a field belongs to one dataset whose source already names the warehouse table, so a bare column is unambiguous; a metric is model-scoped and may reference any dataset, so SUM(amount) is ambiguous as soon as two datasets have an amount. nvidia qualifies metrics for exactly that reason (SUM(orders.subtotal)).

Raised as a follow-up to a review comment on #364 (now merged). PR to follow.

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions