Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(i): Handle field in view query but not view SDL #2192

Merged
merged 5 commits into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions core/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
5 changes: 4 additions & 1 deletion planner/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
64 changes: 64 additions & 0 deletions tests/integration/view/one_to_many/simple_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 with relation 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 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)
}
55 changes: 55 additions & 0 deletions tests/integration/view/one_to_many/with_count_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
100 changes: 100 additions & 0 deletions tests/integration/view/simple/simple_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,103 @@ 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)
}

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)
}
Loading