github.com/unigraph-dev/dgraph@v1.1.1-0.20200923154953-8b52b426f765/query/query0_test.go (about)

     1  /*
     2   * Copyright 2018 Dgraph Labs, Inc. and Contributors
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package query
    18  
    19  import (
    20  	"os"
    21  	"testing"
    22  
    23  	context "golang.org/x/net/context"
    24  
    25  	"github.com/stretchr/testify/require"
    26  
    27  	"github.com/dgraph-io/dgo"
    28  	"github.com/dgraph-io/dgraph/gql"
    29  	"github.com/dgraph-io/dgraph/testutil"
    30  )
    31  
    32  func TestGetUID(t *testing.T) {
    33  	query := `
    34  		{
    35  			me(func: uid(0x01)) {
    36  				name
    37  				uid
    38  				gender
    39  				alive
    40  				friend {
    41  					uid
    42  					name
    43  				}
    44  			}
    45  		}
    46  	`
    47  	js := processQueryNoErr(t, query)
    48  	require.JSONEq(t,
    49  		`{"data": {"me":[{"uid":"0x1","alive":true,"friend":[{"uid":"0x17","name":"Rick Grimes"},{"uid":"0x18","name":"Glenn Rhee"},{"uid":"0x19","name":"Daryl Dixon"},{"uid":"0x1f","name":"Andrea"},{"uid":"0x65"}],"gender":"female","name":"Michonne"}]}}`,
    50  		js)
    51  }
    52  
    53  func TestQueryEmptyDefaultNames(t *testing.T) {
    54  	query := `{
    55  	  people(func: eq(name, "")) {
    56  		uid
    57  		name
    58  	  }
    59  	}`
    60  	js := processQueryNoErr(t, query)
    61  	// only two empty names should be retrieved as the other one is empty in a particular lang.
    62  	require.JSONEq(t,
    63  		`{"data":{"people": [{"uid":"0xdac","name":""}, {"uid":"0xdae","name":""}]}}`,
    64  		js)
    65  }
    66  
    67  func TestQueryEmptyDefaultNameWithLanguage(t *testing.T) {
    68  	query := `{
    69  	  people(func: eq(name, "")) {
    70  		name@ko:en:hi
    71  	  }
    72  	}`
    73  	js := processQueryNoErr(t, query)
    74  	require.JSONEq(t,
    75  		`{"data":{"people": [{"name@ko:en:hi":"상현"},{"name@ko:en:hi":"Amit"}]}}`,
    76  		js)
    77  }
    78  
    79  func TestQueryNamesThatAreEmptyInLanguage(t *testing.T) {
    80  	query := `{
    81  	  people(func: eq(name@hi, "")) {
    82  		name@en
    83  	  }
    84  	}`
    85  	js := processQueryNoErr(t, query)
    86  	require.JSONEq(t,
    87  		`{"data":{"people": [{"name@en":"Andrew"}]}}`,
    88  		js)
    89  }
    90  
    91  func TestQueryNamesInLanguage(t *testing.T) {
    92  	query := `{
    93  	  people(func: eq(name@hi, "अमित")) {
    94  		name@en
    95  	  }
    96  	}`
    97  	js := processQueryNoErr(t, query)
    98  	require.JSONEq(t,
    99  		`{"data":{"people": [{"name@en":"Amit"}]}}`,
   100  		js)
   101  }
   102  
   103  func TestQueryAllLanguages(t *testing.T) {
   104  	query := `{
   105  	  people(func: eq(name@hi, "अमित")) {
   106  		name@*
   107  	  }
   108  	}`
   109  	js := processQueryNoErr(t, query)
   110  	require.JSONEq(t,
   111  		`{"data":{"people": [{"name@en":"Amit", "name@hi":"अमित", "name":""}]}}`,
   112  		js)
   113  }
   114  
   115  func TestQueryNamesBeforeA(t *testing.T) {
   116  	query := `{
   117  	  people(func: lt(name, "A")) {
   118  		uid
   119  		name
   120  	  }
   121  	}`
   122  	js := processQueryNoErr(t, query)
   123  	// only two empty names should be retrieved as the other one is empty in a particular lang.
   124  	require.JSONEq(t,
   125  		`{"data":{"people": [{"uid":"0xdac", "name":""}, {"uid":"0xdae", "name":""}]}}`,
   126  		js)
   127  }
   128  
   129  func TestQueryNamesCompareEmpty(t *testing.T) {
   130  	tests := []struct {
   131  		in, out string
   132  	}{
   133  		{in: `{q(func: lt(name, "")) { name }}`,
   134  			out: `{"data":{"q": []}}`},
   135  		{in: `{q(func: le(name, "")) { uid name }}`,
   136  			out: `{"data":{"q": [{"uid":"0xdac", "name":""}, {"uid":"0xdae", "name":""}]}}`},
   137  		{in: `{q(func: gt(name, ""), first:3) { name }}`,
   138  			out: `{"data":{"q": [{"name":"Michonne"}, {"name":"King Lear"}, {"name":"Margaret"}]}}`},
   139  		{in: `{q(func: ge(name, ""), first:3, after:0x91d) { name }}`,
   140  			out: `{"data":{"q": [{"name":""}, {"name":"Alex"}, {"name":""}]}}`},
   141  	}
   142  	for _, tc := range tests {
   143  		js := processQueryNoErr(t, tc.in)
   144  		require.JSONEq(t, tc.out, js)
   145  	}
   146  }
   147  
   148  func TestQueryCountEmptyNames(t *testing.T) {
   149  	tests := []struct {
   150  		in, out, failure string
   151  	}{
   152  		{in: `{q(func: has(name)) @filter(eq(name, "")) {count(uid)}}`,
   153  			out: `{"data":{"q": [{"count":2}]}}`},
   154  		{in: `{q(func: has(name)) @filter(gt(name, "")) {count(uid)}}`,
   155  			out: `{"data":{"q": [{"count":46}]}}`},
   156  		{in: `{q(func: has(name)) @filter(ge(name, "")) {count(uid)}}`,
   157  			out: `{"data":{"q": [{"count":48}]}}`},
   158  		{in: `{q(func: has(name)) @filter(lt(name, "")) {count(uid)}}`,
   159  			out: `{"data":{"q": [{"count":0}]}}`},
   160  		{in: `{q(func: has(name)) @filter(le(name, "")) {count(uid)}}`,
   161  			out: `{"data":{"q": [{"count":2}]}}`},
   162  		{in: `{q(func: has(name)) @filter(anyofterms(name, "")) {count(uid)}}`,
   163  			out: `{"data":{"q": [{"count":2}]}}`},
   164  		{in: `{q(func: has(name)) @filter(allofterms(name, "")) {count(uid)}}`,
   165  			out: `{"data":{"q": [{"count":2}]}}`},
   166  		// NOTE: match with empty string filters values greater than the max distance.
   167  		{in: `{q(func: has(name)) @filter(match(name, "", 8)) {count(uid)}}`,
   168  			out: `{"data":{"q": [{"count":28}]}}`},
   169  		{in: `{q(func: has(name)) @filter(uid_in(name, "")) {count(uid)}}`,
   170  			failure: `Value "" in uid_in is not a number`},
   171  	}
   172  	for _, tc := range tests {
   173  		js, err := processQuery(context.Background(), t, tc.in)
   174  		if tc.failure != "" {
   175  			require.Error(t, err)
   176  			require.Contains(t, err.Error(), tc.failure)
   177  		} else {
   178  			require.NoError(t, err)
   179  			require.JSONEq(t, tc.out, js)
   180  		}
   181  	}
   182  }
   183  
   184  func TestQueryEmptyRoomsWithTermIndex(t *testing.T) {
   185  	query := `{
   186  		  offices(func: has(office)) {
   187  			count(office.room @filter(eq(room, "")))
   188  		  }
   189  		}`
   190  	js := processQueryNoErr(t, query)
   191  	require.JSONEq(t,
   192  		`{"data":{"offices": [{"count(office.room)":1}]}}`,
   193  		js)
   194  }
   195  
   196  func TestQueryCountEmptyNamesWithLang(t *testing.T) {
   197  	query := `{
   198  	  people_empty_name(func: has(name@hi)) @filter(eq(name@hi, "")) {
   199  		count(uid)
   200  	  }
   201  	}`
   202  	js := processQueryNoErr(t, query)
   203  	require.JSONEq(t,
   204  		`{"data":{"people_empty_name": [{"count":1}]}}`,
   205  		js)
   206  }
   207  
   208  func TestStocksStartsWithAInPortfolio(t *testing.T) {
   209  	query := `{
   210  	  portfolio(func: lt(symbol, "B")) {
   211  		symbol
   212  	  }
   213  	}`
   214  	js := processQueryNoErr(t, query)
   215  	require.JSONEq(t,
   216  		`{"data":{"portfolio": [{"symbol":"AAPL"},{"symbol":"AMZN"},{"symbol":"AMD"}]}}`,
   217  		js)
   218  }
   219  
   220  func TestFindFriendsWhoAreBetween15And19(t *testing.T) {
   221  	query := `{
   222  	  friends_15_and_19(func: uid(1)) {
   223  		name
   224  		friend @filter(ge(age, 15) AND lt(age, 19)) {
   225  			name
   226  			age
   227  	    }
   228        }
   229  	}`
   230  	js := processQueryNoErr(t, query)
   231  	require.JSONEq(t,
   232  		`{"data":{"friends_15_and_19":[{"name":"Michonne","friend":[{"name":"Rick Grimes","age":15},{"name":"Glenn Rhee","age":15},{"name":"Daryl Dixon","age":17}]}]}}`,
   233  		js)
   234  }
   235  
   236  func TestGetNonListUidPredicate(t *testing.T) {
   237  	query := `
   238  		{
   239  			me(func: uid(0x02)) {
   240  				uid
   241  				best_friend {
   242  					uid
   243  				}
   244  			}
   245  		}
   246  	`
   247  	js := processQueryNoErr(t, query)
   248  	require.JSONEq(t,
   249  		`{"data": {"me":[{"uid":"0x2", "best_friend": {"uid": "0x40"}}]}}`,
   250  		js)
   251  }
   252  
   253  func TestNonListUidPredicateReverse1(t *testing.T) {
   254  	query := `
   255  		{
   256  			me(func: uid(0x40)) {
   257  				uid
   258  				~best_friend {
   259  					uid
   260  				}
   261  			}
   262  		}
   263  	`
   264  	js := processQueryNoErr(t, query)
   265  	require.JSONEq(t,
   266  		`{"data": {"me":[{"uid":"0x40", "~best_friend": [{"uid":"0x2"},{"uid":"0x3"},{"uid":"0x4"}]}]}}`,
   267  		js)
   268  }
   269  
   270  func TestNonListUidPredicateReverse2(t *testing.T) {
   271  	query := `
   272  		{
   273  			me(func: uid(0x40)) {
   274  				uid
   275  				~best_friend {
   276  					pet {
   277  						name
   278  					}
   279  					uid
   280  				}
   281  			}
   282  		}
   283  	`
   284  	js := processQueryNoErr(t, query)
   285  	require.JSONEq(t,
   286  		`{"data": {"me":[{"uid":"0x40", "~best_friend": [
   287  			{"uid":"0x2","pet":[{"name":"Garfield"}]},
   288  			{"uid":"0x3","pet":[{"name":"Bear"}]},
   289  			{"uid":"0x4","pet":[{"name":"Nemo"}]}]}]}}`,
   290  		js)
   291  }
   292  
   293  func TestGeAge(t *testing.T) {
   294  	query := `{
   295  		  senior_citizens(func: ge(age, 75)) {
   296  			name
   297  			age
   298  		  }
   299  	}`
   300  	js := processQueryNoErr(t, query)
   301  	require.JSONEq(t,
   302  		`{"data":{"senior_citizens": [{"name":"Elizabeth", "age":75}, {"name":"Alice", "age":75}, {"age":75, "name":"Bob"}, {"name":"Alice", "age":75}]}}`,
   303  		js)
   304  }
   305  
   306  func TestGtAge(t *testing.T) {
   307  	query := `
   308      {
   309  			senior_citizens(func: gt(age, 75)) {
   310  				name
   311  				age
   312  			}
   313      }`
   314  	js := processQueryNoErr(t, query)
   315  	require.JSONEq(t, `{"data": {"senior_citizens":[]}}`, js)
   316  }
   317  
   318  func TestLeAge(t *testing.T) {
   319  	query := `{
   320  		  minors(func: le(age, 15)) {
   321  			name
   322  			age
   323  		  }
   324  	}`
   325  	js := processQueryNoErr(t, query)
   326  	require.JSONEq(t,
   327  		`{"data":{"minors": [{"name":"Rick Grimes", "age":15}, {"name":"Glenn Rhee", "age":15}]}}`,
   328  		js)
   329  }
   330  
   331  func TestLtAge(t *testing.T) {
   332  	query := `
   333      {
   334  			minors(func: Lt(age, 15)) {
   335  				name
   336  				age
   337  			}
   338      }`
   339  	js := processQueryNoErr(t, query)
   340  	require.JSONEq(t, `{"data": {"minors":[]}}`, js)
   341  }
   342  
   343  func TestGetUIDInDebugMode(t *testing.T) {
   344  	query := `
   345  		{
   346  			me(func: uid(0x01)) {
   347  				name
   348  				uid
   349  				gender
   350  				alive
   351  				friend {
   352  					uid
   353  					name
   354  				}
   355  			}
   356  		}
   357  	`
   358  
   359  	ctx := context.Background()
   360  	ctx = context.WithValue(ctx, DebugKey, "true")
   361  	js, err := processQuery(ctx, t, query)
   362  	require.NoError(t, err)
   363  	require.JSONEq(t,
   364  		`{"data": {"me":[{"uid":"0x1","alive":true,"friend":[{"uid":"0x17","name":"Rick Grimes"},{"uid":"0x18","name":"Glenn Rhee"},{"uid":"0x19","name":"Daryl Dixon"},{"uid":"0x1f","name":"Andrea"},{"uid":"0x65"}],"gender":"female","name":"Michonne"}]}}`,
   365  		js)
   366  
   367  }
   368  
   369  func TestReturnUids(t *testing.T) {
   370  	query := `
   371  		{
   372  			me(func: uid(0x01)) {
   373  				name
   374  				uid
   375  				gender
   376  				alive
   377  				friend {
   378  					uid
   379  					name
   380  				}
   381  			}
   382  		}
   383  	`
   384  	js := processQueryNoErr(t, query)
   385  	require.JSONEq(t,
   386  		`{"data": {"me":[{"uid":"0x1","alive":true,"friend":[{"uid":"0x17","name":"Rick Grimes"},{"uid":"0x18","name":"Glenn Rhee"},{"uid":"0x19","name":"Daryl Dixon"},{"uid":"0x1f","name":"Andrea"},{"uid":"0x65"}],"gender":"female","name":"Michonne"}]}}`,
   387  		js)
   388  }
   389  
   390  func TestGetUIDNotInChild(t *testing.T) {
   391  	query := `
   392  		{
   393  			me(func: uid(0x01)) {
   394  				name
   395  				uid
   396  				gender
   397  				alive
   398  				friend {
   399  					name
   400  				}
   401  			}
   402  		}
   403  	`
   404  	js := processQueryNoErr(t, query)
   405  	require.JSONEq(t,
   406  		`{"data": {"me":[{"uid":"0x1","alive":true,"gender":"female","name":"Michonne", "friend":[{"name":"Rick Grimes"},{"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"name":"Andrea"}]}]}}`,
   407  		js)
   408  }
   409  
   410  func TestCascadeDirective(t *testing.T) {
   411  	query := `
   412  		{
   413  			me(func: uid(0x01)) @cascade {
   414  				name
   415  				gender
   416  				friend {
   417  					name
   418  					friend{
   419  						name
   420  						dob
   421  						age
   422  					}
   423  				}
   424  			}
   425  		}
   426  	`
   427  
   428  	js := processQueryNoErr(t, query)
   429  	require.JSONEq(t, `{"data": {"me":[{"friend":[{"friend":[{"age":38,"dob":"1910-01-01T00:00:00Z","name":"Michonne"}],"name":"Rick Grimes"},{"friend":[{"age":15,"dob":"1909-05-05T00:00:00Z","name":"Glenn Rhee"}],"name":"Andrea"}],"gender":"female","name":"Michonne"}]}}`,
   430  		js)
   431  }
   432  
   433  func TestLevelBasedFacetVarAggSum(t *testing.T) {
   434  	query := `
   435  		{
   436  			friend(func: uid(1000)) {
   437  				path @facets(L1 as weight)
   438  				sumw: sum(val(L1))
   439  			}
   440  		}
   441  	`
   442  	js := processQueryNoErr(t, query)
   443  	require.JSONEq(t,
   444  		`{"data":{"friend":[{"path":[{"path|weight":0.100000},{"path|weight":0.700000}],"sumw":0.800000}]}}`,
   445  		js)
   446  }
   447  
   448  func TestLevelBasedFacetVarSum(t *testing.T) {
   449  	query := `
   450  		{
   451  			friend(func: uid(1000)) {
   452  				path @facets(L1 as weight) {
   453  						path @facets(L2 as weight) {
   454  							c as count(follow)
   455  							L4 as math(c+L2+L1)
   456  						}
   457  				}
   458  			}
   459  
   460  			sum(func: uid(L4), orderdesc: val(L4)) {
   461  				name
   462  				val(L4)
   463  			}
   464  		}
   465  	`
   466  	js := processQueryNoErr(t, query)
   467  	require.JSONEq(t, `{"data":{"friend":[{"path":[{"path":[{"count(follow)":1,"val(L4)":1.200000,"path|weight":0.100000},{"count(follow)":1,"val(L4)":3.900000,"path|weight":1.500000}],"path|weight":0.100000},{"path":[{"count(follow)":1,"val(L4)":3.900000,"path|weight":0.600000}],"path|weight":0.700000}]}],"sum":[{"name":"John","val(L4)":3.900000},{"name":"Matt","val(L4)":1.200000}]}}`,
   468  		js)
   469  }
   470  
   471  func TestLevelBasedSumMix1(t *testing.T) {
   472  	query := `
   473  		{
   474  			friend(func: uid( 1)) {
   475  				a as age
   476  				path @facets(L1 as weight) {
   477  					L2 as math(a+L1)
   478  			 	}
   479  			}
   480  			sum(func: uid(L2), orderdesc: val(L2)) {
   481  				name
   482  				val(L2)
   483  			}
   484  		}
   485  	`
   486  	js := processQueryNoErr(t, query)
   487  	require.JSONEq(t,
   488  		`{"data":{"friend":[{"age":38,"path":[{"val(L2)":38.200000,"path|weight":0.200000},{"val(L2)":38.100000,"path|weight":0.100000}]}],"sum":[{"name":"Glenn Rhee","val(L2)":38.200000},{"name":"Andrea","val(L2)":38.100000}]}}`,
   489  		js)
   490  }
   491  
   492  func TestLevelBasedFacetVarSum1(t *testing.T) {
   493  	query := `
   494  		{
   495  			friend(func: uid( 1000)) {
   496  				path @facets(L1 as weight) {
   497  					name
   498  					path @facets(L2 as weight) {
   499  						L3 as math(L1+L2)
   500  					}
   501  			 }
   502  			}
   503  			sum(func: uid(L3), orderdesc: val(L3)) {
   504  				name
   505  				val(L3)
   506  			}
   507  		}
   508  	`
   509  	js := processQueryNoErr(t, query)
   510  	require.JSONEq(t,
   511  		`{"data":{"friend":[{"path":[{"name":"Bob","path":[{"val(L3)":0.200000,"path|weight":0.100000},{"val(L3)":2.900000,"path|weight":1.500000}],"path|weight":0.100000},{"name":"Matt","path":[{"val(L3)":2.900000,"path|weight":0.600000}],"path|weight":0.700000}]}],"sum":[{"name":"John","val(L3)":2.900000},{"name":"Matt","val(L3)":0.200000}]}}`,
   512  		js)
   513  }
   514  
   515  func TestLevelBasedFacetVarSum2(t *testing.T) {
   516  	query := `
   517  		{
   518  			friend(func: uid( 1000)) {
   519  				path @facets(L1 as weight) {
   520  					path @facets(L2 as weight) {
   521  						path @facets(L3 as weight) {
   522  							L4 as math(L1+L2+L3)
   523  						}
   524  					}
   525  				}
   526  			}
   527  			sum(func: uid(L4), orderdesc: val(L4)) {
   528  				name
   529  				val(L4)
   530  			}
   531  		}
   532  	`
   533  	js := processQueryNoErr(t, query)
   534  	require.JSONEq(t,
   535  		`{"data":{"friend":[{"path":[{"path":[{"path":[{"val(L4)":0.800000,"path|weight":0.600000}],"path|weight":0.100000},{"path":[{"val(L4)":2.900000}],"path|weight":1.500000}],"path|weight":0.100000},{"path":[{"path":[{"val(L4)":2.900000}],"path|weight":0.600000}],"path|weight":0.700000}]}],"sum":[{"name":"Bob","val(L4)":2.900000},{"name":"John","val(L4)":0.800000}]}}`,
   536  		js)
   537  }
   538  
   539  func TestQueryConstMathVal(t *testing.T) {
   540  	query := `
   541  		{
   542  			f as var(func: anyofterms(name, "Rick Michonne Andrea")) {
   543  				a as math(24/8 * 3)
   544  			}
   545  
   546  			AgeOrder(func: uid(f)) {
   547  				name
   548  				val(a)
   549  			}
   550  		}
   551  	`
   552  	js := processQueryNoErr(t, query)
   553  	require.JSONEq(t,
   554  		`{"data": {"AgeOrder":[{"name":"Michonne","val(a)":9.000000},{"name":"Rick Grimes","val(a)":9.000000},{"name":"Andrea","val(a)":9.000000},{"name":"Andrea With no friends","val(a)":9.000000}]}}`,
   555  		js)
   556  }
   557  
   558  func TestQueryVarValAggSince(t *testing.T) {
   559  	query := `
   560  		{
   561  			f as var(func: anyofterms(name, "Michonne Andrea Rick")) {
   562  				a as dob
   563  				b as math(since(a)/(60*60*24*365))
   564  			}
   565  
   566  			AgeOrder(func: uid(f), orderasc: val(b)) {
   567  				name
   568  				val(a)
   569  			}
   570  		}
   571  	`
   572  	js := processQueryNoErr(t, query)
   573  	require.JSONEq(t,
   574  		`{"data": {"AgeOrder":[{"name":"Rick Grimes","val(a)":"1910-01-02T00:00:00Z"},{"name":"Michonne","val(a)":"1910-01-01T00:00:00Z"},{"name":"Andrea","val(a)":"1901-01-15T00:00:00Z"}]}}`,
   575  		js)
   576  }
   577  
   578  func TestQueryVarValAggNestedFuncConst(t *testing.T) {
   579  	query := `
   580  		{
   581  			f as var(func: anyofterms(name, "Michonne Andrea Rick")) {
   582  				a as age
   583  				friend {
   584  					x as age
   585  				}
   586  				n as min(val(x))
   587  				s as max(val(x))
   588  				p as math(a + s % n + 10)
   589  				q as math(a * s * n * -1)
   590  			}
   591  
   592  			MaxMe(func: uid(f), orderasc: val(p)) {
   593  				name
   594  				val(p)
   595  				val(a)
   596  				val(n)
   597  				val(s)
   598  			}
   599  
   600  			MinMe(func: uid(f), orderasc: val(q)) {
   601  				name
   602  				val(q)
   603  				val(a)
   604  				val(n)
   605  				val(s)
   606  			}
   607  		}
   608  	`
   609  	js := processQueryNoErr(t, query)
   610  	require.JSONEq(t,
   611  		`{"data": {"MaxMe":[{"name":"Rick Grimes","val(a)":15,"val(n)":38,"val(p)":25.000000,"val(s)":38},{"name":"Andrea","val(a)":19,"val(n)":15,"val(p)":29.000000,"val(s)":15},{"name":"Michonne","val(a)":38,"val(n)":15,"val(p)":52.000000,"val(s)":19}],"MinMe":[{"name":"Rick Grimes","val(a)":15,"val(n)":38,"val(q)":-21660.000000,"val(s)":38},{"name":"Michonne","val(a)":38,"val(n)":15,"val(q)":-10830.000000,"val(s)":19},{"name":"Andrea","val(a)":19,"val(n)":15,"val(q)":-4275.000000,"val(s)":15}]}}`,
   612  		js)
   613  }
   614  
   615  func TestQueryVarValAggNestedFuncMinMaxVars(t *testing.T) {
   616  	query := `
   617  		{
   618  			f as var(func: anyofterms(name, "Michonne Andrea Rick")) {
   619  				a as age
   620  				friend {
   621  					x as age
   622  				}
   623  				n as min(val(x))
   624  				s as max(val(x))
   625  				p as math(max(max(a, s), n))
   626  				q as math(min(min(a, s), n))
   627  			}
   628  
   629  			MaxMe(func: uid(f), orderasc: val(p)) {
   630  				name
   631  				val(p)
   632  				val(a)
   633  				val(n)
   634  				val(s)
   635  			}
   636  
   637  			MinMe(func: uid(f), orderasc: val(q)) {
   638  				name
   639  				val(q)
   640  				val(a)
   641  				val(n)
   642  				val(s)
   643  			}
   644  		}
   645  	`
   646  	js := processQueryNoErr(t, query)
   647  	require.JSONEq(t,
   648  		`{"data": {"MinMe":[{"name":"Michonne","val(a)":38,"val(n)":15,"val(q)":15,"val(s)":19},{"name":"Rick Grimes","val(a)":15,"val(n)":38,"val(q)":15,"val(s)":38},{"name":"Andrea","val(a)":19,"val(n)":15,"val(q)":15,"val(s)":15}],"MaxMe":[{"name":"Andrea","val(a)":19,"val(n)":15,"val(p)":19,"val(s)":15},{"name":"Michonne","val(a)":38,"val(n)":15,"val(p)":38,"val(s)":19},{"name":"Rick Grimes","val(a)":15,"val(n)":38,"val(p)":38,"val(s)":38}]}}`,
   649  		js)
   650  }
   651  
   652  func TestQueryVarValAggNestedFuncConditional(t *testing.T) {
   653  	query := `
   654  	{
   655  			f as var(func: anyofterms(name, "Michonne Andrea Rick")) {
   656  				a as age
   657  				friend {
   658  					x as age
   659  				}
   660  				n as min(val(x))
   661  				condLog as math(cond(a > 10, logbase(n, 5), 1))
   662  				condExp as math(cond(a < 40, 1, pow(2, n)))
   663  			}
   664  
   665  			LogMe(func: uid(f), orderasc: val(condLog)) {
   666  				name
   667  				val(condLog)
   668  				val(n)
   669  				val(a)
   670  			}
   671  
   672  			ExpMe(func: uid(f), orderasc: val(condExp)) {
   673  				name
   674  				val(condExp)
   675  				val(n)
   676  				val(a)
   677  			}
   678  		}
   679  	`
   680  	js := processQueryNoErr(t, query)
   681  	require.JSONEq(t,
   682  		`{"data": {"ExpMe":[{"name":"Michonne","val(a)":38,"val(condExp)":1.000000,"val(n)":15},{"name":"Rick Grimes","val(a)":15,"val(condExp)":1.000000,"val(n)":38},{"name":"Andrea","val(a)":19,"val(condExp)":1.000000,"val(n)":15}],"LogMe":[{"name":"Michonne","val(a)":38,"val(condLog)":1.682606,"val(n)":15},{"name":"Andrea","val(a)":19,"val(condLog)":1.682606,"val(n)":15},{"name":"Rick Grimes","val(a)":15,"val(condLog)":2.260159,"val(n)":38}]}}`,
   683  		js)
   684  }
   685  
   686  func TestQueryVarValAggNestedFuncConditional2(t *testing.T) {
   687  	query := `
   688  		{
   689  			f as var(func: anyofterms(name, "Michonne Andrea Rick")) {
   690  				a as age
   691  				friend {
   692  					x as age
   693  				}
   694  				n as min(val(x))
   695  				condLog as math(cond(a==38, n/2, 1))
   696  				condExp as math(cond(a!=38, 1, sqrt(2*n)))
   697  			}
   698  
   699  			LogMe(func: uid(f), orderasc: val(condLog)) {
   700  				name
   701  				val(condLog)
   702  				val(n)
   703  				val(a)
   704  			}
   705  
   706  			ExpMe(func: uid(f), orderasc: val(condExp)) {
   707  				name
   708  				val(condExp)
   709  				val(n)
   710  				val(a)
   711  			}
   712  		}
   713  	`
   714  	js := processQueryNoErr(t, query)
   715  	require.JSONEq(t,
   716  		`{"data": {"ExpMe":[{"name":"Rick Grimes","val(a)":15,"val(condExp)":1.000000,"val(n)":38},{"name":"Andrea","val(a)":19,"val(condExp)":1.000000,"val(n)":15},{"name":"Michonne","val(a)":38,"val(condExp)":5.477226,"val(n)":15}],"LogMe":[{"name":"Rick Grimes","val(a)":15,"val(condLog)":1.000000,"val(n)":38},{"name":"Andrea","val(a)":19,"val(condLog)":1.000000,"val(n)":15},{"name":"Michonne","val(a)":38,"val(condLog)":7.500000,"val(n)":15}]}}`,
   717  		js)
   718  }
   719  
   720  func TestQueryVarValAggNestedFuncUnary(t *testing.T) {
   721  	query := `
   722  		{
   723  			f as var(func: anyofterms(name, "Michonne Andrea Rick")) {
   724  				a as age
   725  				friend {
   726  					x as age
   727  				}
   728  				n as min(val(x))
   729  				s as max(val(x))
   730  				combiLog as math(a + ln(s - n))
   731  				combiExp as math(a + exp(s - n))
   732  			}
   733  
   734  			LogMe(func: uid(f), orderasc: val(combiLog)) {
   735  				name
   736  				val(combiLog)
   737  				val(a)
   738  				val(n)
   739  				val(s)
   740  			}
   741  
   742  			ExpMe(func: uid(f), orderasc: val(combiExp)) {
   743  				name
   744  				val(combiExp)
   745  				val(a)
   746  				val(n)
   747  				val(s)
   748  			}
   749  		}
   750  	`
   751  	js := processQueryNoErr(t, query)
   752  	require.JSONEq(t,
   753  		`{"data": {"ExpMe":[{"name":"Rick Grimes","val(a)":15,"val(combiExp)":16.000000,"val(n)":38,"val(s)":38},{"name":"Andrea","val(a)":19,"val(combiExp)":20.000000,"val(n)":15,"val(s)":15},{"name":"Michonne","val(a)":38,"val(combiExp)":92.598150,"val(n)":15,"val(s)":19}],"LogMe":[{"name":"Rick Grimes","val(a)":15,"val(combiLog)":-179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.000000,"val(n)":38,"val(s)":38},{"name":"Andrea","val(a)":19,"val(combiLog)":-179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.000000,"val(n)":15,"val(s)":15},{"name":"Michonne","val(a)":38,"val(combiLog)":39.386294,"val(n)":15,"val(s)":19}]}}`,
   754  		js)
   755  }
   756  
   757  func TestQueryVarValAggNestedFunc(t *testing.T) {
   758  	query := `
   759  		{
   760  			f as var(func: anyofterms(name, "Michonne Andrea Rick")) {
   761  				a as age
   762  				friend {
   763  					x as age
   764  				}
   765  				n as min(val(x))
   766  				s as max(val(x))
   767  				combi as math(a + n * s)
   768  			}
   769  
   770  			me(func: uid(f), orderasc: val(combi)) {
   771  				name
   772  				val(combi)
   773  				val(a)
   774  				val(n)
   775  				val(s)
   776  			}
   777  		}
   778  	`
   779  	js := processQueryNoErr(t, query)
   780  	require.JSONEq(t,
   781  		`{"data": {"me":[{"name":"Andrea","val(a)":19,"val(combi)":244,"val(n)":15,"val(s)":15},{"name":"Michonne","val(a)":38,"val(combi)":323,"val(n)":15,"val(s)":19},{"name":"Rick Grimes","val(a)":15,"val(combi)":1459,"val(n)":38,"val(s)":38}]}}`,
   782  		js)
   783  }
   784  
   785  func TestQueryVarValAggMinMaxSelf(t *testing.T) {
   786  	query := `
   787  		{
   788  			f as var(func: anyofterms(name, "Michonne Andrea Rick")) {
   789  				a as age
   790  				friend {
   791  					x as age
   792  				}
   793  				n as min(val(x))
   794  				s as max(val(x))
   795  				sum as math(n +  a + s)
   796  			}
   797  
   798  			me(func: uid(f), orderasc: val(sum)) {
   799  				name
   800  				val(sum)
   801  				val(s)
   802  			}
   803  		}
   804  	`
   805  	js := processQueryNoErr(t, query)
   806  	require.JSONEq(t,
   807  		`{"data": {"me":[{"name":"Andrea","val(s)":15,"val(sum)":49},{"name":"Michonne","val(s)":19,"val(sum)":72},{"name":"Rick Grimes","val(s)":38,"val(sum)":91}]}}`,
   808  		js)
   809  }
   810  
   811  func TestQueryVarValAggMinMax(t *testing.T) {
   812  	query := `
   813  		{
   814  			f as var(func: anyofterms(name, "Michonne Andrea Rick")) {
   815  				friend {
   816  					x as age
   817  				}
   818  				n as min(val(x))
   819  				s as max(val(x))
   820  				sum as math(n + s)
   821  			}
   822  
   823  			me(func: uid(f), orderdesc: val(sum)) {
   824  				name
   825  				val(n)
   826  				val(s)
   827  			}
   828  		}
   829  	`
   830  	js := processQueryNoErr(t, query)
   831  	require.JSONEq(t,
   832  		`{"data": {"me":[{"name":"Rick Grimes","val(n)":38,"val(s)":38},{"name":"Michonne","val(n)":15,"val(s)":19},{"name":"Andrea","val(n)":15,"val(s)":15}]}}`,
   833  		js)
   834  }
   835  
   836  func TestQueryVarValAggMinMaxAlias(t *testing.T) {
   837  	query := `
   838  		{
   839  			f as var(func: anyofterms(name, "Michonne Andrea Rick")) {
   840  				friend {
   841  					x as age
   842  				}
   843  				n as min(val(x))
   844  				s as max(val(x))
   845  				sum as math(n + s)
   846  			}
   847  
   848  			me(func: uid(f), orderdesc: val(sum)) {
   849  				name
   850  				MinAge: val(n)
   851  				MaxAge: val(s)
   852  			}
   853  		}
   854  	`
   855  	js := processQueryNoErr(t, query)
   856  	require.JSONEq(t,
   857  		`{"data": {"me":[{"name":"Rick Grimes","MinAge":38,"MaxAge":38},{"name":"Michonne","MinAge":15,"MaxAge":19},{"name":"Andrea","MinAge":15,"MaxAge":15}]}}`,
   858  		js)
   859  }
   860  
   861  func TestQueryVarValAggMul(t *testing.T) {
   862  	query := `
   863  		{
   864  			var(func: uid( 1)) {
   865  				f as friend {
   866  					n as age
   867  					s as count(friend)
   868  					mul as math(n * s)
   869  				}
   870  			}
   871  
   872  			me(func: uid(f), orderdesc: val(mul)) {
   873  				name
   874  				val(s)
   875  				val(n)
   876  				val(mul)
   877  			}
   878  		}
   879  	`
   880  	js := processQueryNoErr(t, query)
   881  	require.JSONEq(t,
   882  		`{"data": {"me":[{"name":"Andrea","val(mul)":19.000000,"val(n)":19,"val(s)":1},{"name":"Rick Grimes","val(mul)":15.000000,"val(n)":15,"val(s)":1},{"name":"Glenn Rhee","val(mul)":0.000000,"val(n)":15,"val(s)":0},{"name":"Daryl Dixon","val(mul)":0.000000,"val(n)":17,"val(s)":0},{"val(mul)":0.000000,"val(s)":0}]}}`,
   883  		js)
   884  }
   885  
   886  func TestQueryVarValAggOrderDesc(t *testing.T) {
   887  	query := `
   888  		{
   889  			info(func: uid( 1)) {
   890  				f as friend {
   891  					n as age
   892  					s as count(friend)
   893  					sum as math(n + s)
   894  				}
   895  			}
   896  
   897  			me(func: uid(f), orderdesc: val(sum)) {
   898  				name
   899  				age
   900  				count(friend)
   901  			}
   902  		}
   903  	`
   904  	js := processQueryNoErr(t, query)
   905  	require.JSONEq(t,
   906  		`{"data": {"info":[{"friend":[{"age":15,"count(friend)":1,"val(sum)":16.000000},{"age":15,"count(friend)":0,"val(sum)":15.000000},{"age":17,"count(friend)":0,"val(sum)":17.000000},{"age":19,"count(friend)":1,"val(sum)":20.000000},{"count(friend)":0,"val(sum)":0.000000}]}],"me":[{"age":19,"count(friend)":1,"name":"Andrea"},{"age":17,"count(friend)":0,"name":"Daryl Dixon"},{"age":15,"count(friend)":1,"name":"Rick Grimes"},{"age":15,"count(friend)":0,"name":"Glenn Rhee"},{"count(friend)":0}]}}`,
   907  		js)
   908  }
   909  
   910  func TestQueryVarValAggOrderAsc(t *testing.T) {
   911  	query := `
   912  		{
   913  			var(func: uid( 1)) {
   914  				f as friend {
   915  					n as age
   916  					s as survival_rate
   917  					sum as math(n + s)
   918  				}
   919  			}
   920  
   921  			me(func: uid(f), orderasc: val(sum)) {
   922  				name
   923  				age
   924  				survival_rate
   925  			}
   926  		}
   927  	`
   928  	js := processQueryNoErr(t, query)
   929  	require.JSONEq(t,
   930  		`{"data": {"me":[{"age":15,"name":"Rick Grimes","survival_rate":1.600000},{"age":15,"name":"Glenn Rhee","survival_rate":1.600000},{"age":17,"name":"Daryl Dixon","survival_rate":1.600000},{"age":19,"name":"Andrea","survival_rate":1.600000}]}}`,
   931  		js)
   932  }
   933  
   934  func TestQueryVarValOrderAsc(t *testing.T) {
   935  	query := `
   936  		{
   937  			var(func: uid( 1)) {
   938  				f as friend {
   939  					n as name
   940  				}
   941  			}
   942  
   943  			me(func: uid(f), orderasc: val(n)) {
   944  				name
   945  			}
   946  		}
   947  	`
   948  	js := processQueryNoErr(t, query)
   949  	require.JSONEq(t,
   950  		`{"data": {"me":[{"name":"Andrea"},{"name":"Daryl Dixon"},{"name":"Glenn Rhee"},{"name":"Rick Grimes"}]}}`,
   951  		js)
   952  }
   953  
   954  func TestQueryVarValOrderDob(t *testing.T) {
   955  	query := `
   956  		{
   957  			var(func: uid( 1)) {
   958  				f as friend {
   959  					n as dob
   960  				}
   961  			}
   962  
   963  			me(func: uid(f), orderasc: val(n)) {
   964  				name
   965  				dob
   966  			}
   967  		}
   968  	`
   969  	js := processQueryNoErr(t, query)
   970  	require.JSONEq(t,
   971  		`{"data": {"me":[{"name":"Andrea", "dob":"1901-01-15T00:00:00Z"},{"name":"Daryl Dixon", "dob":"1909-01-10T00:00:00Z"},{"name":"Glenn Rhee", "dob":"1909-05-05T00:00:00Z"},{"name":"Rick Grimes", "dob":"1910-01-02T00:00:00Z"}]}}`,
   972  		js)
   973  }
   974  
   975  func TestQueryVarValOrderError(t *testing.T) {
   976  	query := `
   977  		{
   978  			var(func: uid( 1)) {
   979  				friend {
   980  					n as name
   981  				}
   982  			}
   983  
   984  			me(func: uid(n), orderdesc: n) {
   985  				name
   986  			}
   987  		}
   988  	`
   989  	_, err := processQuery(context.Background(), t, query)
   990  	require.Error(t, err)
   991  	require.Contains(t, err.Error(), "Cannot sort by unknown attribute n")
   992  }
   993  
   994  func TestQueryVarValOrderDesc(t *testing.T) {
   995  	query := `
   996  		{
   997  			var(func: uid( 1)) {
   998  				f as friend {
   999  					n as name
  1000  				}
  1001  			}
  1002  
  1003  			me(func: uid(f), orderdesc: val(n)) {
  1004  				name
  1005  			}
  1006  		}
  1007  	`
  1008  	js := processQueryNoErr(t, query)
  1009  	require.JSONEq(t,
  1010  		`{"data": {"me":[{"name":"Rick Grimes"},{"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"name":"Andrea"}]}}`,
  1011  		js)
  1012  }
  1013  
  1014  func TestQueryVarValOrderDescMissing(t *testing.T) {
  1015  	query := `
  1016  		{
  1017  			var(func: uid( 1034)) {
  1018  				f As friend {
  1019  					n As name
  1020  				}
  1021  			}
  1022  
  1023  			me(func: uid(f), orderdesc: val(n)) {
  1024  				name
  1025  			}
  1026  		}
  1027  	`
  1028  	js := processQueryNoErr(t, query)
  1029  	require.JSONEq(t, `{"data": {"me": []}}`, js)
  1030  }
  1031  
  1032  func TestGroupByRoot(t *testing.T) {
  1033  	query := `
  1034  	{
  1035  		me(func: uid(1, 23, 24, 25, 31)) @groupby(age) {
  1036  				count(uid)
  1037  		}
  1038  	}
  1039  	`
  1040  	js := processQueryNoErr(t, query)
  1041  	require.JSONEq(t,
  1042  		`{"data": {"me":[{"@groupby":[{"age":17,"count":1},{"age":19,"count":1},{"age":38,"count":1},{"age":15,"count":2}]}]}}`,
  1043  		js)
  1044  }
  1045  
  1046  func TestGroupByRootEmpty(t *testing.T) {
  1047  	// Predicate agent doesn't exist.
  1048  	query := `
  1049  	{
  1050  		me(func: uid(1, 23, 24, 25, 31)) @groupby(agent) {
  1051  				count(uid)
  1052  		}
  1053  	}
  1054  	`
  1055  	js := processQueryNoErr(t, query)
  1056  	require.JSONEq(t, `{"data": {}}`, js)
  1057  }
  1058  
  1059  func TestGroupByRootAlias(t *testing.T) {
  1060  	query := `
  1061  	{
  1062  		me(func: uid(1, 23, 24, 25, 31)) @groupby(age) {
  1063  			Count: count(uid)
  1064  		}
  1065  	}
  1066  	`
  1067  	js := processQueryNoErr(t, query)
  1068  	require.JSONEq(t, `{"data":{"me":[{"@groupby":[{"age":17,"Count":1},{"age":19,"Count":1},{"age":38,"Count":1},{"age":15,"Count":2}]}]}}`, js)
  1069  }
  1070  
  1071  func TestGroupByRootAlias2(t *testing.T) {
  1072  	query := `
  1073  	{
  1074  		me(func: uid(1, 23, 24, 25, 31)) @groupby(Age: age) {
  1075  			Count: count(uid)
  1076  		}
  1077  	}
  1078  	`
  1079  	js := processQueryNoErr(t, query)
  1080  	require.JSONEq(t, `{"data":{"me":[{"@groupby":[{"Age":17,"Count":1},{"Age":19,"Count":1},{"Age":38,"Count":1},{"Age":15,"Count":2}]}]}}`, js)
  1081  }
  1082  
  1083  func TestGroupBy_RepeatAttr(t *testing.T) {
  1084  	query := `
  1085  	{
  1086  		me(func: uid(1)) {
  1087  			friend @groupby(age) {
  1088  				count(uid)
  1089  			}
  1090  			friend {
  1091  				name
  1092  				age
  1093  			}
  1094  			name
  1095  		}
  1096  	}
  1097  	`
  1098  	js := processQueryNoErr(t, query)
  1099  	require.JSONEq(t,
  1100  		`{"data": {"me":[{"friend":[{"@groupby":[{"age":17,"count":1},{"age":19,"count":1},{"age":15,"count":2}]},{"age":15,"name":"Rick Grimes"},{"age":15,"name":"Glenn Rhee"},{"age":17,"name":"Daryl Dixon"},{"age":19,"name":"Andrea"}],"name":"Michonne"}]}}`,
  1101  		js)
  1102  }
  1103  
  1104  func TestGroupBy(t *testing.T) {
  1105  	query := `
  1106  	{
  1107  		age(func: uid(1)) {
  1108  			friend {
  1109  				age
  1110  				name
  1111  			}
  1112  		}
  1113  
  1114  		me(func: uid(1)) {
  1115  			friend @groupby(age) {
  1116  				count(uid)
  1117  			}
  1118  			name
  1119  		}
  1120  	}
  1121  	`
  1122  	js := processQueryNoErr(t, query)
  1123  	require.JSONEq(t,
  1124  		`{"data": {"age":[{"friend":[{"age":15,"name":"Rick Grimes"},{"age":15,"name":"Glenn Rhee"},{"age":17,"name":"Daryl Dixon"},{"age":19,"name":"Andrea"}]}],"me":[{"friend":[{"@groupby":[{"age":17,"count":1},{"age":19,"count":1},{"age":15,"count":2}]}],"name":"Michonne"}]}}`,
  1125  		js)
  1126  }
  1127  
  1128  func TestGroupByCountval(t *testing.T) {
  1129  	query := `
  1130  		{
  1131  			var(func: uid( 1)) {
  1132  				friend @groupby(school) {
  1133  					a as count(uid)
  1134  				}
  1135  			}
  1136  
  1137  			order(func :uid(a), orderdesc: val(a)) {
  1138  				name
  1139  				val(a)
  1140  			}
  1141  		}
  1142  	`
  1143  	js := processQueryNoErr(t, query)
  1144  	require.JSONEq(t,
  1145  		`{"data": {"order":[{"name":"School B","val(a)":3},{"name":"School A","val(a)":2}]}}`,
  1146  		js)
  1147  }
  1148  
  1149  func TestGroupByAggval(t *testing.T) {
  1150  	query := `
  1151  		{
  1152  			var(func: uid(1)) {
  1153  				friend @groupby(school) {
  1154  					a as max(name)
  1155  					b as min(name)
  1156  				}
  1157  			}
  1158  
  1159  			orderMax(func :uid(a), orderdesc: val(a)) {
  1160  				name
  1161  				val(a)
  1162  			}
  1163  
  1164  			orderMin(func :uid(b), orderdesc: val(b)) {
  1165  				name
  1166  				val(b)
  1167  			}
  1168  		}
  1169  	`
  1170  	js := processQueryNoErr(t, query)
  1171  	require.JSONEq(t,
  1172  		`{"data": {"orderMax":[{"name":"School B","val(a)":"Rick Grimes"},{"name":"School A","val(a)":"Glenn Rhee"}],"orderMin":[{"name":"School A","val(b)":"Daryl Dixon"},{"name":"School B","val(b)":"Andrea"}]}}`,
  1173  		js)
  1174  }
  1175  
  1176  func TestGroupByAlias(t *testing.T) {
  1177  	query := `
  1178  		{
  1179  			me(func: uid(1)) {
  1180  				friend @groupby(school) {
  1181  					MaxName: max(name)
  1182  					MinName: min(name)
  1183  					UidCount: count(uid)
  1184  				}
  1185  			}
  1186  		}
  1187  	`
  1188  	js := processQueryNoErr(t, query)
  1189  	require.JSONEq(t, `{"data":{"me":[{"friend":[{"@groupby":[{"school":"0x1388","MaxName":"Glenn Rhee","MinName":"Daryl Dixon","UidCount":2},{"school":"0x1389","MaxName":"Rick Grimes","MinName":"Andrea","UidCount":3}]}]}]}}`, js)
  1190  }
  1191  
  1192  func TestGroupByAgg(t *testing.T) {
  1193  	query := `
  1194  		{
  1195  			me(func: uid( 1)) {
  1196  				friend @groupby(age) {
  1197  					max(name)
  1198  				}
  1199  			}
  1200  		}
  1201  	`
  1202  	js := processQueryNoErr(t, query)
  1203  	require.JSONEq(t,
  1204  		`{"data": {"me":[{"friend":[{"@groupby":[{"age":17,"max(name)":"Daryl Dixon"},{"age":19,"max(name)":"Andrea"},{"age":15,"max(name)":"Rick Grimes"}]}]}]}}`,
  1205  		js)
  1206  }
  1207  
  1208  func TestGroupByMulti(t *testing.T) {
  1209  	query := `
  1210  		{
  1211  			me(func: uid(1)) {
  1212  				friend @groupby(FRIEND: friend,name) {
  1213  					count(uid)
  1214  				}
  1215  			}
  1216  		}
  1217  	`
  1218  	js := processQueryNoErr(t, query)
  1219  	require.JSONEq(t,
  1220  		`{"data": {"me":[{"friend":[{"@groupby":[{"count":1,"FRIEND":"0x1","name":"Rick Grimes"},{"count":1,"FRIEND":"0x18","name":"Andrea"}]}]}]}}`,
  1221  		js)
  1222  }
  1223  
  1224  func TestGroupByMulti2(t *testing.T) {
  1225  	query := `
  1226  		{
  1227  			me(func: uid(1)) {
  1228  				Friend: friend @groupby(Friend: friend,Name: name) {
  1229  					Count: count(uid)
  1230  				}
  1231  			}
  1232  		}
  1233  	`
  1234  	js := processQueryNoErr(t, query)
  1235  	require.JSONEq(t,
  1236  		`{"data":{"me":[{"Friend":[{"@groupby":[{"Friend":"0x1","Name":"Rick Grimes","Count":1},{"Friend":"0x18","Name":"Andrea","Count":1}]}]}]}}`,
  1237  		js)
  1238  }
  1239  
  1240  func TestGroupByMultiParents(t *testing.T) {
  1241  	query := `
  1242  		{
  1243  			me(func: uid(1,23,31)) {
  1244  				name
  1245  				friend @groupby(name, age) {
  1246  					count(uid)
  1247  				}
  1248  			}
  1249  		}
  1250  	`
  1251  	js := processQueryNoErr(t, query)
  1252  	require.JSONEq(t, `{"data":{"me":[{"name":"Michonne","friend":[{"@groupby":[{"name":"Andrea","age":19,"count":1},{"name":"Daryl Dixon","age":17,"count":1},{"name":"Glenn Rhee","age":15,"count":1},{"name":"Rick Grimes","age":15,"count":1}]}]},{"name":"Rick Grimes","friend":[{"@groupby":[{"name":"Michonne","age":38,"count":1}]}]},{"name":"Andrea","friend":[{"@groupby":[{"name":"Glenn Rhee","age":15,"count":1}]}]}]}}`, js)
  1253  }
  1254  
  1255  func TestGroupByMultiParents_2(t *testing.T) {
  1256  	// We dont have any data for uid 99999
  1257  	query := `
  1258  		{
  1259  			me(func: uid(1,23,99999,31)) {
  1260  				name
  1261  				friend @groupby(name, age) {
  1262  					count(uid)
  1263  				}
  1264  			}
  1265  		}
  1266  	`
  1267  	js := processQueryNoErr(t, query)
  1268  	require.JSONEq(t, `{"data":{"me":[{"name":"Michonne","friend":[{"@groupby":[{"name":"Andrea","age":19,"count":1},{"name":"Daryl Dixon","age":17,"count":1},{"name":"Glenn Rhee","age":15,"count":1},{"name":"Rick Grimes","age":15,"count":1}]}]},{"name":"Rick Grimes","friend":[{"@groupby":[{"name":"Michonne","age":38,"count":1}]}]},{"name":"Andrea","friend":[{"@groupby":[{"name":"Glenn Rhee","age":15,"count":1}]}]}]}}`, js)
  1269  
  1270  }
  1271  
  1272  func TestGroupByAgeMultiParents(t *testing.T) {
  1273  	// We dont have any data for uid 99999, 99998.
  1274  	query := `
  1275  		{
  1276  			me(func: uid(23,99999,31, 99998,1)) {
  1277  				name
  1278  				friend @groupby(age) {
  1279  					count(uid)
  1280  				}
  1281  			}
  1282  		}
  1283  	`
  1284  	js := processQueryNoErr(t, query)
  1285  	require.JSONEq(t, `{"data":{"me":[{"name":"Michonne","friend":[{"@groupby":[{"age":17,"count":1},{"age":19,"count":1},{"age":15,"count":2}]}]},{"name":"Rick Grimes","friend":[{"@groupby":[{"age":38,"count":1}]}]},{"name":"Andrea","friend":[{"@groupby":[{"age":15,"count":1}]}]}]}}`, js)
  1286  }
  1287  
  1288  func TestGroupByFriendsMultipleParents(t *testing.T) {
  1289  
  1290  	// We dont have any data for uid 99999, 99998.
  1291  	query := `
  1292  		{
  1293  			me(func: uid(23,99999,31, 99998,1)) {
  1294  				name
  1295  				friend @groupby(friend) {
  1296  					count(uid)
  1297  				}
  1298  			}
  1299  		}
  1300  	`
  1301  	js := processQueryNoErr(t, query)
  1302  	require.JSONEq(t, `{"data":{"me":[{"name":"Michonne","friend":[{"@groupby":[{"friend":"0x1","count":1},{"friend":"0x18","count":1}]}]},{"name":"Rick Grimes","friend":[{"@groupby":[{"friend":"0x17","count":1},{"friend":"0x18","count":1},{"friend":"0x19","count":1},{"friend":"0x1f","count":1},{"friend":"0x65","count":1}]}]},{"name":"Andrea"}]}}`, js)
  1303  }
  1304  
  1305  func TestGroupByFriendsMultipleParentsVar(t *testing.T) {
  1306  
  1307  	// We dont have any data for uid 99999, 99998.
  1308  	query := `
  1309  		{
  1310  			var(func: uid(23,99999,31, 99998,1)) {
  1311  				name
  1312  				friend @groupby(friend) {
  1313  					f as count(uid)
  1314  				}
  1315  			}
  1316  
  1317  			me(func: uid(f), orderdesc: val(f)) {
  1318  				uid
  1319  				name
  1320  				val(f)
  1321  			}
  1322  		}
  1323  	`
  1324  	js := processQueryNoErr(t, query)
  1325  	require.JSONEq(t, `{"data":{"me":[{"uid":"0x18","name":"Glenn Rhee","val(f)":2},{"uid":"0x1","name":"Michonne","val(f)":1},{"uid":"0x17","name":"Rick Grimes","val(f)":1},{"uid":"0x19","name":"Daryl Dixon","val(f)":1},{"uid":"0x1f","name":"Andrea","val(f)":1},{"uid":"0x65","val(f)":1}]}}`, js)
  1326  }
  1327  
  1328  func TestGroupBy_FixPanicForNilDestUIDs(t *testing.T) {
  1329  	// This a fix for GitHub issue #3768.
  1330  	query := `
  1331  		{
  1332  			var(func: eq(name, "abcdef")) @ignorereflex {
  1333  				random_nonexistent {
  1334  					f as uid
  1335  				}
  1336  			}
  1337  
  1338  			me(func: uid(f)) @groupby(uid) {
  1339  				a as count(uid)
  1340  			}
  1341  
  1342  			me2(func: uid(f)) {
  1343  				val(a)
  1344  			}
  1345  		}
  1346  	`
  1347  	js := processQueryNoErr(t, query)
  1348  	require.JSONEq(t, `{"data": {"me2": []}}`, js)
  1349  
  1350  }
  1351  
  1352  func TestMultiEmptyBlocks(t *testing.T) {
  1353  
  1354  	query := `
  1355  		{
  1356  			you(func: uid(0x01)) {
  1357  			}
  1358  
  1359  			me(func: uid(0x02)) {
  1360  			}
  1361  		}
  1362  	`
  1363  	js := processQueryNoErr(t, query)
  1364  	require.JSONEq(t, `{"data": {"you": [], "me": []}}`, js)
  1365  }
  1366  
  1367  func TestUseVarsMultiCascade1(t *testing.T) {
  1368  
  1369  	query := `
  1370  		{
  1371  			him(func: uid(0x01)) @cascade {
  1372  				L as friend {
  1373  					B as friend
  1374  					name
  1375  			 	}
  1376  			}
  1377  
  1378  			me(func: uid(L, B)) {
  1379  				name
  1380  			}
  1381  		}
  1382  	`
  1383  	js := processQueryNoErr(t, query)
  1384  	require.JSONEq(t,
  1385  		`{"data": {"him": [{"friend":[{"name":"Rick Grimes"}, {"name":"Andrea"}]}], "me":[{"name":"Michonne"},{"name":"Rick Grimes"},{"name":"Glenn Rhee"}, {"name":"Andrea"}]}}`,
  1386  		js)
  1387  }
  1388  
  1389  func TestUseVarsMultiCascade(t *testing.T) {
  1390  
  1391  	query := `
  1392  		{
  1393  			var(func: uid(0x01)) @cascade {
  1394  				L as friend {
  1395  				 	B as friend
  1396  				}
  1397  			}
  1398  
  1399  			me(func: uid(L, B)) {
  1400  				name
  1401  			}
  1402  		}
  1403  	`
  1404  	js := processQueryNoErr(t, query)
  1405  	require.JSONEq(t,
  1406  		`{"data": {"me":[{"name":"Michonne"},{"name":"Rick Grimes"},{"name":"Glenn Rhee"}, {"name":"Andrea"}]}}`,
  1407  		js)
  1408  }
  1409  
  1410  func TestUseVarsMultiOrder(t *testing.T) {
  1411  
  1412  	query := `
  1413  		{
  1414  			var(func: uid(0x01)) {
  1415  				L as friend(first:2, orderasc: dob)
  1416  			}
  1417  
  1418  			var(func: uid(0x01)) {
  1419  				G as friend(first:2, offset:2, orderasc: dob)
  1420  			}
  1421  
  1422  			friend1(func: uid(L)) {
  1423  				name
  1424  			}
  1425  
  1426  			friend2(func: uid(G)) {
  1427  				name
  1428  			}
  1429  		}
  1430  	`
  1431  	js := processQueryNoErr(t, query)
  1432  	require.JSONEq(t,
  1433  		`{"data": {"friend1":[{"name":"Daryl Dixon"}, {"name":"Andrea"}],"friend2":[{"name":"Rick Grimes"},{"name":"Glenn Rhee"}]}}`,
  1434  		js)
  1435  }
  1436  
  1437  func TestFilterFacetval(t *testing.T) {
  1438  
  1439  	query := `
  1440  		{
  1441  			friend(func: uid(0x01)) {
  1442  				path @facets(L as weight) {
  1443  					name
  1444  				 	friend @filter(uid(L)) {
  1445  						name
  1446  						val(L)
  1447  					}
  1448  				}
  1449  			}
  1450  		}
  1451  	`
  1452  	js := processQueryNoErr(t, query)
  1453  	require.JSONEq(t,
  1454  		`{"data":{"friend":[{"path":[{"name":"Glenn Rhee","path|weight":0.200000},{"name":"Andrea","friend":[{"name":"Glenn Rhee","val(L)":0.200000}],"path|weight":0.100000}]}]}}`,
  1455  		js)
  1456  }
  1457  
  1458  func TestFilterFacetVar1(t *testing.T) {
  1459  
  1460  	query := `
  1461  		{
  1462  			friend(func: uid(0x01)) {
  1463  				path @facets(L as weight1) {
  1464  					name
  1465  				 	friend @filter(uid(L)){
  1466  						name
  1467  					}
  1468  				}
  1469  			}
  1470  		}
  1471  	`
  1472  	js := processQueryNoErr(t, query)
  1473  	require.JSONEq(t,
  1474  		`{"data":{"friend":[{"path":[{"name":"Glenn Rhee"},{"name":"Andrea","path|weight1":0.200000}]}]}}`,
  1475  		js)
  1476  }
  1477  
  1478  func TestUseVarsFilterVarReuse1(t *testing.T) {
  1479  
  1480  	query := `
  1481  		{
  1482  			friend(func: uid(0x01)) {
  1483  				friend {
  1484  					L as friend {
  1485  						name
  1486  						friend @filter(uid(L)) {
  1487  							name
  1488  						}
  1489  					}
  1490  				}
  1491  			}
  1492  		}
  1493  	`
  1494  	js := processQueryNoErr(t, query)
  1495  	require.JSONEq(t,
  1496  		`{"data": {"friend":[{"friend":[{"friend":[{"name":"Michonne", "friend":[{"name":"Glenn Rhee"}]}]}, {"friend":[{"name":"Glenn Rhee"}]}]}]}}`,
  1497  		js)
  1498  }
  1499  
  1500  func TestUseVarsFilterVarReuse2(t *testing.T) {
  1501  
  1502  	query := `
  1503  		{
  1504  			friend(func:anyofterms(name, "Michonne Andrea Glenn")) {
  1505  				friend {
  1506  				 L as friend {
  1507  					nonexistent_pred
  1508  					name
  1509  					friend @filter(uid(L)) {
  1510  						name
  1511  					}
  1512  				}
  1513  			}
  1514  		}
  1515  	}
  1516  	`
  1517  	js := processQueryNoErr(t, query)
  1518  	require.JSONEq(t,
  1519  		`{"data": {"friend":[{"friend":[{"friend":[{"name":"Michonne", "friend":[{"name":"Glenn Rhee"}]}]}, {"friend":[{"name":"Glenn Rhee"}]}]}]}}`,
  1520  		js)
  1521  }
  1522  
  1523  func TestDoubleOrder(t *testing.T) {
  1524  
  1525  	query := `
  1526      {
  1527  		me(func: uid(1)) {
  1528  			friend(orderdesc: dob) @facets(orderasc: weight)
  1529  		}
  1530  	}
  1531    `
  1532  	_, err := processQuery(context.Background(), t, query)
  1533  	require.Error(t, err)
  1534  }
  1535  
  1536  func TestVarInAggError(t *testing.T) {
  1537  
  1538  	query := `
  1539      {
  1540  			var(func: uid( 1)) {
  1541  				friend {
  1542  					a as age
  1543  				}
  1544  			}
  1545  
  1546  			# var not allowed in min filter
  1547  			me(func: min(val(a))) {
  1548  				name
  1549  			}
  1550  		}
  1551    `
  1552  	_, err := gql.Parse(gql.Request{Str: query})
  1553  	require.Error(t, err)
  1554  	require.Contains(t, err.Error(), "Function name: min is not valid.")
  1555  }
  1556  
  1557  func TestVarInIneqError(t *testing.T) {
  1558  
  1559  	query := `
  1560      {
  1561  			var(func: uid( 1)) {
  1562  				f as friend {
  1563  					a as age
  1564  				}
  1565  			}
  1566  
  1567  			me(func: uid(f)) @filter(gt(val(a), "alice")) {
  1568  				name
  1569  			}
  1570  		}
  1571    `
  1572  	_, err := processQuery(context.Background(), t, query)
  1573  	require.Error(t, err)
  1574  }
  1575  
  1576  func TestVarInIneqScore(t *testing.T) {
  1577  
  1578  	query := `
  1579      {
  1580  			var(func: uid( 1)) {
  1581  				friend {
  1582  					a as age
  1583  					s as count(friend)
  1584  					score as math(2*a + 3 * s + 1)
  1585  				}
  1586  			}
  1587  
  1588  			me(func: ge(val(score), 35)) {
  1589  				name
  1590  				val(score)
  1591  				val(a)
  1592  				val(s)
  1593  			}
  1594  		}
  1595    `
  1596  	js := processQueryNoErr(t, query)
  1597  	require.JSONEq(t, `{"data": {"me":[{"name":"Daryl Dixon","val(a)":17,"val(s)":0,"val(score)":35.000000},{"name":"Andrea","val(a)":19,"val(s)":1,"val(score)":42.000000}]}}`,
  1598  		js)
  1599  }
  1600  
  1601  func TestVarInIneq(t *testing.T) {
  1602  
  1603  	query := `
  1604      {
  1605  			var(func: uid( 1)) {
  1606  				f as friend {
  1607  					a as age
  1608  				}
  1609  			}
  1610  
  1611  			me(func: uid(f)) @filter(gt(val(a), 18)) {
  1612  				name
  1613  			}
  1614  		}
  1615    `
  1616  	js := processQueryNoErr(t, query)
  1617  	require.JSONEq(t, `{"data": {"me":[{"name":"Andrea"}]}}`, js)
  1618  }
  1619  
  1620  func TestVarInIneq2(t *testing.T) {
  1621  
  1622  	query := `
  1623      {
  1624  			var(func: uid(1)) {
  1625  				friend {
  1626  					a as age
  1627  				}
  1628  			}
  1629  
  1630  			me(func: gt(val(a), 18)) {
  1631  				name
  1632  			}
  1633  		}
  1634    `
  1635  	js := processQueryNoErr(t, query)
  1636  	require.JSONEq(t, `{"data": {"me":[{"name":"Andrea"}]}}`, js)
  1637  }
  1638  
  1639  func TestVarInIneq3(t *testing.T) {
  1640  
  1641  	query := `
  1642      {
  1643  			var(func: uid(0x1f)) {
  1644  				a as name
  1645  			}
  1646  
  1647  			me(func: eq(name, val(a))) {
  1648  				name
  1649  			}
  1650  		}
  1651    `
  1652  	js := processQueryNoErr(t, query)
  1653  	require.JSONEq(t, `{"data": {"me":[{"name":"Andrea"}]}}`, js)
  1654  }
  1655  
  1656  func TestVarInIneq4(t *testing.T) {
  1657  
  1658  	query := `
  1659      {
  1660  			var(func: uid(0x1f)) {
  1661  				a as name
  1662  			}
  1663  
  1664  			me(func: uid(0x1f)) @filter(eq(name, val(a))) {
  1665  				name
  1666  			}
  1667  		}
  1668    `
  1669  	js := processQueryNoErr(t, query)
  1670  	require.JSONEq(t, `{"data": {"me":[{"name":"Andrea"}]}}`, js)
  1671  }
  1672  
  1673  func TestVarInIneq5(t *testing.T) {
  1674  
  1675  	query1 := `
  1676      {
  1677  			var(func: uid(1)) {
  1678  				friend {
  1679  				  a as name
  1680  			  }
  1681  			}
  1682  
  1683  			me(func: eq(name, val(a))) {
  1684  				name
  1685  			}
  1686  		}
  1687    `
  1688  	query2 := `
  1689      {
  1690  			var(func: uid(1)) {
  1691  				friend {
  1692  				  a as name
  1693  			  }
  1694  			}
  1695  
  1696  			me(func: uid(a)) {
  1697  				name: val(a)
  1698  			}
  1699  		}
  1700    `
  1701  	js1 := processQueryNoErr(t, query1)
  1702  	js2 := processQueryNoErr(t, query2)
  1703  	require.JSONEq(t, js2, js1)
  1704  }
  1705  
  1706  func TestNestedFuncRoot(t *testing.T) {
  1707  	query := `
  1708      {
  1709  			me(func: gt(count(friend), 2)) {
  1710  				name
  1711  			}
  1712  		}
  1713    `
  1714  	js := processQueryNoErr(t, query)
  1715  	require.JSONEq(t, `{"data": {"me":[{"name":"Michonne"}]}}`, js)
  1716  }
  1717  
  1718  func TestNestedFuncRoot2(t *testing.T) {
  1719  	query := `
  1720  		{
  1721  			me(func: ge(count(friend), 1)) {
  1722  				name
  1723  			}
  1724  		}
  1725    `
  1726  	js := processQueryNoErr(t, query)
  1727  	require.JSONEq(t, `{"data": {"me":[{"name":"Michonne"},{"name":"Rick Grimes"},{"name":"Andrea"}]}}`, js)
  1728  }
  1729  
  1730  func TestNestedFuncRoot4(t *testing.T) {
  1731  
  1732  	query := `
  1733  		{
  1734  			me(func: le(count(friend), 1)) {
  1735  				name
  1736  			}
  1737  		}
  1738    `
  1739  	js := processQueryNoErr(t, query)
  1740  	require.JSONEq(t, `{"data": {"me":[{"name":"Rick Grimes"},{"name":"Andrea"}]}}`, js)
  1741  }
  1742  
  1743  func TestCountUidToVar(t *testing.T) {
  1744  	query := `
  1745  	{
  1746  		var(func: has(school), first: 3) {
  1747  			f as count(uid)
  1748  		}
  1749  
  1750  		me(func: uid(1)) {
  1751  			score: math(f)
  1752  		}
  1753  	}
  1754      `
  1755  	js := processQueryNoErr(t, query)
  1756  	require.JSONEq(t, `{"data": {"me":[{"score": 3}]}}`, js)
  1757  }
  1758  
  1759  func TestFilterUsingLenFunction(t *testing.T) {
  1760  	tests := []struct {
  1761  		name, in, out string
  1762  	}{
  1763  		{
  1764  			"Eq length should return results",
  1765  			`{
  1766  			    var(func: has(school), first: 3) {
  1767  			        f as uid
  1768  			    }
  1769  
  1770  			    me(func: uid(f)) @filter(eq(len(f), 3)) {
  1771  			        count(uid)
  1772  			    }
  1773  			}`,
  1774  			`{"data": {"me":[{"count": 3}]}}`,
  1775  		},
  1776  		{
  1777  			"Eq length should return empty results",
  1778  			`{
  1779  				var(func: has(school), first: 3) {
  1780  					f as uid
  1781  				}
  1782  				me(func: uid(f)) @filter(eq(len(f), 0)) {
  1783  					uid
  1784  					name
  1785  				}
  1786  			}`,
  1787  			`{"data": {"me":[]}}`,
  1788  		},
  1789  		{
  1790  			"Eq length with uid(0) should return results",
  1791  			`{
  1792  				f as var(func: eq(name, "random"))
  1793  				me(func: uid(0)) @filter(eq(len(f), 0)) {
  1794  					uid
  1795  				}
  1796  			}`,
  1797  			`{"data": {"me":[{"uid": "0x0"}]}}`,
  1798  		},
  1799  		{
  1800  			"Ge length should return results",
  1801  			`{
  1802  			    var(func: has(school), first: 3) {
  1803  			        f as uid
  1804  			    }
  1805  
  1806  			    me(func: uid(f)) @filter(ge(len(f), 0)) {
  1807  			        count(uid)
  1808  			    }
  1809  			}`,
  1810  			`{"data": {"me":[{"count": 3}]}}`,
  1811  		},
  1812  		{
  1813  			"Lt length should return results",
  1814  			`{
  1815  			    var(func: has(school), first: 3) {
  1816  			        f as uid
  1817  			    }
  1818  
  1819  			    me(func: uid(f)) @filter(lt(len(f), 100)) {
  1820  			        count(uid)
  1821  			    }
  1822  			}`,
  1823  
  1824  			`{"data": {"me":[{"count": 3}]}}`,
  1825  		},
  1826  		{
  1827  			"Multiple length conditions",
  1828  			`{
  1829  			    var(func: has(school), first: 3) {
  1830  			        f as uid
  1831  			    }
  1832  
  1833  			    f2 as var(func: has(name), first: 5)
  1834  
  1835  			    me(func: uid(f2)) @filter(lt(len(f), 100) AND lt(len(f2), 10)) {
  1836  			        count(uid)
  1837  			    }
  1838  			}`,
  1839  
  1840  			`{"data": {"me":[{"count": 5}]}}`,
  1841  		},
  1842  		{
  1843  			"Filter in child with true result",
  1844  			`{
  1845  			    var(func: has(school), first: 3) {
  1846  			        f as uid
  1847  			    }
  1848  
  1849  			    me(func: uid(f)) {
  1850  					name
  1851  					friend @filter(lt(len(f), 100)) {
  1852  						name
  1853  					}
  1854  				}
  1855  			}`,
  1856  			`{"data":{"me":[{"name":"Michonne","friend":[{"name":"Rick Grimes"},
  1857  			 {"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"name":"Andrea"}]},
  1858  			 {"name":"Rick Grimes","friend":[{"name":"Michonne"}]},
  1859  			 {"name":"Glenn Rhee"}]}}`,
  1860  		},
  1861  		{
  1862  			"Filter in child with false result",
  1863  			`{
  1864  			    var(func: has(school), first: 3) {
  1865  			        f as uid
  1866  			    }
  1867  
  1868  			    me(func: uid(f)) {
  1869  					name
  1870  					friend @filter(gt(len(f), 100)) {
  1871  						name
  1872  					}
  1873  				}
  1874  			}`,
  1875  
  1876  			`{"data":{"me":[{"name":"Michonne"},{"name":"Rick Grimes"},
  1877  			 {"name":"Glenn Rhee"}]}}`,
  1878  		},
  1879  	}
  1880  
  1881  	for _, tc := range tests {
  1882  		t.Log("Running: ", tc.name)
  1883  		js := processQueryNoErr(t, tc.in)
  1884  		require.JSONEq(t, tc.out, js)
  1885  	}
  1886  }
  1887  
  1888  func TestCountOnVarAtRootErr(t *testing.T) {
  1889  	query := `
  1890  	       {
  1891  	               var(func: has(school), first: 3) {
  1892  	                       f as count(uid)
  1893  	               }
  1894  
  1895  	               me(func: len(f)) {
  1896  	                       score: math(f)
  1897  	               }
  1898  	       }
  1899  	    `
  1900  	_, err := processQuery(context.Background(), t, query)
  1901  	require.Error(t, err)
  1902  	require.Contains(t, err.Error(), "Function name: len is not valid")
  1903  }
  1904  
  1905  func TestFilterUsingLenFunctionWithMath(t *testing.T) {
  1906  	query := `
  1907  	{
  1908  		var(func: has(school), first: 3) {
  1909  			f as count(uid)
  1910  		}
  1911  
  1912  		me(func: uid(f)) @filter(lt(len(f), 100)) {
  1913  			score: math(f)
  1914  		}
  1915  	}
  1916      `
  1917  	js := processQueryNoErr(t, query)
  1918  	require.JSONEq(t, `{"data": {"me":[{"score": 3}]}}`, js)
  1919  }
  1920  
  1921  func TestCountUidToVarMultiple(t *testing.T) {
  1922  	query := `
  1923  	{
  1924  		var(func: has(school), first: 3) {
  1925  			f as count(uid)
  1926  		}
  1927  
  1928  		var(func: has(follow), first: 4) {
  1929  			g as count(uid)
  1930  		}
  1931  
  1932  		me(func: uid(1)) {
  1933  			score: math(f + g)
  1934  		}
  1935  	}
  1936      `
  1937  	js := processQueryNoErr(t, query)
  1938  	require.JSONEq(t, `{"data": {"me":[{"score": 7}]}}`, js)
  1939  }
  1940  
  1941  func TestCountUidToVarCombinedWithNormalVar(t *testing.T) {
  1942  	query := `
  1943  	{
  1944  		var(func: has(school), first: 3) {
  1945  			f as count(uid)
  1946  		}
  1947  
  1948  		var(func: has(follow)) {
  1949  			g as count(path)
  1950  		}
  1951  
  1952  		me(func: uid(1)) {
  1953  			score: math(f + g)
  1954  		}
  1955  	}
  1956      `
  1957  	js := processQueryNoErr(t, query)
  1958  	require.JSONEq(t, `{"data": {"me":[{"score": 5}]}}`, js)
  1959  }
  1960  
  1961  func TestDefaultValueVar1(t *testing.T) {
  1962  	query := `
  1963  	{
  1964  		var(func: has(pred)) {
  1965  			n as uid
  1966  			cnt as count(nonexistent_pred)
  1967  		}
  1968  
  1969  		data(func: uid(n)) @filter(gt(val(cnt), 4)) {
  1970  			expand(_all_)
  1971  		}
  1972  	}`
  1973  	js := processQueryNoErr(t, query)
  1974  	require.JSONEq(t, `{"data": {"data":[]}}`, js)
  1975  }
  1976  
  1977  func TestDefaultValueVar2(t *testing.T) {
  1978  	query := `
  1979  	{
  1980  		var(func: uid(0x1)) {
  1981  			cnt as nonexistent_pred
  1982  		}
  1983  
  1984  		data(func: uid(0x1)) {
  1985  			val(cnt)
  1986  		}
  1987  	}`
  1988  	js := processQueryNoErr(t, query)
  1989  	require.JSONEq(t, `{"data": {"data":[]}}`, js)
  1990  }
  1991  
  1992  func TestNonFlattenedResponse(t *testing.T) {
  1993  	query := `
  1994  	{
  1995  		me(func: eq(name@en, "Baz Luhrmann")) {
  1996  			uid
  1997  			director.film {
  1998  				name@en
  1999  			}
  2000  		}
  2001  	}`
  2002  	js := processQueryNoErr(t, query)
  2003  	require.JSONEq(t, `{"data": {"me":[
  2004  		{"uid":"0x2af8", "director.film": [
  2005  			{"name@en": "Strictly Ballroom"},
  2006  			{"name@en": "Puccini: La boheme (Sydney Opera)"},
  2007  			{"name@en": "No. 5 the film"}
  2008  		]}
  2009  	]}}`, js)
  2010  
  2011  }
  2012  
  2013  func TestDateTimeQuery(t *testing.T) {
  2014  	var query string
  2015  
  2016  	// Test 19
  2017  	query = `
  2018  {
  2019    q(func: has(created_at), orderdesc: created_at) {
  2020  		uid
  2021  		created_at
  2022    }
  2023  }
  2024  `
  2025  	require.JSONEq(t,
  2026  		`{"data":{"q":[{"uid":"0x133","created_at":"2019-05-28T14:41:57+30:00"},{"uid":"0x130","created_at":"2019-03-28T15:41:57+30:00"},{"uid":"0x12d","created_at":"2019-03-28T14:41:57+30:00"},{"uid":"0x12e","created_at":"2019-03-28T13:41:57+29:00"},{"uid":"0x12f","created_at":"2019-03-27T14:41:57+06:00"},{"uid":"0x131","created_at":"2019-03-28T13:41:57+30:00"},{"uid":"0x132","created_at":"2019-03-24T14:41:57+05:30"}]}}`,
  2027  		processQueryNoErr(t, query))
  2028  
  2029  	// Test 18
  2030  	query = `
  2031  {
  2032  	q(func: has(best_friend)) @cascade {
  2033  		uid
  2034  		best_friend @facets(lt(since, "2019-03-24")) @facets(since) {
  2035  			uid
  2036  		}
  2037  	}
  2038  }
  2039  `
  2040  	require.JSONEq(t,
  2041  		`{"data":{"q":[{"uid":"0x3","best_friend":{"uid":"0x40","best_friend|since":"2018-03-24T14:41:57+05:30"}}]}}`,
  2042  		processQueryNoErr(t, query))
  2043  
  2044  	// Test 17
  2045  	query = `
  2046  {
  2047  	q(func: has(best_friend)) @cascade {
  2048  		uid
  2049  		best_friend @facets(gt(since, "2019-03-27")) @facets(since) {
  2050  			uid
  2051  		}
  2052  	}
  2053  }
  2054  `
  2055  	require.JSONEq(t,
  2056  		`{"data":{"q":[{"uid":"0x2","best_friend":{"uid":"0x40","best_friend|since":"2019-03-28T14:41:57+30:00"}}]}}`,
  2057  		processQueryNoErr(t, query))
  2058  
  2059  	// Test 16
  2060  	query = `
  2061  {
  2062  	q(func: gt(created_at, "2019-03-28")) {
  2063  		uid
  2064  		created_at @facets(modified_at)
  2065  		updated_at @facets(modified_at)
  2066  	}
  2067  }
  2068  `
  2069  	require.JSONEq(t,
  2070  		`{"data":{"q":[{"uid":"0x133","created_at":"2019-05-28T14:41:57+30:00","updated_at|modified_at":"2019-03-24T14:41:57+05:30","updated_at":"2019-05-28T00:00:00Z"}]}}`,
  2071  		processQueryNoErr(t, query))
  2072  
  2073  	// Test 15
  2074  	query = `
  2075  {
  2076  	q(func: gt(age, 15)) @filter(gt(graduation, "1932") AND lt(graduation, "1934")) {
  2077  		uid
  2078  		graduation
  2079  	}
  2080  }
  2081  `
  2082  	require.JSONEq(t,
  2083  		`{"data":{"q":[{"uid":"0x1f","graduation":["1935-01-01T00:00:00Z","1933-01-01T00:00:00Z"]}]}}`,
  2084  		processQueryNoErr(t, query))
  2085  
  2086  	// Test 14
  2087  	query = `
  2088  {
  2089  	q(func: gt(age, 15)) @filter(le(graduation, "1932") OR gt(graduation, "1936")) {
  2090  		uid
  2091  		graduation
  2092  	}
  2093  }
  2094  `
  2095  	require.JSONEq(t,
  2096  		`{"data":{"q":[{"uid":"0x1","graduation":["1932-01-01T00:00:00Z"]}]}}`,
  2097  		processQueryNoErr(t, query))
  2098  
  2099  	// Test 13
  2100  	query = `
  2101  	{
  2102  		q(func: gt(age, 15)) @filter(lt(graduation, "1932") AND gt(graduation, "1936")) {
  2103  			uid
  2104  			graduation
  2105  		}
  2106  	}
  2107  	`
  2108  	require.JSONEq(t,
  2109  		`{"data":{"q":[]}}`,
  2110  		processQueryNoErr(t, query))
  2111  
  2112  	// Test 12
  2113  	query = `
  2114  {
  2115    q(func: le(dob, "1909-05-05")) {
  2116      uid
  2117      dob
  2118    }
  2119  }
  2120  `
  2121  	require.JSONEq(t,
  2122  		`{"data":{"q":[{"uid":"0x18","dob":"1909-05-05T00:00:00Z"},{"uid":"0x19","dob":"1909-01-10T00:00:00Z"},{"uid":"0x1f","dob":"1901-01-15T00:00:00Z"}]}}`,
  2123  		processQueryNoErr(t, query))
  2124  
  2125  	// Test 11
  2126  	query = `
  2127  {
  2128    q(func: le(dob, "1909-05-05T00:00:00+05:30")) {
  2129      uid
  2130      dob
  2131    }
  2132  }
  2133  `
  2134  	require.JSONEq(t,
  2135  		`{"data":{"q":[{"uid":"0x19","dob":"1909-01-10T00:00:00Z"},{"uid":"0x1f","dob":"1901-01-15T00:00:00Z"}]}}`,
  2136  		processQueryNoErr(t, query))
  2137  
  2138  	// Test 10
  2139  	query = `
  2140  {
  2141    q(func: eq(graduation, "1932-01-01T00:00:00+05:30")) {
  2142      uid
  2143      graduation
  2144    }
  2145  }
  2146  `
  2147  	require.JSONEq(t,
  2148  		`{"data":{"q":[]}}`,
  2149  		processQueryNoErr(t, query))
  2150  
  2151  	// Test 9
  2152  	query = `
  2153  {
  2154    q(func: eq(graduation, "1932")) {
  2155      uid
  2156      graduation
  2157    }
  2158  }
  2159  `
  2160  	require.JSONEq(t,
  2161  		`{"data":{"q":[{"uid":"0x1","graduation":["1932-01-01T00:00:00Z"]}]}}`,
  2162  		processQueryNoErr(t, query))
  2163  
  2164  	// Test 8
  2165  	query = `
  2166  {
  2167    q(func: lt(graduation, "1933")) {
  2168      uid
  2169      graduation
  2170    }
  2171  }
  2172  `
  2173  	require.JSONEq(t,
  2174  		`{"data":{"q":[{"uid":"0x1","graduation":["1932-01-01T00:00:00Z"]}]}}`,
  2175  		processQueryNoErr(t, query))
  2176  
  2177  	// Test 7
  2178  	query = `
  2179  {
  2180    q(func: gt(graduation, "1932")) {
  2181      uid
  2182      graduation
  2183    }
  2184  }
  2185  `
  2186  	require.JSONEq(t,
  2187  		`{"data":{"q":[{"uid":"0x1f","graduation":["1935-01-01T00:00:00Z","1933-01-01T00:00:00Z"]}]}}`,
  2188  		processQueryNoErr(t, query))
  2189  
  2190  	// Test 6
  2191  	query = `
  2192  {
  2193    q(func: le(updated_at, "2019-03-27T14:41:56+06:00")) {
  2194      uid
  2195      updated_at
  2196    }
  2197  }
  2198  `
  2199  	require.JSONEq(t,
  2200  		`{"data":{"q":[{"uid":"0x131","updated_at":"2019-03-28T13:41:57+30:00"},{"uid":"0x132","updated_at":"2019-03-24T14:41:57+05:30"}]}}`,
  2201  		processQueryNoErr(t, query))
  2202  
  2203  	// Test 5
  2204  	query = `
  2205  {
  2206    q(func: ge(updated_at, "2019-03-28T13:41:57+00:00")) {
  2207      uid
  2208      updated_at
  2209    }
  2210  }
  2211  `
  2212  	require.JSONEq(t,
  2213  		`{"data":{"q":[{"uid":"0x133","updated_at":"2019-05-28T00:00:00Z"}]}}`,
  2214  		processQueryNoErr(t, query))
  2215  
  2216  	// Test 4
  2217  	query = `
  2218  {
  2219    q(func: ge(updated_at, "2019-03-28T13:41:57")) {
  2220      uid
  2221      updated_at
  2222    }
  2223  }
  2224  `
  2225  	require.JSONEq(t,
  2226  		`{"data":{"q":[{"uid":"0x133","updated_at":"2019-05-28T00:00:00Z"}]}}`,
  2227  		processQueryNoErr(t, query))
  2228  
  2229  	// Test 3
  2230  	query = `
  2231  {
  2232    q(func: le(created_at, "2019-03-27T14:41:56+06:00")) {
  2233      uid
  2234      created_at
  2235    }
  2236  }
  2237  `
  2238  	require.JSONEq(t,
  2239  		`{"data":{"q":[{"uid":"0x131","created_at":"2019-03-28T13:41:57+30:00"},{"uid":"0x132","created_at":"2019-03-24T14:41:57+05:30"}]}}`,
  2240  		processQueryNoErr(t, query))
  2241  
  2242  	// Test 2
  2243  	query = `
  2244  {
  2245    q(func: ge(created_at, "2019-03-28T13:41:57+00:00")) {
  2246      uid
  2247      created_at
  2248    }
  2249  }
  2250  `
  2251  	require.JSONEq(t,
  2252  		`{"data":{"q":[{"uid":"0x133","created_at":"2019-05-28T14:41:57+30:00"}]}}`,
  2253  		processQueryNoErr(t, query))
  2254  
  2255  	// Test 1
  2256  	query = `
  2257  {
  2258    q(func: ge(created_at, "2019-03-28T13:41:57")) {
  2259      uid
  2260      created_at
  2261    }
  2262  }
  2263  `
  2264  	require.JSONEq(t,
  2265  		`{"data":{"q":[{"uid":"0x133","created_at":"2019-05-28T14:41:57+30:00"}]}}`,
  2266  		processQueryNoErr(t, query))
  2267  }
  2268  
  2269  func TestCountUidWithAlias(t *testing.T) {
  2270  	query := `
  2271  		{
  2272  			me(func: uid(1, 23, 24, 25, 31)) {
  2273  				countUid: count(uid)
  2274  				name
  2275  			}
  2276  		}
  2277  		`
  2278  	js := processQueryNoErr(t, query)
  2279  	require.JSONEq(t,
  2280  		`{"data":{"me":[{"countUid":5},{"name":"Michonne"},{"name":"Rick Grimes"},{"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"name":"Andrea"}]}}`,
  2281  		js)
  2282  }
  2283  
  2284  var client *dgo.Dgraph
  2285  
  2286  func TestMain(m *testing.M) {
  2287  	client = testutil.DgraphClientWithGroot(testutil.SockAddr)
  2288  
  2289  	populateCluster()
  2290  	os.Exit(m.Run())
  2291  }