Skip to content

Commit

Permalink
fix: Support relationships where both fields have the same name (sour…
Browse files Browse the repository at this point in the history
…cenetwork#109)

* Remove unneeded explicit type declaration

* Remove commented out code

* Reduce field.type.name calls

* Remove unused property

* Support relationships between two fields of same name
  • Loading branch information
AndrewSisley authored Jan 11, 2022
1 parent 5af6089 commit dc99f24
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 15 deletions.
107 changes: 107 additions & 0 deletions db/tests/query/one_to_many/with_same_field_name_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Copyright 2020 Source Inc.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.
package one_to_many

import (
"testing"

testUtils "github.com/sourcenetwork/defradb/db/tests"
)

var sameFieldNameGQLSchema = (`
type book {
name: String
relationship1: author
}
type author {
name: String
relationship1: [book]
}
`)

func executeSameFieldNameTestCase(t *testing.T, test testUtils.QueryTestCase) {
testUtils.ExecuteQueryTestCase(t, sameFieldNameGQLSchema, []string{"book", "author"}, test)
}

func TestQueryOneToManyWithSameFieldName(t *testing.T) {
tests := []testUtils.QueryTestCase{
{
Description: "One-to-many relation query from one side, same field name",
Query: `query {
book {
name
relationship1 {
name
}
}
}`,
Docs: map[int][]string{
//books
0: { // bae-9217906d-e8c5-533d-8520-71c754590844
(`{
"name": "Painted House",
"relationship1_id": "bae-2edb7fdd-cad7-5ad4-9c7d-6920245a96ed"
}`)},
//authors
1: { // bae-2edb7fdd-cad7-5ad4-9c7d-6920245a96ed
(`{
"name": "John Grisham"
}`)},
},
Results: []map[string]interface{}{
{
"name": "Painted House",
"relationship1": map[string]interface{}{
"name": "John Grisham",
},
},
},
},
{
Description: "One-to-many relation query from many side, same field name",
Query: `query {
author {
name
relationship1 {
name
}
}
}`,
Docs: map[int][]string{
//books
0: { // bae-9217906d-e8c5-533d-8520-71c754590844
(`{
"name": "Painted House",
"relationship1_id": "bae-2edb7fdd-cad7-5ad4-9c7d-6920245a96ed"
}`)},
//authors
1: { // bae-2edb7fdd-cad7-5ad4-9c7d-6920245a96ed
(`{
"name": "John Grisham"
}`)},
},
Results: []map[string]interface{}{
{
"name": "John Grisham",
"relationship1": []map[string]interface{}{
{
"name": "Painted House",
},
},
},
},
},
}

for _, test := range tests {
executeSameFieldNameTestCase(t, test)
}
}
15 changes: 12 additions & 3 deletions query/graphql/planner/type_join.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ type typeJoinOne struct {
root planNode
subType planNode

rootName string
subTypeName string
subTypeFieldName string

Expand Down Expand Up @@ -195,7 +194,6 @@ func (p *Planner) makeTypeJoinOne(parent *selectNode, source planNode, subType *

typeJoin.subTypeName = subTypeFieldDesc.Name
typeJoin.subTypeFieldName = subtypefieldname
typeJoin.rootName = desc.Name // @todo: Correctly handle getting sub/root names

// split filter
if scan, ok := source.(*scanNode); ok {
Expand Down Expand Up @@ -351,13 +349,24 @@ func (p *Planner) makeTypeJoinMany(parent *selectNode, source planNode, subType
}
subType.CollectionName = subTypeFieldDesc.Schema

// get relation
rm := p.db.SchemaManager().Relations
rel := rm.GetRelationByDescription(subType.Name, subTypeFieldDesc.Schema, desc.Name)
if rel == nil {
return nil, errors.New("Relation does not exists")
}
subTypeLookupFieldName, _, ok := rel.GetFieldFromSchemaType(subTypeFieldDesc.Schema)
if !ok {
return nil, errors.New("Relation is missing referenced field")
}

selectPlan, err := p.SubSelect(subType)
if err != nil {
return nil, err
}
typeJoin.subType = selectPlan
typeJoin.subTypeName = subTypeFieldDesc.Name
typeJoin.rootName = desc.Name
typeJoin.rootName = subTypeLookupFieldName

// split filter
if scan, ok := source.(*scanNode); ok {
Expand Down
15 changes: 5 additions & 10 deletions query/graphql/schema/descriptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,27 +118,22 @@ func (g *Generator) CreateDescriptions(types []*gql.Object) ([]base.CollectionDe
fd.Typ = defaultCRDTForFieldKind[fd.Kind]

if fd.IsObject() {
fd.Schema = field.Type.Name()
schemaName := field.Type.Name()
fd.Schema = schemaName

// check if its a one-to-one, one-to-many, many-to-many
rel := g.manager.Relations.GetRelationByDescription(
fname, field.Type.Name(), t.Name())
fname, schemaName, t.Name())
if rel == nil {
return nil, errors.New("Field missing associated relation")
}

_, fieldRelationType, ok := rel.GetField(fname)
_, fieldRelationType, ok := rel.GetField(schemaName, fname)
if !ok {
return nil, errors.New("Relation is missing field")
}

fd.Meta = rel.Kind() | fieldRelationType
// if {
// fd.Meta = fieldRelationType // Primary is embedded within fieldRelationType
// } else if base.IsSet(rel.Kind(), base.Meta_Relation_ONEMANY) {
// // are we the one side or the many side

// }
}

desc.Schema.Fields = append(desc.Schema.Fields, fd)
Expand All @@ -157,7 +152,7 @@ func (g *Generator) CreateDescriptions(types []*gql.Object) ([]base.CollectionDe

// add default index
desc.Indexes = []base.IndexDescription{
base.IndexDescription{
{
Name: "primary",
ID: uint32(0),
Primary: true,
Expand Down
4 changes: 2 additions & 2 deletions query/graphql/schema/relations.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,9 +281,9 @@ func (r Relation) schemaTypeExists(t string) (int, bool) {
return -1, false
}

func (r Relation) GetField(field string) (string, uint8, bool) {
func (r Relation) GetField(schemaType string, field string) (string, uint8, bool) {
for i, f := range r.fields {
if f == field {
if f == field && r.schemaTypes[i] == schemaType {
return f, r.types[i], true
}
}
Expand Down

0 comments on commit dc99f24

Please sign in to comment.