From 6f786518cd2a22799e09b998756499bae7d41d8a Mon Sep 17 00:00:00 2001 From: Jatin Dev <64803093+JatinDevDG@users.noreply.github.com> Date: Wed, 10 Mar 2021 22:53:35 +0530 Subject: [PATCH] fix(GRAPHQL): Added support for exact index on field having @id directive. (#7534) Currently we add hash index on a field of type String! @id by default. And as index exact and hash are not compatible , user can't add exact index on such field and can't take advantage of comparator functions like lt,le,gt,ge. To allow this we now changing that behavior, i.e. for a field of type String! @id @search(by:[exact]) , we don't generate default hash index and only generate exact index. (cherry picked from commit 195f2474cca437027fe1ad6868f7bcb7b645eb0f) --- graphql/schema/dgraph_schemagen_test.yml | 19 +++++++++++++++ graphql/schema/gqlschema.go | 10 ++------ graphql/schema/gqlschema_test.yml | 6 +++++ graphql/schema/schemagen.go | 24 ++++++++++--------- .../input/field-with-id-directive.graphql | 3 ++- .../output/field-with-id-directive.graphql | 4 ++-- 6 files changed, 44 insertions(+), 22 deletions(-) diff --git a/graphql/schema/dgraph_schemagen_test.yml b/graphql/schema/dgraph_schemagen_test.yml index 3555b13d581..0f9796d9ee0 100644 --- a/graphql/schema/dgraph_schemagen_test.yml +++ b/graphql/schema/dgraph_schemagen_test.yml @@ -494,6 +494,25 @@ schemas: } B.correct: bool @index(bool) . + - name: "Field with @id directive and a exact arg in search directive generates correct schema." + input: | + interface A { + id: String! @id @search(by: [exact]) + } + type B implements A { + correct: Boolean @search + } + output: | + type A { + A.id + } + A.id: string @index(exact) @upsert . + type B { + A.id + B.correct + } + B.correct: bool @index(bool) . + - name: "Field with reverse predicate in dgraph directive adds @reverse to predicate." input: | diff --git a/graphql/schema/gqlschema.go b/graphql/schema/gqlschema.go index 0e672f2ded1..7156769c3ff 100644 --- a/graphql/schema/gqlschema.go +++ b/graphql/schema/gqlschema.go @@ -1648,14 +1648,8 @@ func addHashIfRequired(fld *ast.FieldDefinition, indexes []string) []string { id := fld.Directives.ForName(idDirective) if id != nil { // If @id directive is applied along with @search, we check if the search has hash as an - // arg. If it doesn't, then we add it. - containsHash := false - for _, index := range indexes { - if index == "hash" { - containsHash = true - } - } - if !containsHash { + // arg. If it doesn't and there is no exact arg, then we add hash in it. + if !x.HasString(indexes, "hash") && !x.HasString(indexes, "exact") { indexes = append(indexes, "hash") } } diff --git a/graphql/schema/gqlschema_test.yml b/graphql/schema/gqlschema_test.yml index d9fa401c169..f9eb7673f4b 100644 --- a/graphql/schema/gqlschema_test.yml +++ b/graphql/schema/gqlschema_test.yml @@ -2838,6 +2838,12 @@ valid_schemas: f2: String! @id } + - name: "field with @id directive can have exact index" + input: | + type X { + f1: String! @id @search(by:[exact]) + } + - name: "Type implements from two interfaces where both have ID" input: | interface X { diff --git a/graphql/schema/schemagen.go b/graphql/schema/schemagen.go index fc505b054b6..9e97a29f43b 100644 --- a/graphql/schema/schemagen.go +++ b/graphql/schema/schemagen.go @@ -637,6 +637,16 @@ func genDgSchema(gqlSch *ast.Schema, definitions []string) string { var indexes []string upsertStr := "" search := f.Directives.ForName(searchDirective) + if search != nil { + arg := search.Arguments.ForName(searchArgs) + if arg != nil { + indexes = append(indexes, getAllSearchIndexes(arg.Value)...) + } else { + indexes = append(indexes, supportedSearches[defaultSearches[f.Type. + Name()]].dgIndex) + } + } + id := f.Directives.ForName(idDirective) if id != nil || f.Type.Name() == "ID" { upsertStr = "@upsert " @@ -646,17 +656,9 @@ func genDgSchema(gqlSch *ast.Schema, definitions []string) string { case "Float": indexes = append(indexes, "float") case "String", "ID": - indexes = append(indexes, "hash") - } - } - - if search != nil { - arg := search.Arguments.ForName(searchArgs) - if arg != nil { - indexes = append(indexes, getAllSearchIndexes(arg.Value)...) - } else { - indexes = append(indexes, supportedSearches[defaultSearches[f.Type. - Name()]].dgIndex) + if !x.HasString(indexes, "exact") { + indexes = append(indexes, "hash") + } } } diff --git a/graphql/schema/testdata/schemagen/input/field-with-id-directive.graphql b/graphql/schema/testdata/schemagen/input/field-with-id-directive.graphql index 9f9bfaa58c9..19676b1d59e 100644 --- a/graphql/schema/testdata/schemagen/input/field-with-id-directive.graphql +++ b/graphql/schema/testdata/schemagen/input/field-with-id-directive.graphql @@ -13,5 +13,6 @@ type Author { } type Genre { - name: String! @id + # This will add exact index on name field, overwriting the default "hash" index for field of type "String! @id". + name: String! @id @search(by: [exact]) } diff --git a/graphql/schema/testdata/schemagen/output/field-with-id-directive.graphql b/graphql/schema/testdata/schemagen/output/field-with-id-directive.graphql index 87397d9f074..953cd61e262 100755 --- a/graphql/schema/testdata/schemagen/output/field-with-id-directive.graphql +++ b/graphql/schema/testdata/schemagen/output/field-with-id-directive.graphql @@ -18,7 +18,7 @@ type Author { } type Genre { - name: String! @id + name: String! @id @search(by: [exact]) } ####################### @@ -430,7 +430,7 @@ input AuthorRef { } input GenreFilter { - name: StringHashFilter + name: StringExactFilter has: [GenreHasFilter] and: [GenreFilter] or: [GenreFilter]