From 8b43fb01eada55119dd1431725deecb3b3fa8c98 Mon Sep 17 00:00:00 2001 From: Andrew Sisley Date: Thu, 11 Jan 2024 09:44:33 -0500 Subject: [PATCH 1/5] Add test for extra field in view SDL --- tests/integration/view/simple/simple_test.go | 49 ++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tests/integration/view/simple/simple_test.go b/tests/integration/view/simple/simple_test.go index 0e5aa0f4a7..a04dd560a1 100644 --- a/tests/integration/view/simple/simple_test.go +++ b/tests/integration/view/simple/simple_test.go @@ -160,3 +160,52 @@ func TestView_SimpleWithFieldSubset_ErrorsSelectingExcludedField(t *testing.T) { testUtils.ExecuteTestCase(t, test) } + +func TestView_SimpleWithExtraFieldInViewSDL(t *testing.T) { + test := testUtils.TestCase{ + Description: "Simple view with extra field in SDL", + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String + age: Int + } + `, + }, + testUtils.CreateView{ + Query: ` + User { + name + } + `, + // `age` is present in SDL but not the query + SDL: ` + type UserView { + name: String + age: Int + } + `, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "John" + }`, + }, + testUtils.Request{ + Request: `query { + UserView { + name + } + }`, + Results: []map[string]any{ + { + "name": "John", + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} From 32d1a1a2113fd34dda69a34cb64e2051018906fc Mon Sep 17 00:00:00 2001 From: Andrew Sisley Date: Thu, 11 Jan 2024 09:56:52 -0500 Subject: [PATCH 2/5] Fix file name --- .../view/one_to_one/{simple_test_test.go => simple_test.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/integration/view/one_to_one/{simple_test_test.go => simple_test.go} (100%) diff --git a/tests/integration/view/one_to_one/simple_test_test.go b/tests/integration/view/one_to_one/simple_test.go similarity index 100% rename from tests/integration/view/one_to_one/simple_test_test.go rename to tests/integration/view/one_to_one/simple_test.go From 9cc88ff20e063982ccb6a2f6d21d6f1c41d43310 Mon Sep 17 00:00:00 2001 From: Andrew Sisley Date: Thu, 11 Jan 2024 09:45:06 -0500 Subject: [PATCH 3/5] Handle field in query but not SDL --- core/doc.go | 15 +++++ planner/view.go | 5 +- .../view/one_to_many/simple_test.go | 64 +++++++++++++++++++ .../view/one_to_many/with_count_test.go | 55 ++++++++++++++++ tests/integration/view/simple/simple_test.go | 49 ++++++++++++++ 5 files changed, 187 insertions(+), 1 deletion(-) diff --git a/core/doc.go b/core/doc.go index 2a149dccc5..379ac79bf9 100644 --- a/core/doc.go +++ b/core/doc.go @@ -180,6 +180,21 @@ func (mapping *DocumentMapping) SetFirstOfName(d *Doc, name string, value any) { d.Fields[mapping.IndexesByName[name][0]] = value } +// TrySetFirstOfName overwrites the first field of this name with the given value. +// +// Will return false if the field does not exist, otherwise will return true. +func (mapping *DocumentMapping) TrySetFirstOfName(d *Doc, name string, value any) bool { + if indexes, ok := mapping.IndexesByName[name]; ok && len(indexes) > 0 { + index := indexes[0] + // Panicing here should be impossible unless there is something very wrong in + // the mapper code. + d.Fields[index] = value + return true + } + + return false +} + // FirstOfName returns the value of the first field of the given name. // // Will panic if the field does not exist (but not if it's value is default). diff --git a/planner/view.go b/planner/view.go index 7050469ffd..48a026f306 100644 --- a/planner/view.go +++ b/planner/view.go @@ -69,7 +69,10 @@ func (n *viewNode) Value() core.Doc { // will take into account any aliases defined in the base query. doc := n.docMapper.documentMapping.NewDoc() for fieldName, fieldValue := range sourceValue { - n.docMapper.documentMapping.SetFirstOfName(&doc, fieldName, fieldValue) + // If the field does not exist, ignore it an continue. It likely means that + // the field was declared in the query but not the SDL, and if it is not in the + // SDL it cannot be requested/rendered by the user and would be dropped later anyway. + _ = n.docMapper.documentMapping.TrySetFirstOfName(&doc, fieldName, fieldValue) } return doc diff --git a/tests/integration/view/one_to_many/simple_test.go b/tests/integration/view/one_to_many/simple_test.go index 02bb7cb8a5..68949f6999 100644 --- a/tests/integration/view/one_to_many/simple_test.go +++ b/tests/integration/view/one_to_many/simple_test.go @@ -239,3 +239,67 @@ func TestView_OneToManyOuterToInnerToOuter_Errors(t *testing.T) { testUtils.ExecuteTestCase(t, test) } + +func TestView_OneToManyWithRelationInQueryButNotInSDL(t *testing.T) { + test := testUtils.TestCase{ + Description: "One to many view", + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Author { + name: String + books: [Book] + } + type Book { + name: String + author: Author + } + `, + }, + testUtils.CreateView{ + // Query books via author but do not declare relation in SDL + Query: ` + Author { + name + books { + name + } + } + `, + SDL: ` + type AuthorView { + name: String + } + `, + }, + // bae-ef9cd756-08e1-5f23-abeb-7b3e6351a68d + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ + "name": "Harper Lee" + }`, + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ + "name": "To Kill a Mockingbird", + "author_id": "bae-ef9cd756-08e1-5f23-abeb-7b3e6351a68d" + }`, + }, + testUtils.Request{ + Request: `query { + AuthorView { + name + } + }`, + Results: []map[string]any{ + { + "name": "Harper Lee", + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/view/one_to_many/with_count_test.go b/tests/integration/view/one_to_many/with_count_test.go index ffc6b4cacd..256b2057bb 100644 --- a/tests/integration/view/one_to_many/with_count_test.go +++ b/tests/integration/view/one_to_many/with_count_test.go @@ -156,3 +156,58 @@ func TestView_OneToManyWithAliasedCount(t *testing.T) { testUtils.ExecuteTestCase(t, test) } + +func TestView_OneToManyWithCountInQueryButNotSDL(t *testing.T) { + test := testUtils.TestCase{ + Description: "One to many view with count in query but not sdl", + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Author { + name: String + books: [Book] + } + type Book { + name: String + author: Author + } + `, + }, + testUtils.CreateView{ + Query: ` + Author { + name + _count(books: {}) + } + `, + SDL: ` + type AuthorView { + name: String + } + `, + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ + "name": "Harper Lee" + }`, + }, + testUtils.Request{ + Request: ` + query { + AuthorView { + name + } + } + `, + Results: []map[string]any{ + { + "name": "Harper Lee", + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/view/simple/simple_test.go b/tests/integration/view/simple/simple_test.go index a04dd560a1..1e0f7c3115 100644 --- a/tests/integration/view/simple/simple_test.go +++ b/tests/integration/view/simple/simple_test.go @@ -209,3 +209,52 @@ func TestView_SimpleWithExtraFieldInViewSDL(t *testing.T) { testUtils.ExecuteTestCase(t, test) } + +func TestView_SimpleWithExtraFieldInViewQuery(t *testing.T) { + test := testUtils.TestCase{ + Description: "Simple view with extra field in view query", + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String + age: Int + } + `, + }, + testUtils.CreateView{ + // `age` is present in the query but not the SDL + Query: ` + User { + name + age + } + `, + SDL: ` + type UserView { + name: String + } + `, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "John" + }`, + }, + testUtils.Request{ + Request: `query { + UserView { + name + } + }`, + Results: []map[string]any{ + { + "name": "John", + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} From aac34315d823677203c1a0c0d5e391815deec243 Mon Sep 17 00:00:00 2001 From: Andrew Sisley Date: Thu, 11 Jan 2024 10:19:28 -0500 Subject: [PATCH 4/5] PR FIXUP - Fix indentation --- tests/integration/view/simple/simple_test.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/integration/view/simple/simple_test.go b/tests/integration/view/simple/simple_test.go index 1e0f7c3115..802e281391 100644 --- a/tests/integration/view/simple/simple_test.go +++ b/tests/integration/view/simple/simple_test.go @@ -242,11 +242,13 @@ func TestView_SimpleWithExtraFieldInViewQuery(t *testing.T) { }`, }, testUtils.Request{ - Request: `query { - UserView { - name - } - }`, + Request: ` + query { + UserView { + name + } + } + `, Results: []map[string]any{ { "name": "John", From a797d41a3083f2b088558370a62bb44456602aee Mon Sep 17 00:00:00 2001 From: Andrew Sisley Date: Thu, 11 Jan 2024 10:20:25 -0500 Subject: [PATCH 5/5] PR FIXUP - Fix test description --- tests/integration/view/one_to_many/simple_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/view/one_to_many/simple_test.go b/tests/integration/view/one_to_many/simple_test.go index 68949f6999..249254c585 100644 --- a/tests/integration/view/one_to_many/simple_test.go +++ b/tests/integration/view/one_to_many/simple_test.go @@ -242,7 +242,7 @@ func TestView_OneToManyOuterToInnerToOuter_Errors(t *testing.T) { func TestView_OneToManyWithRelationInQueryButNotInSDL(t *testing.T) { test := testUtils.TestCase{ - Description: "One to many view", + Description: "One to many view with relation in query but not SDL", Actions: []any{ testUtils.SchemaUpdate{ Schema: `