Skip to content

fix: preserve compact reverse-association retrieves#356

Open
hjotha wants to merge 2 commits intomendixlabs:mainfrom
hjotha:submit/retrieve-reverse-association-compact-form
Open

fix: preserve compact reverse-association retrieves#356
hjotha wants to merge 2 commits intomendixlabs:mainfrom
hjotha:submit/retrieve-reverse-association-compact-form

Conversation

@hjotha
Copy link
Copy Markdown
Contributor

@hjotha hjotha commented Apr 27, 2026

Closes part of #352.
Part of #332.

Summary

This extracts the reverse-association retrieve formatter fix from the audit staging branch.

Some Mendix models store a compact association retrieve as a database retrieve with a single XPath predicate like [Module.Association = $Variable] and range All. The formatter previously described that as a verbose database retrieve with a where clause, causing avoidable describe/exec/describe drift.

Changes

  • Detect the narrow reverse-association database retrieve shape.
  • Verify through the backend domain model that the association target matches the retrieved entity before compacting.
  • Emit retrieve $Result from $Variable/Module.Association; only for safe All range, unsorted, single-predicate cases.
  • Keep existing database retrieve output for complex predicates, non-variable RHS, sorting, non-All ranges, and non-matching targets.

Validation

  • make build
  • make lint-go
  • make test

Symptom: describing a reverse-association retrieve stored as a database retrieve with a simple association XPath expanded it into a verbose where-clause retrieve instead of preserving the compact retrieve-from-association form.

Root cause: the formatter only recognized explicit AssociationRetrieveSource values. Some Mendix models encode the same association traversal as a DatabaseRetrieveSource with a single predicate of the form [Module.Association = $Variable] and RangeType All.

Fix: detect that narrow database-retrieve shape, verify the association points at the retrieved entity through the backend domain model, and emit retrieve $Result from $Variable/Module.Association when it is safe. Complex predicates, sorting, non-All ranges, non-variable right-hand sides, and non-matching association targets keep the existing database retrieve output.

Tests: add synthetic format-action regressions for the compact form, range fallback, target-entity fallback, and parser rejection of complex predicates.
@github-actions
Copy link
Copy Markdown

AI Code Review

What Looks Good

  • The PR successfully preserves compact reverse-association retrieves in microflow formatting, preventing unnecessary describe/exec/describe drift
  • Changes are tightly scoped to the formatter logic with clear helper functions (parseReverseAssociationRetrieve, isRangeAllOrNil, etc.)
  • Comprehensive test coverage added including positive cases and edge cases (non-All range, non-matching entity, complex predicates)
  • Proper backend abstraction usage via ctx.Backend for domain model validation
  • Maintains existing verbose output for unsafe/complex cases ensuring no regressions
  • Follows existing code style and patterns in the formatter
  • Helper functions correctly validate XPath structure, association qualifications, and entity matching

Recommendation

Approve the PR. The changes are minimal, well-tested, and address the specific issue without violating any architectural guidelines. No modifications to MDL grammar or syntax are needed since this is purely a formatting improvement for existing constructs.


Automated review via OpenRouter (Nemotron Super 120B) — workflow source

Adds an MDL script under mdl-examples/bug-tests/ exercising a
retrieve sourced through `from $Var/Module.Association`. After
exec, the describe output must keep the compact form and
`mx check` must report 0 errors.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.

2 participants