Skip to content

Commit

Permalink
Fix(GraphQL): Add filter in DQL query in case of reverse predicate (#…
Browse files Browse the repository at this point in the history
…7728)

* Add code

* Fix GraphQL schemagen with reverse Dgraph predicates (#7689)

(cherry picked from commit f7c199e)

* Add yaml test

* Fix tests

(cherry picked from commit 1743501)
  • Loading branch information
vmrajas committed Apr 16, 2021
1 parent f7c199e commit da0f1a6
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 3 deletions.
18 changes: 18 additions & 0 deletions graphql/resolve/query_rewriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ func aggregateQuery(query schema.Query, authRw *authRewriter) []*gql.GraphQuery
// var(func: type(Tweets)) {
// scoreVar as Tweets.score
// }

mainQuery.Children = append(mainQuery.Children, child)
isAggregateFieldVisited[constructedForField] = true
}
Expand Down Expand Up @@ -1042,6 +1043,12 @@ func buildAggregateFields(

// addedAggregateFields is a map from aggregate field name to boolean
addedAggregateField := make(map[string]bool)
// Add type filter in case the Dgraph predicate for which the aggregate
// field belongs to is a reverse edge
if strings.HasPrefix(constructedForDgraphPredicate, "~") {
addTypeFilter(mainField, f.ConstructedFor())
}

// isAggregateFieldVisited is a map from field name to boolean. It is used to
// ensure that a field is added to Var query at maximum once.
// Eg. Even if scoreMax and scoreMin are queried, the corresponding field will
Expand All @@ -1056,6 +1063,11 @@ func buildAggregateFields(
}
// Add filter to count aggregation field.
_ = addFilter(aggregateChild, constructedForType, fieldFilter)
// Add type filter in case the Dgraph predicate for which the aggregate
// field belongs to is a reverse edge
if strings.HasPrefix(constructedForDgraphPredicate, "~") {
addTypeFilter(aggregateChild, f.ConstructedFor())
}
aggregateChildren = append(aggregateChildren, aggregateChild)

// Iterate over fields queried inside aggregate.
Expand Down Expand Up @@ -1268,6 +1280,12 @@ func addSelectionSetFrom(
if includeField := addFilter(child, f.Type(), filter); !includeField {
continue
}

// Add type filter in case the Dgraph predicate is a reverse edge
if strings.HasPrefix(f.DgraphPredicate(), "~") {
addTypeFilter(child, f.Type())
}

addOrder(child, f)
addPagination(child, f)
addCascadeDirective(child, f)
Expand Down
52 changes: 50 additions & 2 deletions graphql/resolve/query_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2395,7 +2395,7 @@
query {
queryMovie(func: type(Movie)) {
name : Movie.name
director : ~directed.movies {
director : ~directed.movies @filter(type(MovieDirector)) {
name : MovieDirector.name
dgraph.uid : uid
}
Expand Down Expand Up @@ -3183,4 +3183,52 @@
name : Author.name
dgraph.uid : uid
}
}
}
-
name: "Query fields linked to reverse predicates in Dgraph"
gqlquery: |
query {
queryLinkX(filter:{f9:{eq: "Alice"}}) {
f1(filter: {f6: {eq: "Eve"}}) {
f6
}
f2(filter: {f7: {eq: "Bob"}}) {
f7
}
f1Aggregate(filter: {f6: {eq: "Eve"}}) {
count
f6Max
}
f2Aggregate(filter: {f7: {eq: "Bob"}}) {
count
f7Min
}
}
}
dgquery: |-
query {
queryLinkX(func: type(LinkX)) @filter(eq(LinkX.f9, "Alice")) {
f1 : ~link @filter((eq(LinkY.f6, "Eve") AND type(LinkY))) {
f6 : LinkY.f6
dgraph.uid : uid
}
f2 : ~link @filter((eq(LinkZ.f7, "Bob") AND type(LinkZ))) {
f7 : LinkZ.f7
dgraph.uid : uid
}
f1Aggregate : ~link @filter((eq(LinkY.f6, "Eve") AND type(LinkY))) {
f1Aggregate_f6Var as LinkY.f6
dgraph.uid : uid
}
count_f1Aggregate : count(~link) @filter((eq(LinkY.f6, "Eve") AND type(LinkY)))
f6Max_f1Aggregate : max(val(f1Aggregate_f6Var))
f2Aggregate : ~link @filter((eq(LinkZ.f7, "Bob") AND type(LinkZ))) {
f2Aggregate_f7Var as LinkZ.f7
dgraph.uid : uid
}
count_f2Aggregate : count(~link) @filter((eq(LinkZ.f7, "Bob") AND type(LinkZ)))
f7Min_f2Aggregate : min(val(f2Aggregate_f7Var))
dgraph.uid : uid
}
}
16 changes: 15 additions & 1 deletion graphql/resolve/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -378,4 +378,18 @@ type Workflow {

type Node {
name: String!
}
}

type LinkX {
f9: String! @id
f1: [LinkY] @dgraph(pred: "~link")
f2: [LinkZ] @dgraph(pred: "~link")
}
type LinkY {
f6: String! @id
f3: [LinkX] @dgraph(pred: "link")
}
type LinkZ {
f7: String! @id
f4: [LinkX] @dgraph(pred: "link")
}
13 changes: 13 additions & 0 deletions graphql/schema/gqlschema_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3121,3 +3121,16 @@ valid_schemas:
type Z {
f4: [X] @dgraph(pred: "link")
}
- name: "Same reverse dgraph predicate can be used by two different GraphQL fields"
input: |
type X {
f1: [Y] @dgraph(pred: "~link")
f2: [Z] @dgraph(pred: "~link")
}
type Y {
f3: [X] @dgraph(pred: "link")
}
type Z {
f4: [X] @dgraph(pred: "link")
}

0 comments on commit da0f1a6

Please sign in to comment.