Skip to content

Commit

Permalink
Ensure other field is returned from GetRelation
Browse files Browse the repository at this point in the history
If the relationship references the same (host) collection, the function would in some circumstances return the known field.  In collection.save, when updating via a secondary one-one field this leads to an infinite loop.
  • Loading branch information
AndrewSisley committed Sep 27, 2023
1 parent b2ec0f3 commit c4f84dc
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 13 deletions.
14 changes: 8 additions & 6 deletions client/descriptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,14 @@ func (col CollectionDescription) GetFieldByID(id FieldID) (FieldDescription, boo
}

// GetRelation returns the field that supports the relation of the given name.
func (col CollectionDescription) GetRelation(name string) (FieldDescription, bool) {
if !col.Schema.IsEmpty() {
for _, field := range col.Schema.Fields {
if field.RelationName == name {
return field, true
}
func (col CollectionDescription) GetFieldByRelation(
relationName string,
otherCollectionName string,
otherFieldName string,
) (FieldDescription, bool) {
for _, field := range col.Schema.Fields {
if field.RelationName == relationName && !(col.Name == otherCollectionName && otherFieldName == field.Name) {
return field, true
}
}
return FieldDescription{}, false
Expand Down
2 changes: 1 addition & 1 deletion db/collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -1062,7 +1062,7 @@ func (c *collection) save(
if isSecondaryRelationID {
primaryId := val.Value().(string)

err = c.patchPrimaryDoc(ctx, txn, relationFieldDescription, primaryKey.DocKey, primaryId)
err = c.patchPrimaryDoc(ctx, txn, c.Name(), relationFieldDescription, primaryKey.DocKey, primaryId)
if err != nil {
return cid.Undef, err
}
Expand Down
7 changes: 6 additions & 1 deletion db/collection_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ func (c *collection) isSecondaryIDField(fieldDesc client.FieldDescription) (clie
func (c *collection) patchPrimaryDoc(
ctx context.Context,
txn datastore.Txn,
secondaryCollectionName string,
relationFieldDescription client.FieldDescription,
docKey string,
fieldValue string,
Expand All @@ -365,7 +366,11 @@ func (c *collection) patchPrimaryDoc(
}
primaryCol = primaryCol.WithTxn(txn)

primaryField, ok := primaryCol.Description().GetRelation(relationFieldDescription.RelationName)
primaryField, ok := primaryCol.Description().GetFieldByRelation(
relationFieldDescription.RelationName,
secondaryCollectionName,
relationFieldDescription.Name,
)
if !ok {
return client.NewErrFieldNotExist(relationFieldDescription.RelationName)
}
Expand Down
13 changes: 11 additions & 2 deletions planner/type_join.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,11 @@ func (p *Planner) makeTypeJoinOne(
return nil, err
}

subTypeField, subTypeFieldNameFound := subTypeCollectionDesc.GetRelation(subTypeFieldDesc.RelationName)
subTypeField, subTypeFieldNameFound := subTypeCollectionDesc.GetFieldByRelation(
subTypeFieldDesc.RelationName,
parent.sourceInfo.collectionDescription.Name,
subTypeFieldDesc.Name,
)
if !subTypeFieldNameFound {
return nil, client.NewErrFieldNotExist(subTypeFieldDesc.RelationName)
}
Expand Down Expand Up @@ -481,7 +485,12 @@ func (p *Planner) makeTypeJoinMany(
return nil, err
}

rootField, rootNameFound := subTypeCollectionDesc.GetRelation(subTypeFieldDesc.RelationName)
rootField, rootNameFound := subTypeCollectionDesc.GetFieldByRelation(
subTypeFieldDesc.RelationName,
parent.sourceInfo.collectionDescription.Name,
subTypeFieldDesc.Name,
)

if !rootNameFound {
return nil, client.NewErrFieldNotExist(subTypeFieldDesc.RelationName)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,6 @@ func TestMutationUpdateOneToOne_SelfReferencingFromPrimary(t *testing.T) {
testUtils.ExecuteTestCase(t, test)
}

/*
This test will enter an infinite loop
func TestMutationUpdateOneToOne_SelfReferencingFromSecondary(t *testing.T) {
user1ID := "bae-decf6467-4c7c-50d7-b09d-0a7097ef6bad"

Expand Down Expand Up @@ -191,4 +189,3 @@ func TestMutationUpdateOneToOne_SelfReferencingFromSecondary(t *testing.T) {

testUtils.ExecuteTestCase(t, test)
}
*/

0 comments on commit c4f84dc

Please sign in to comment.