Skip to content

Commit c10d06d

Browse files
committed
fix: infer ReferenceSet association retrieve list entity type
Symptom: list operations after compact association retrieves could write bare filter attributes as unqualified invalid attribute identifiers. Root cause: ReferenceSet association retrieves registered their result type as a list of the association name instead of a list of the entity on the other side, so downstream member resolution had no entity context. Fix: use association metadata to register the other endpoint entity for ReferenceSet retrieves, while retaining the previous fallback for unknown metadata. Tests: added a ReferenceSet retrieve type regression and ran make test.
1 parent b0162c3 commit c10d06d

2 files changed

Lines changed: 40 additions & 1 deletion

File tree

mdl/executor/cmd_microflows_builder_actions.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,18 @@ func (fb *flowBuilder) addRetrieveAction(s *ast.RetrieveStmt) model.ID {
329329
otherEntity = assocInfo.parentEntityQN
330330
}
331331
fb.varTypes[s.Variable] = otherEntity
332+
} else if assocInfo != nil && assocInfo.Type == domainmodel.AssociationTypeReferenceSet {
333+
// ReferenceSet traversal returns a list of the entity on the other side,
334+
// not a list typed as the association itself.
335+
otherEntity := assocInfo.childEntityQN
336+
if startVarType == assocInfo.childEntityQN {
337+
otherEntity = assocInfo.parentEntityQN
338+
}
339+
if otherEntity != "" {
340+
fb.varTypes[s.Variable] = "List of " + otherEntity
341+
} else {
342+
fb.varTypes[s.Variable] = "List of " + assocQN
343+
}
332344
} else {
333345
// ReferenceSet or unknown: returns a list
334346
fb.varTypes[s.Variable] = "List of " + assocQN

mdl/executor/cmd_microflows_builder_retrieve_reverse_test.go

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,38 @@ func TestAddRetrieveAction_ReverseReferenceNonPersistableParentUsesAssociationSo
8181
}
8282
}
8383

84+
func TestAddRetrieveAction_ReferenceSetRegistersOtherEntityListType(t *testing.T) {
85+
fb := newRetrieveAssociationFlowBuilderWithType(domainmodel.AssociationTypeReferenceSet, domainmodel.AssociationOwnerBoth, true, true)
86+
fb.varTypes["Parent"] = "Sample.Parent"
87+
88+
fb.addRetrieveAction(&ast.RetrieveStmt{
89+
Variable: "Children",
90+
StartVariable: "Parent",
91+
Source: ast.QualifiedName{Module: "Sample", Name: "Parent_Child"},
92+
})
93+
94+
action := onlyRetrieveAction(t, fb)
95+
source, ok := action.Source.(*microflows.AssociationRetrieveSource)
96+
if !ok {
97+
t.Fatalf("reference-set retrieve source = %T, want AssociationRetrieveSource", action.Source)
98+
}
99+
if source.StartVariable != "Parent" || source.AssociationQualifiedName != "Sample.Parent_Child" {
100+
t.Fatalf("association source = %#v", source)
101+
}
102+
if got := fb.varTypes["Children"]; got != "List of Sample.Child" {
103+
t.Fatalf("result var type = %q, want List of Sample.Child", got)
104+
}
105+
}
106+
84107
func newRetrieveAssociationFlowBuilder(owner domainmodel.AssociationOwner) *flowBuilder {
85108
return newRetrieveAssociationFlowBuilderWithPersistability(owner, true, true)
86109
}
87110

88111
func newRetrieveAssociationFlowBuilderWithPersistability(owner domainmodel.AssociationOwner, parentPersistable, childPersistable bool) *flowBuilder {
112+
return newRetrieveAssociationFlowBuilderWithType(domainmodel.AssociationTypeReference, owner, parentPersistable, childPersistable)
113+
}
114+
115+
func newRetrieveAssociationFlowBuilderWithType(associationType domainmodel.AssociationType, owner domainmodel.AssociationOwner, parentPersistable, childPersistable bool) *flowBuilder {
89116
moduleID := model.ID("sample-module")
90117
parentID := model.ID("parent-entity")
91118
childID := model.ID("child-entity")
@@ -113,7 +140,7 @@ func newRetrieveAssociationFlowBuilderWithPersistability(owner domainmodel.Assoc
113140
Name: "Parent_Child",
114141
ParentID: parentID,
115142
ChildID: childID,
116-
Type: domainmodel.AssociationTypeReference,
143+
Type: associationType,
117144
Owner: owner,
118145
},
119146
},

0 commit comments

Comments
 (0)