diff --git a/cmd/dgraph/main_test.go b/cmd/dgraph/main_test.go index cad94040efa..0c45818d04f 100644 --- a/cmd/dgraph/main_test.go +++ b/cmd/dgraph/main_test.go @@ -375,11 +375,11 @@ func TestDeletePredicate(t *testing.T) { require.JSONEq(t, `{"data":{"schema":[{"predicate":"_predicate_","type":"string","list":true},{"predicate":"age","type":"default"},{"predicate":"friend","type":"uid","reverse":true},{"predicate":"name","type":"string","index":true,"tokenizer":["term"]}]}}`, output) output, err = runQuery(q1) - require.JSONEq(t, `{"data": {}}`, output) + require.JSONEq(t, `{"data": {"user": []}}`, output) output, err = runQuery(q2) require.NoError(t, err) - require.JSONEq(t, `{"data": {}}`, output) + require.JSONEq(t, `{"data": {"user": []}}`, output) output, err = runQuery(q5) require.NoError(t, err) @@ -812,11 +812,11 @@ func TestDeleteAll(t *testing.T) { output, err = runQuery(q1) require.NoError(t, err) - require.JSONEq(t, `{"data": {}}`, output) + require.JSONEq(t, `{"data": {"user": []}}`, output) output, err = runQuery(q2) require.NoError(t, err) - require.JSONEq(t, `{"data": {}}`, output) + require.JSONEq(t, `{"data": {"user": []}}`, output) } func TestDeleteAllSP(t *testing.T) { @@ -928,15 +928,15 @@ func TestDeleteAllSP(t *testing.T) { output, err = runQuery(q1) require.NoError(t, err) - require.JSONEq(t, `{"data": {}}`, output) + require.JSONEq(t, `{"data": {"user": []}}`, output) output, err = runQuery(q2) require.NoError(t, err) - require.JSONEq(t, `{"data": {}}`, output) + require.JSONEq(t, `{"data": {"user": []}}`, output) output, err = runQuery(q3) require.NoError(t, err) - require.JSONEq(t, `{"data": {}}`, + require.JSONEq(t, `{"data": {"user": []}}`, output) } @@ -986,7 +986,7 @@ func TestSchemaValidationError(t *testing.T) { _, err := gql.Parse(gql.Request{Str: m5, Http: true}) require.Error(t, err) output := processToFastJSON(strings.Replace(q5, "", "0x8", -1)) - require.JSONEq(t, `{"data": {}}`, output) + require.JSONEq(t, `{"data": {"user": []}}`, output) } var m6 = ` @@ -1737,7 +1737,7 @@ func TestDeleteAllSP2(t *testing.T) { q := fmt.Sprintf(` { - all_tracked_days(func: uid(%s)) { + me(func: uid(%s)) { _predicate_ name date @@ -1749,7 +1749,7 @@ func TestDeleteAllSP2(t *testing.T) { output, err = runQuery(q) require.NoError(t, err) - require.Equal(t, `{"data": {"all_tracked_days":[{"_predicate_":["name","date","weightUnit","postMortem","lifeLoad","weight","stressLevel","nodeType","plan"],"name":"July 3 2017","date":"2017-07-03T03:49:03+00:00","weight":"262.3","lifeLoad":"5","stressLevel":"3"}]}}`, output) + require.Equal(t, `{"data": {"me":[{"_predicate_":["name","date","weightUnit","postMortem","lifeLoad","weight","stressLevel","nodeType","plan"],"name":"July 3 2017","date":"2017-07-03T03:49:03+00:00","weight":"262.3","lifeLoad":"5","stressLevel":"3"}]}}`, output) m = fmt.Sprintf(` mutation { @@ -1763,7 +1763,7 @@ func TestDeleteAllSP2(t *testing.T) { output, err = runQuery(q) require.NoError(t, err) - require.Equal(t, `{"data": {}}`, output) + require.Equal(t, `{"data": {"me":[]}}`, output) } func TestMain(m *testing.M) { diff --git a/query/outputnode.go b/query/outputnode.go index 16685295049..70ffaaf3475 100644 --- a/query/outputnode.go +++ b/query/outputnode.go @@ -677,10 +677,13 @@ func processNodeUids(n *fastJsonNode, sg *SubGraph) error { } if sg.uidMatrix == nil { + n.AddListChild(sg.Params.Alias, &fastJsonNode{}) return nil } + hasChild := false if sg.Params.uidCount != "" { + hasChild = true n.addCountAtRoot(sg) } @@ -709,6 +712,7 @@ func processNodeUids(n *fastJsonNode, sg *SubGraph) error { continue } + hasChild = true if !sg.Params.Normalize { n.AddListChild(sg.Params.Alias, n1) continue @@ -723,6 +727,11 @@ func processNodeUids(n *fastJsonNode, sg *SubGraph) error { n.AddListChild(sg.Params.Alias, &fastJsonNode{attrs: c}) } } + + if !hasChild { + // So that we return an empty key if the root didn't have any children. + n.AddListChild(sg.Params.Alias, &fastJsonNode{}) + } return nil } diff --git a/query/query_test.go b/query/query_test.go index 8f8c4e45e61..1c36d06afba 100644 --- a/query/query_test.go +++ b/query/query_test.go @@ -1117,7 +1117,7 @@ func TestQueryVarValOrderDescMissing(t *testing.T) { } ` js := processToFastJSON(t, query) - require.JSONEq(t, `{"data": {}}`, js) + require.JSONEq(t, `{"data": {"me": []}}`, js) } func TestGroupByRootProto(t *testing.T) { @@ -1352,14 +1352,12 @@ func TestMultiEmptyBlocks(t *testing.T) { you(func: uid(0x01)) { } - me(func: uid( 0x02)) { + me(func: uid(0x02)) { } } ` js := processToFastJSON(t, query) - require.JSONEq(t, - `{"data": {}}`, - js) + require.JSONEq(t, `{"data": {"you": [], "me": []}}`, js) } func TestUseVarsMultiCascade1(t *testing.T) { @@ -1748,7 +1746,7 @@ func TestNestedFuncRoot3(t *testing.T) { } ` js := processToFastJSON(t, query) - require.JSONEq(t, `{"data": {}}`, js) + require.JSONEq(t, `{"data": { "me": []}}`, js) } func TestNestedFuncRoot4(t *testing.T) { @@ -1840,7 +1838,7 @@ func TestRecurseVariable(t *testing.T) { ` js := processToFastJSON(t, query) - require.Equal(t, `{"data": {"me":[{"name":"Michonne"},{"name":"Rick Grimes"},{"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"name":"Andrea"}]}}`, js) + require.Equal(t, `{"data": {"recurse":[],"me":[{"name":"Michonne"},{"name":"Rick Grimes"},{"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"name":"Andrea"}]}}`, js) } func TestRecurseVariable2(t *testing.T) { @@ -1864,7 +1862,7 @@ func TestRecurseVariable2(t *testing.T) { } ` js := processToFastJSON(t, query) - require.Equal(t, `{"data": {"me":[{"name":"Glenn Rhee"},{"name":"Andrea"},{"name":"Alice"},{"name":"Bob"},{"name":"Matt"},{"name":"John"}],"me2":[{"name":"Michonne"},{"name":"Rick Grimes"},{"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"name":"Andrea"}]}}`, js) + require.Equal(t, `{"data": {"recurse":[],"me":[{"name":"Glenn Rhee"},{"name":"Andrea"},{"name":"Alice"},{"name":"Bob"},{"name":"Matt"},{"name":"John"}],"me2":[{"name":"Michonne"},{"name":"Rick Grimes"},{"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"name":"Andrea"}]}}`, js) } func TestShortestPath_ExpandError(t *testing.T) { @@ -1902,9 +1900,7 @@ func TestShortestPath_NoPath(t *testing.T) { } }` js := processToFastJSON(t, query) - require.JSONEq(t, - `{"data": {}}`, - js) + require.JSONEq(t, `{"data": {"me": []}}`, js) } func TestKShortestPath_NoPath(t *testing.T) { @@ -1922,9 +1918,7 @@ func TestKShortestPath_NoPath(t *testing.T) { } }` js := processToFastJSON(t, query) - require.JSONEq(t, - `{"data": {}}`, - js) + require.JSONEq(t, `{"data": {"me": []}}`, js) } func TestKShortestPathWeighted(t *testing.T) { @@ -2173,9 +2167,7 @@ func TestShortestPath_filter2(t *testing.T) { } }` js := processToFastJSON(t, query) - require.JSONEq(t, - `{"data": {}}`, - js) + require.JSONEq(t, `{"data": { "me": []}}`, js) } func TestUseVarsFilterMultiId(t *testing.T) { @@ -3642,8 +3634,7 @@ func TestFilterRegex13(t *testing.T) { // no results are returned, becaues case insensive mode is turned off before 'ISSION' js := processToFastJSON(t, query) - require.JSONEq(t, - `{"data": {}}`, js) + require.JSONEq(t, `{"data": {"me": []}}`, js) } // invalid regexp modifier @@ -6423,9 +6414,7 @@ func TestLangSingleFallback(t *testing.T) { } ` js := processToFastJSON(t, query) - require.JSONEq(t, - `{"data": {}}`, - js) + require.JSONEq(t, `{"data": {"me": []}}`, js) } func TestLangMany1(t *testing.T) { @@ -6483,9 +6472,7 @@ func TestLangManyFallback(t *testing.T) { } ` js := processToFastJSON(t, query) - require.JSONEq(t, - `{"data": {}}`, - js) + require.JSONEq(t, `{"data": {"me": []}}`, js) } func TestLangNoFallbackNoDefault(t *testing.T) { @@ -6498,9 +6485,7 @@ func TestLangNoFallbackNoDefault(t *testing.T) { } ` js := processToFastJSON(t, query) - require.JSONEq(t, - `{"data": {}}`, - js) + require.JSONEq(t, `{"data": {"me": []}}`, js) } func TestLangSingleNoFallbackNoDefault(t *testing.T) { @@ -6513,9 +6498,7 @@ func TestLangSingleNoFallbackNoDefault(t *testing.T) { } ` js := processToFastJSON(t, query) - require.JSONEq(t, - `{"data": {}}`, - js) + require.JSONEq(t, `{"data": {"me": []}}`, js) } func TestLangMultipleNoFallbackNoDefault(t *testing.T) { @@ -6528,9 +6511,7 @@ func TestLangMultipleNoFallbackNoDefault(t *testing.T) { } ` js := processToFastJSON(t, query) - require.JSONEq(t, - `{"data": {}}`, - js) + require.JSONEq(t, `{"data": {"me": []}}`, js) } func TestLangOnlyForcedFallbackNoDefault(t *testing.T) { @@ -6606,9 +6587,7 @@ func TestLangFilterMismatch1(t *testing.T) { } ` js := processToFastJSON(t, query) - require.JSONEq(t, - `{"data": {}}`, - js) + require.JSONEq(t, `{"data": {"me": []}}`, js) } func TestLangFilterMismatch2(t *testing.T) { @@ -6621,9 +6600,7 @@ func TestLangFilterMismatch2(t *testing.T) { } ` js := processToFastJSON(t, query) - require.JSONEq(t, - `{"data": {}}`, - js) + require.JSONEq(t, `{"data": {"me": []}}`, js) } func TestLangFilterMismatch3(t *testing.T) { @@ -6636,9 +6613,7 @@ func TestLangFilterMismatch3(t *testing.T) { } ` js := processToFastJSON(t, query) - require.JSONEq(t, - `{"data": {}}`, - js) + require.JSONEq(t, `{"data": {"me": []}}`, js) } func TestLangFilterMismatch5(t *testing.T) { @@ -6666,9 +6641,7 @@ func TestLangFilterMismatch6(t *testing.T) { } ` js := processToFastJSON(t, query) - require.JSONEq(t, - `{"data": {}}`, - js) + require.JSONEq(t, `{"data": {"me": []}}`, js) } func TestLangLossyIndex1(t *testing.T) { @@ -6714,9 +6687,7 @@ func TestLangLossyIndex3(t *testing.T) { } ` js := processToFastJSON(t, query) - require.JSONEq(t, - `{"data": {}}`, - js) + require.JSONEq(t, `{"data": {"me": []}}`, js) } func TestLangLossyIndex4(t *testing.T) { @@ -6757,9 +6728,7 @@ func TestLangBug1295(t *testing.T) { json, err := processToFastJsonReq(t, query) require.NoError(t, err) if l == "" { - require.JSONEq(t, - `{"data": {}}`, - json) + require.JSONEq(t, `{"data": {"q": []}}`, json) } else { require.JSONEq(t, `{"data": {"q":[{"royal_title@en":"Her Majesty Elizabeth the Second, by the Grace of God of the United Kingdom of Great Britain and Northern Ireland and of Her other Realms and Territories Queen, Head of the Commonwealth, Defender of the Faith"}]}}`, @@ -9127,7 +9096,7 @@ func TestMathCeil1(t *testing.T) { } ` js := processToFastJSON(t, query) - require.JSONEq(t, `{"data": {}}`, js) + require.JSONEq(t, `{"data": {"me": []}}`, js) } func TestMathCeil2(t *testing.T) { @@ -9162,7 +9131,7 @@ func TestAppendDummyValuesPanic(t *testing.T) { } }` js := processToFastJSON(t, query) - require.JSONEq(t, `{"data": {}}`, js) + require.JSONEq(t, `{"data": {"n": []}}`, js) } func TestMultipleValueFilter(t *testing.T) { @@ -9464,7 +9433,7 @@ func TestFilterRootOverride(t *testing.T) { } ` js := processToFastJSON(t, query) - require.JSONEq(t, `{"data": {}}`, js) + require.JSONEq(t, `{"data": {"me": []}}`, js) } func TestFilterRoot(t *testing.T) { @@ -9478,7 +9447,7 @@ func TestFilterRoot(t *testing.T) { } ` js := processToFastJSON(t, query) - require.JSONEq(t, `{"data": {}}`, js) + require.JSONEq(t, `{"data": {"me": []}}`, js) } func TestMathAlias(t *testing.T) { @@ -9533,3 +9502,20 @@ func TestMultipleValueVarError(t *testing.T) { require.Error(t, err) require.Contains(t, err.Error(), "Value variables not supported for predicate with list type.") } + +func TestReturnEmptyBlock(t *testing.T) { + populateGraph(t) + query := `{ + me(func:allofterms(name, "Michonne")) @filter(eq(name, "Rick Grimes")) { + } + + me2(func: eq(name, "XYZ")) + + me3(func: eq(name, "Michonne")) { + name + } + }` + + js := processToFastJSON(t, query) + require.JSONEq(t, `{"data": {"me":[],"me2":[],"me3":[{"name":"Michonne"}]}}`, js) +}