From 7bb966ee744b3d266a1c17eeafa3fef8f400249c Mon Sep 17 00:00:00 2001 From: Piotr Zduniak Date: Wed, 5 Aug 2020 12:45:48 +0200 Subject: [PATCH 1/4] Fixed union inline fragments --- internal/exec/selected/selected.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/internal/exec/selected/selected.go b/internal/exec/selected/selected.go index 3075521e..51333c13 100644 --- a/internal/exec/selected/selected.go +++ b/internal/exec/selected/selected.go @@ -173,7 +173,9 @@ func applySelectionSet(r *Request, s *resolvable.Schema, e *resolvable.Object, s } func applyFragment(r *Request, s *resolvable.Schema, e *resolvable.Object, frag *query.Fragment) []Selection { - if frag.On.Name != "" && frag.On.Name != e.Name { + t := r.Schema.Resolve(frag.On.Name) + face, ok := t.(*schema.Interface) + if !ok && frag.On.Name != "" && frag.On.Name != e.Name { a, ok := e.TypeAssertions[frag.On.Name] if !ok { panic(fmt.Errorf("%q does not implement %q", frag.On, e.Name)) // TODO proper error handling @@ -184,6 +186,19 @@ func applyFragment(r *Request, s *resolvable.Schema, e *resolvable.Object, frag Sels: applySelectionSet(r, s, a.TypeExec.(*resolvable.Object), frag.Selections), }} } + if ok && len(face.PossibleTypes) > 0 { + for _, t := range face.PossibleTypes { + if t.Name == e.Name { + return applySelectionSet(r, s, e, frag.Selections) + } + for assertedName, assertedObject := range e.TypeAssertions { + if t.Name == assertedName { + return applySelectionSet(r, s, assertedObject.TypeExec.(*resolvable.Object), frag.Selections) + } + } + } + panic(fmt.Errorf("%q does not implement %q", e.Name, frag.On)) // TODO proper error handling + } return applySelectionSet(r, s, e, frag.Selections) } From b9376caf771ddef9fc75b4338881d536e519f1f4 Mon Sep 17 00:00:00 2001 From: Piotr Zduniak Date: Wed, 5 Aug 2020 12:57:01 +0200 Subject: [PATCH 2/4] Corrected the lookup to be more efficient (didn't realize it was a map) --- internal/exec/selected/selected.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/internal/exec/selected/selected.go b/internal/exec/selected/selected.go index 51333c13..9fadc2e6 100644 --- a/internal/exec/selected/selected.go +++ b/internal/exec/selected/selected.go @@ -191,10 +191,8 @@ func applyFragment(r *Request, s *resolvable.Schema, e *resolvable.Object, frag if t.Name == e.Name { return applySelectionSet(r, s, e, frag.Selections) } - for assertedName, assertedObject := range e.TypeAssertions { - if t.Name == assertedName { - return applySelectionSet(r, s, assertedObject.TypeExec.(*resolvable.Object), frag.Selections) - } + if assertion, ok := e.TypeAssertions[t.Name]; ok { + return applySelectionSet(r, s, assertion.TypeExec.(*resolvable.Object), frag.Selections) } } panic(fmt.Errorf("%q does not implement %q", e.Name, frag.On)) // TODO proper error handling From c672f0f592f81c81362cd637d4cd995ac65fe253 Mon Sep 17 00:00:00 2001 From: Piotr Zduniak Date: Fri, 11 Sep 2020 16:51:38 +0200 Subject: [PATCH 3/4] Assertion cast --- internal/exec/selected/selected.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/internal/exec/selected/selected.go b/internal/exec/selected/selected.go index 9fadc2e6..cbfd5bde 100644 --- a/internal/exec/selected/selected.go +++ b/internal/exec/selected/selected.go @@ -191,8 +191,11 @@ func applyFragment(r *Request, s *resolvable.Schema, e *resolvable.Object, frag if t.Name == e.Name { return applySelectionSet(r, s, e, frag.Selections) } - if assertion, ok := e.TypeAssertions[t.Name]; ok { - return applySelectionSet(r, s, assertion.TypeExec.(*resolvable.Object), frag.Selections) + if a, ok := e.TypeAssertions[t.Name]; ok { + return []Selection{&TypeAssertion{ + TypeAssertion: *a, + Sels: applySelectionSet(r, s, a.TypeExec.(*resolvable.Object), frag.Selections), + }} } } panic(fmt.Errorf("%q does not implement %q", e.Name, frag.On)) // TODO proper error handling From 4b23be73de626f130f4201685ab4b06f9ad55543 Mon Sep 17 00:00:00 2001 From: Piotr Zduniak Date: Fri, 11 Sep 2020 18:01:06 +0200 Subject: [PATCH 4/4] fixed the test --- internal/exec/selected/selected.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/internal/exec/selected/selected.go b/internal/exec/selected/selected.go index cbfd5bde..34b5c9ce 100644 --- a/internal/exec/selected/selected.go +++ b/internal/exec/selected/selected.go @@ -187,18 +187,23 @@ func applyFragment(r *Request, s *resolvable.Schema, e *resolvable.Object, frag }} } if ok && len(face.PossibleTypes) > 0 { + sels := []Selection{} for _, t := range face.PossibleTypes { if t.Name == e.Name { return applySelectionSet(r, s, e, frag.Selections) } + if a, ok := e.TypeAssertions[t.Name]; ok { - return []Selection{&TypeAssertion{ + sels = append(sels, &TypeAssertion{ TypeAssertion: *a, Sels: applySelectionSet(r, s, a.TypeExec.(*resolvable.Object), frag.Selections), - }} + }) } } - panic(fmt.Errorf("%q does not implement %q", e.Name, frag.On)) // TODO proper error handling + if len(sels) == 0 { + panic(fmt.Errorf("%q does not implement %q", e.Name, frag.On)) // TODO proper error handling + } + return sels } return applySelectionSet(r, s, e, frag.Selections) }