fix: emit list retrieve for owner-both reverse references#381
Conversation
Symptom: retrieving through a Reference association from the child side can be serialized as an AssociationRetrieveSource, which represents a single object. When association ownership metadata is explicit, that loses the one-to-many shape needed by downstream actions. Root cause: the reverse-reference database-retrieve fallback excluded AssociationOwnerBoth. The association-source fallback also typed reverse Reference traversals as a single object even when the start variable was on the child side. Fix: use a DatabaseRetrieveSource with an XPath constraint for explicit-owner reverse Reference traversal over a persistable parent, including owner-both, and keep legacy association-source fallback list-typed for child-side traversal. Tests: updated synthetic reverse-reference unit coverage for owner-both, non-persistable fallback, and unknown-owner fallback, then ran make build and make test.
AI Code ReviewCritical IssuesNone found. Moderate IssuesNone found. Minor IssuesNone found. What Looks Good
RecommendationApprove the PR. The changes correctly implement the fix for emitting list retrieve for owner-both reverse references while preserving existing fallback behavior. The test coverage is adequate and validates both the new behavior and edge cases. No syntax or architectural concerns were identified. Automated review via OpenRouter (Nemotron Super 120B) — workflow source |
ako
left a comment
There was a problem hiding this comment.
PR #381 — fix: emit list retrieve for owner-both reverse references
Reviewed against the CLAUDE.md checklist.
No Blockers
The core fix is correct. Owner=Both (symmetric association) is still a one-to-many relationship when traversed in reverse (child → parent), so using DatabaseRetrieveSource with an XPath constraint is the right output. The old != AssociationOwnerBoth condition incorrectly routed it to AssociationRetrieveSource.
Moderate Issues
1. Missing mdl-examples/bug-tests/ file
The checklist requires a bug-test MDL script for every bug fix that is verifiable in Studio Pro:
"every bug fix should include an MDL test script in
mdl-examples/bug-tests/that reproduces the issue, so the fix can be verified in Studio Pro if applicable"
The fix changes how ChangeAction BSON retrieve actions are built — directly affecting what ends up in the MPR. A short script that creates an entity with a Both-owned association and retrieves via reverse traversal, with a note to run mx check, would be the natural companion.
Minor Issues
2. Owner="" behavioural change is implicit in the condition swap
Changing != AssociationOwnerBoth to != "" has a second effect beyond the stated fix: associations where Owner is empty (missing metadata) now fall through to AssociationRetrieveSource instead of DatabaseRetrieveSource. Previously "" != "Both" was true, so empty-owner associations would have entered the database-retrieve path.
The new test TestAddRetrieveAction_ReverseReferenceUnknownOwnerPreservesAssociationSource correctly documents this new behaviour, and the PR summary mentions "missing ownership metadata" as an intended fallback case. The only gap is that the summary doesn't explicitly note this is also a behaviour change from the previous state (not just a preservation of pre-PR-356 behaviour). A one-line note in the PR description or a code comment at the != "" guard (// Owner="" means metadata was unavailable; fall back to association source) would make the intent self-evident for future readers.
Positive Notes
- List typing fix in the
elsebranch ("List of " + otherEntityfor reverse traversal) is correct and appropriately scoped — it applies only whenstartVarType == assocInfo.childEntityQN. - Three test cases cover the three distinct owner states (
Both→ database source,""→ association source, non-persistable → association source), and theNonPersistableParenttest correctly updated its varType assertion to"List of Sample.Parent". ✓ - No grammar, AST, or BSON writer changes needed — the fix is entirely in the routing logic. ✓
Summary: No blockers. The fix is correct and test coverage is solid. Two gaps: missing mdl-examples/bug-tests/ file (checklist item), and the implicit Owner="" behaviour change warrants a one-line comment at the guard.
Closes #380.
Summary
Referencetraversal, includingOwner=Both, as a database retrieve with XPath when the parent entity is persistable.Referencetraversal even when fallback source syntax is used.Validation
go test ./mdl/executor -run 'TestAddRetrieveAction_ReverseReference'make buildmake test