Skip to content

fix(gooddata): preserve grain for aliased primary-key fields - #347

Open
mattfaltyn wants to merge 2 commits into
apache:mainfrom
mattfaltyn:fix/gooddata-aliased-primary-key-grain
Open

fix(gooddata): preserve grain for aliased primary-key fields#347
mattfaltyn wants to merge 2 commits into
apache:mainfrom
mattfaltyn:fix/gooddata-aliased-primary-key-grain

Conversation

@mattfaltyn

Copy link
Copy Markdown

Summary

  • Preserve GoodData dataset grain when an Ossie attribute uses a logical field name that differs from its physical primary-key column.
  • Match primary_key entries against the converted attribute's source_column, which is already derived from the ANSI SQL expression.
  • Cover both explicit dimensions and MAQL-detected attributes with regression cases.

This keeps the existing behavior for fields whose logical and physical names match while preventing silent loss of key/grain semantics for aliased fields.

Related Issues

Closes #346

Validation

Python 3.12: uv run --python 3.12 --frozen pytest -q  -> 76 passed
Python 3.13: uv run pytest -q                         -> 76 passed
Python 3.14: uv run --python 3.14 --frozen pytest -q  -> 76 passed
uv run ruff check src tests                           -> passed
git diff --check                                      -> passed

Checklist

Specification

  • No specification changes

Converters

  • Converter logic is updated
  • Regression coverage is included under the GoodData test directory

Documentation

  • Existing documentation was reviewed; no update is needed because this restores the documented primary-key-to-grain mapping without changing the interface

Tests

  • All GoodData tests pass across the CI Python matrix
  • New behavior is covered by tests

Compliance

  • No new source files or dependencies

Signed-off-by: Matt Faltyn <faltyn.matthew@gmail.com>
@jbonofre
jbonofre self-requested a review September 12, 2026 06:12
attr = _convert_to_attribute(field_def, ds_name)
attributes.append(attr)
if field_name in pk_columns:
if attr.source_column in pk_columns:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This matches PK columns by comparing attr.source_column against pk_columns, which is a string/value match rather than a unique field match. If two fields alias the same physical column (e.g. a natural key customer_id and a display alias customer_key that both resolve to ANSI_SQL: customer_id), both get added to grain_ids, producing a bogus multi-attribute composite grain for what's actually a single-column key.

I suggest keyring grain membership off the field's identity (e.g. matching source columns to specific field defs and taking the first match, or building grain from primary_key entries directly rather than scanning all attributes) instead of plain "is this source_column in pk_columns" check.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

building grain from primary_key entries directly rather than scanning all attributes

Great catch. Grain now follows primary_key entries directly, so each key column resolves to one attribute.

if not is_date:
for f in ds.get("fields", []):
src = _get_source_column(f)
col_to_attr[src] = f"attr.{ds_name}.{f['name']}"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found it related while reviewing 😄

col_to_attr is a dict keyed by resolved source_column, with no collision check. If two fields resolve to the same physical column, whichever is processed last silently overwrites the earlier entry. Since _convert_relationship looks up target attributes through this map, a relationship meant to reference one attribute can get silently rewired to a different one (no error, just a wrong GdReferenceTarget in the output).

Given _convert_relationship already raises ValueError for an unresolved column, this should probably raise (or at least warn) on a source_column collision here too, rather than overwriting silently.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should probably raise on a source_column collision here too

Agreed. The converter now raises ValueError on duplicate resolved source columns, with regression coverage for ambiguous grain and relationship targets.

Signed-off-by: Matt Faltyn <faltyn.matthew@gmail.com>
@mattfaltyn
mattfaltyn requested a review from jbonofre September 12, 2026 16:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GoodData export drops grain for aliased primary-key fields

2 participants