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(DGRAPH): fix @normalize response when multiple fields at different levels with same alias are selected. #7639

Merged
merged 16 commits into from Mar 30, 2021
Merged
68 changes: 66 additions & 2 deletions query/outputnode.go
Expand Up @@ -150,6 +150,67 @@ func newEncoder() *encoder {
return e
}

// Sort the given fastJson list
func (enc *encoder) MergeSort(headRef *fastJsonNode) {
head := *headRef
JatinDev543 marked this conversation as resolved.
Show resolved Hide resolved
var a fastJsonNode
var b fastJsonNode

if headRef == nil || head.next == nil {
return
}

frontBackSplit(head, &a, &b)

enc.MergeSort(&a)
enc.MergeSort(&b)

*headRef = enc.sortedMerge(a, b)
}

func (enc *encoder) sortedMerge(a fastJsonNode, b fastJsonNode) fastJsonNode {
var result fastJsonNode

if a == nil {
return b
} else if b == nil {
return a
}

if enc.less(a, b) {
result = a
result.next = enc.sortedMerge(a.next, b)
} else {
result = b
result.next = enc.sortedMerge(a, b.next)
}
return result
}

func (enc *encoder) less(i fastJsonNode, j fastJsonNode) bool {
attri := enc.getAttr(i)
attrj := enc.getAttr(j)
return strings.Compare(enc.attrForID(attri), enc.attrForID(attrj)) <= 0
}

func frontBackSplit(source fastJsonNode,
frontRef *fastJsonNode, backRef *fastJsonNode) {
slow := source
fast := source.next

for fast != nil {
fast = fast.next
if fast != nil {
slow = slow.next
fast = fast.next
}
}

*frontRef = source
*backRef = slow.next
slow.next = nil
}

func (enc *encoder) idForAttr(attr string) uint16 {
if attr == "uid" && enc.uidAttr > 0 {
return enc.uidAttr
Expand Down Expand Up @@ -891,8 +952,11 @@ func (enc *encoder) normalize(fj fastJsonNode) ([]fastJsonNode, error) {
}
}

for _, slice := range parentSlice {
// From every slice we need to remove node with attribute "uid".
for i, slice := range parentSlice {
// sort the fastJson list
// This will ensure that nodes with same attribute name comes together in response
enc.MergeSort(&parentSlice[i])
JatinDev543 marked this conversation as resolved.
Show resolved Hide resolved
// From every list we need to remove node with attribute "uid".
var prev, cur fastJsonNode
cur = slice
for cur != nil {
Expand Down
64 changes: 64 additions & 0 deletions query/query2_test.go
Expand Up @@ -1841,6 +1841,70 @@ func TestNormalizeDirective(t *testing.T) {
}`, js)
}

func TestNormalizeDirectiveWithRecurseDirective(t *testing.T) {
query := `
{
me(func: uid(0x01)) @recurse @normalize {
n: name
d: dob
friend
}
}`

js := processQueryNoErr(t, query)
require.JSONEq(t, `
{
"data": {
"me": [
{
"n": [
"Michonne",
"Rick Grimes",
"Michonne"
],
"d": [
"1910-01-01T00:00:00Z",
"1910-01-02T00:00:00Z",
"1910-01-01T00:00:00Z"
]
},
{
"n": [
"Michonne",
"Glenn Rhee"
],
"d": [
"1910-01-01T00:00:00Z",
"1909-05-05T00:00:00Z"
]
},
{
"n": [
"Michonne",
"Daryl Dixon"
],
"d": [
"1910-01-01T00:00:00Z",
"1909-01-10T00:00:00Z"
]
},
{
"n": [
"Michonne",
"Andrea",
"Glenn Rhee"
],
"d": [
"1910-01-01T00:00:00Z",
"1901-01-15T00:00:00Z",
"1909-05-05T00:00:00Z"
]
}
]
}
}`, js)
}

func TestNormalizeDirectiveSubQueryLevel1(t *testing.T) {
query := `
{
Expand Down