From 8e25086f53726c2ca4b61b36eae97c111900b7df Mon Sep 17 00:00:00 2001 From: Islam Aleiv Date: Mon, 6 May 2024 16:32:38 +0200 Subject: [PATCH] Remove limit for fetching secondary docs --- planner/type_join.go | 9 +- tests/integration/index/docs.go | 2 +- .../index/query_with_relation_filter_test.go | 112 +++++++++++++++++- 3 files changed, 114 insertions(+), 9 deletions(-) diff --git a/planner/type_join.go b/planner/type_join.go index f93a8fe7db..efc6750299 100644 --- a/planner/type_join.go +++ b/planner/type_join.go @@ -294,7 +294,7 @@ func (n *typeJoinOne) Kind() string { return "typeJoinOne" } -func fetchDocsWithFieldValue(plan planNode, fieldName string, val any, limit uint) ([]core.Doc, error) { +func fetchDocsWithFieldValue(plan planNode, fieldName string, val any) ([]core.Doc, error) { propIndex := plan.DocumentMap().FirstIndexOfName(fieldName) setSubTypeFilterToScanNode(plan, propIndex, val) @@ -302,7 +302,7 @@ func fetchDocsWithFieldValue(plan planNode, fieldName string, val any, limit uin return nil, NewErrSubTypeInit(err) } - docs := make([]core.Doc, 0, limit) + var docs []core.Doc for { next, err := plan.Next() if err != nil { @@ -313,10 +313,6 @@ func fetchDocsWithFieldValue(plan planNode, fieldName string, val any, limit uin } docs = append(docs, plan.Value()) - - if limit > 0 && len(docs) >= int(limit) { - break - } } return docs, nil @@ -587,7 +583,6 @@ func (join *invertibleTypeJoin) Next() (bool, error) { // otherwise the user would not have been able to request it. join.dir.secondaryField.Value(), firstDoc.GetID(), - join.secondaryFetchLimit, ) if err != nil { return false, err diff --git a/tests/integration/index/docs.go b/tests/integration/index/docs.go index 379ad5a8a1..cd53dd2f39 100644 --- a/tests/integration/index/docs.go +++ b/tests/integration/index/docs.go @@ -216,7 +216,7 @@ func getUserDocs() predefined.DocsList { }, { "model": "Playstation 5", - "year": 2022, + "year": 2021, "type": "game_console", "specs": map[string]any{ "CPU": 3.5, diff --git a/tests/integration/index/query_with_relation_filter_test.go b/tests/integration/index/query_with_relation_filter_test.go index 8fb6500eef..06a097dac9 100644 --- a/tests/integration/index/query_with_relation_filter_test.go +++ b/tests/integration/index/query_with_relation_filter_test.go @@ -265,7 +265,7 @@ func TestQueryWithIndexOnOneToOnePrimaryRelation_IfFilterOnIndexedFieldOfRelatio }, testUtils.Request{ Request: makeExplainQuery(req2), - Asserter: testUtils.NewExplainAsserter().WithFieldFetches(15).WithIndexFetches(3), + Asserter: testUtils.NewExplainAsserter().WithFieldFetches(33).WithIndexFetches(3), }, }, } @@ -553,3 +553,113 @@ func TestQueryWithIndexOnOneToOne_IfFilterOnIndexedRelation_ShouldFilter(t *test testUtils.ExecuteTestCase(t, test) } + +func TestQueryWithIndexOnManyToOne_IfFilterOnIndexedField_ShouldFilterWithExplain(t *testing.T) { + req := `query { + Device(filter: { + year: {_eq: 2021} + }) { + model + owner { + name + } + } + }` + test := testUtils.TestCase{ + Description: "With filter on indexed field of secondary relation (N-1) should fetch secondary and primary objects", + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String + devices: [Device] + } + + type Device { + model: String + year: Int @index + owner: User + } + `, + }, + testUtils.CreatePredefinedDocs{ + Docs: getUserDocs(), + }, + testUtils.Request{ + Request: req, + Results: []map[string]any{ + { + "model": "Playstation 5", + "owner": map[string]any{ + "name": "Islam", + }, + }, + { + "model": "Playstation 5", + "owner": map[string]any{ + "name": "Addo", + }, + }, + { + "model": "iPhone 10", + "owner": map[string]any{ + "name": "Addo", + }, + }, + }, + }, + testUtils.Request{ + Request: makeExplainQuery(req), + Asserter: testUtils.NewExplainAsserter().WithFieldFetches(9).WithIndexFetches(3), + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestQueryWithIndexOnManyToOne_IfFilterOnIndexedRelation_ShouldFilterWithExplain(t *testing.T) { + req := `query { + Device(filter: { + owner: {age: {_eq: 48}} + }) { + model + } + }` + test := testUtils.TestCase{ + Description: "Upon querying secondary object with filter on indexed field of primary relation (in 1-N) should fetch all secondary objects of the same primary one", + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String + age: Int @index + devices: [Device] + } + + type Device { + model: String + owner: User + } + `, + }, + testUtils.CreatePredefinedDocs{ + Docs: getUserDocs(), + }, + testUtils.Request{ + Request: req, + Results: []map[string]any{ + {"model": "iPad Mini"}, + {"model": "iPhone 13"}, + {"model": "MacBook Pro"}, + }, + }, + testUtils.Request{ + Request: makeExplainQuery(req), + Asserter: testUtils.NewExplainAsserter().WithFieldFetches(44).WithIndexFetches(1), + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +}