github.com/unigraph-dev/dgraph@v1.1.1-0.20200923154953-8b52b426f765/query/query1_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  	"context"
    21  	"encoding/json"
    22  	"io/ioutil"
    23  	"strings"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/stretchr/testify/require"
    28  	"google.golang.org/grpc/metadata"
    29  )
    30  
    31  func TestSchemaBlock2(t *testing.T) {
    32  	query := `
    33  		schema(pred: name) {
    34  			index
    35  			reverse
    36  			type
    37  			tokenizer
    38  			count
    39  		}
    40  	`
    41  
    42  	js := processQueryNoErr(t, query)
    43  	require.JSONEq(t, `{"data":{"schema":[{"predicate":"name","type":"string","index":true,"tokenizer":["term","exact","trigram"],"count":true}]}}`, js)
    44  }
    45  
    46  func TestSchemaBlock3(t *testing.T) {
    47  	query := `
    48  		schema(pred: age) {
    49  			index
    50  			reverse
    51  			type
    52  			tokenizer
    53  			count
    54  		}
    55  	`
    56  	js := processQueryNoErr(t, query)
    57  	require.JSONEq(t, `{"data":{"schema":[{"predicate":"age","type":"int","index":true,"tokenizer":["int"]}]}}`, js)
    58  }
    59  
    60  func TestSchemaBlock4(t *testing.T) {
    61  	query := `
    62  		schema(pred: [age, genre, random]) {
    63  			index
    64  			reverse
    65  			type
    66  			tokenizer
    67  		}
    68  	`
    69  	js := processQueryNoErr(t, query)
    70  	require.JSONEq(t, `{"data":{"schema":[{"predicate":"age","type":"int","index":true,"tokenizer":["int"]},{"predicate":"genre","type":"uid","reverse":true}]}}`, js)
    71  }
    72  
    73  func TestSchemaBlock5(t *testing.T) {
    74  	query := `
    75  		schema(pred: name) {
    76  		}
    77  	`
    78  
    79  	js := processQueryNoErr(t, query)
    80  	require.JSONEq(t, `{"data":{"schema":[{"predicate":"name","type":"string","index":true,"tokenizer":["term","exact","trigram"],"count":true,"lang":true}]}}`, js)
    81  }
    82  
    83  func TestFilterNonIndexedPredicateFail(t *testing.T) {
    84  
    85  	// filtering on non indexing predicate fails
    86  	query := `
    87  		{
    88  			me(func: uid(0x01)) {
    89  				friend @filter(le(survival_rate, 30)) {
    90  					uid
    91  					name
    92  					age
    93  				}
    94  			}
    95  		}
    96  	`
    97  	_, err := processQuery(context.Background(), t, query)
    98  	require.Error(t, err)
    99  }
   100  
   101  func TestMultipleSamePredicateInBlockFail(t *testing.T) {
   102  
   103  	// name is asked for two times..
   104  	query := `
   105  		{
   106  			me(func: uid(0x01)) {
   107  				name
   108  				friend {
   109  					age
   110  				}
   111  				name
   112  			}
   113  		}
   114  	`
   115  	_, err := processQuery(context.Background(), t, query)
   116  	require.Error(t, err)
   117  }
   118  
   119  func TestMultipleSamePredicateInBlockFail2(t *testing.T) {
   120  
   121  	// age is asked for two times..
   122  	query := `
   123  		{
   124  			me(func: uid(0x01)) {
   125  				friend {
   126  					age
   127  					age
   128  				}
   129  				name
   130  			}
   131  		}
   132  	`
   133  	_, err := processQuery(context.Background(), t, query)
   134  	require.Error(t, err)
   135  }
   136  
   137  func TestMultipleSamePredicateInBlockFail3(t *testing.T) {
   138  
   139  	// friend is asked for two times..
   140  	query := `
   141  		{
   142  			me(func: uid(0x01)) {
   143  				friend {
   144  					age
   145  				}
   146  				friend {
   147  					name
   148  				}
   149  				name
   150  			}
   151  		}
   152  	`
   153  	_, err := processQuery(context.Background(), t, query)
   154  	require.Error(t, err)
   155  }
   156  
   157  func TestXidInvalidJSON(t *testing.T) {
   158  
   159  	query := `
   160  		{
   161  			me(func: uid(0x01)) {
   162  				name
   163  				_xid_
   164  				gender
   165  				alive
   166  				friend {
   167  					_xid_
   168  					random
   169  					name
   170  				}
   171  			}
   172  		}
   173  	`
   174  	js := processQueryNoErr(t, query)
   175  	require.JSONEq(t,
   176  		`{"data": {"me":[{"_xid_":"mich","alive":true,"friend":[{"name":"Rick Grimes"},{"_xid_":"g\"lenn","name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"name":"Andrea"}],"gender":"female","name":"Michonne"}]}}`,
   177  		js)
   178  	m := make(map[string]interface{})
   179  	err := json.Unmarshal([]byte(js), &m)
   180  	require.NoError(t, err)
   181  }
   182  
   183  func TestToJSONReverseNegativeFirst(t *testing.T) {
   184  
   185  	query := `
   186  		{
   187  			me(func: allofterms(name, "Andrea")) {
   188  				name
   189  				~friend (first: -1) {
   190  					name
   191  					gender
   192  				}
   193  			}
   194  		}
   195  	`
   196  	js := processQueryNoErr(t, query)
   197  	require.JSONEq(t,
   198  		`{"data": {"me":[{"name":"Andrea","~friend":[{"gender":"female","name":"Michonne"}]},{"name":"Andrea With no friends"}]}}`,
   199  		js)
   200  }
   201  
   202  func TestToFastJSONOrderLang(t *testing.T) {
   203  
   204  	query := `
   205  		{
   206  			me(func: uid(0x01)) {
   207  				friend(first:2, orderdesc: alias@en:de:.) {
   208  					alias
   209  				}
   210  			}
   211  		}
   212  	`
   213  
   214  	js := processQueryNoErr(t, query)
   215  	require.JSONEq(t,
   216  		`{"data": {"me":[{"friend":[{"alias":"Zambo Alice"},{"alias":"John Oliver"}]}]}}`,
   217  		js)
   218  }
   219  
   220  func TestBoolIndexEqRoot1(t *testing.T) {
   221  
   222  	query := `
   223  		{
   224  			me(func: eq(alive, true)) {
   225  				name
   226  				alive
   227  			}
   228  		}
   229  	`
   230  	js := processQueryNoErr(t, query)
   231  	require.JSONEq(t,
   232  		`{"data": {"me":[{"alive":true,"name":"Michonne"},{"alive":true,"name":"Rick Grimes"}]}}`,
   233  		js)
   234  }
   235  
   236  func TestBoolIndexEqRoot2(t *testing.T) {
   237  
   238  	query := `
   239  		{
   240  			me(func: eq(alive, false)) {
   241  				name
   242  				alive
   243  			}
   244  		}
   245  	`
   246  	js := processQueryNoErr(t, query)
   247  	require.JSONEq(t,
   248  		`{"data": {"me":[{"alive":false,"name":"Daryl Dixon"},{"alive":false,"name":"Andrea"}]}}`,
   249  		js)
   250  }
   251  
   252  func TestBoolIndexgeRoot(t *testing.T) {
   253  
   254  	q := `
   255  		{
   256  			me(func: ge(alive, true)) {
   257  				name
   258  				alive
   259  				friend {
   260  					name
   261  					alive
   262  				}
   263  			}
   264  		}`
   265  
   266  	_, err := processQuery(context.Background(), t, q)
   267  	require.Error(t, err)
   268  }
   269  
   270  func TestBoolIndexEqChild(t *testing.T) {
   271  
   272  	query := `
   273  		{
   274  			me(func: eq(alive, true)) {
   275  				name
   276  				alive
   277  				friend @filter(eq(alive, false)) {
   278  					name
   279  					alive
   280  				}
   281  			}
   282  		}
   283  	`
   284  	js := processQueryNoErr(t, query)
   285  	require.JSONEq(t,
   286  		`{"data": {"me":[{"alive":true,"friend":[{"alive":false,"name":"Daryl Dixon"},{"alive":false,"name":"Andrea"}],"name":"Michonne"},{"alive":true,"name":"Rick Grimes"}]}}`,
   287  		js)
   288  }
   289  
   290  func TestBoolSort(t *testing.T) {
   291  
   292  	q := `
   293  		{
   294  			me(func: anyofterms(name, "Michonne Andrea Rick"), orderasc: alive) {
   295  				name
   296  				alive
   297  			}
   298  		}
   299  	`
   300  
   301  	_, err := processQuery(context.Background(), t, q)
   302  	require.Error(t, err)
   303  }
   304  
   305  func TestStringEscape(t *testing.T) {
   306  
   307  	query := `
   308  		{
   309  			me(func: uid(2301)) {
   310  				name
   311  			}
   312  		}
   313  	`
   314  	js := processQueryNoErr(t, query)
   315  	require.JSONEq(t,
   316  		`{"data": {"me":[{"name":"Alice\""}]}}`,
   317  		js)
   318  }
   319  
   320  func TestJSONQueryVariables(t *testing.T) {
   321  
   322  	q := `query test ($a: int = 1) {
   323  		me(func: uid(0x01)) {
   324  			name
   325  			gender
   326  			friend(first: $a) {
   327  				name
   328  			}
   329  		}
   330  	}`
   331  	js, err := processQueryWithVars(t, q, map[string]string{"$a": "2"})
   332  	require.NoError(t, err)
   333  	require.JSONEq(t, `{"data": {"me":[{"friend":[{"name":"Rick Grimes"},{"name":"Glenn Rhee"}],"gender":"female","name":"Michonne"}]}}`, js)
   334  }
   335  
   336  func TestOrderDescFilterCount(t *testing.T) {
   337  
   338  	query := `
   339  		{
   340  			me(func: uid(0x01)) {
   341  				friend(first:2, orderdesc: age) @filter(eq(alias, "Zambo Alice")) {
   342  					alias
   343  				}
   344  			}
   345  		}
   346  	`
   347  
   348  	js := processQueryNoErr(t, query)
   349  	require.JSONEq(t,
   350  		`{"data": {"me":[{"friend":[{"alias":"Zambo Alice"}]}]}}`,
   351  		js)
   352  }
   353  
   354  func TestHashTokEq(t *testing.T) {
   355  
   356  	query := `
   357  		{
   358  			me(func: eq(full_name, "Michonne's large name for hashing")) {
   359  				full_name
   360  				alive
   361  				friend {
   362  					name
   363  				}
   364  			}
   365  		}
   366  	`
   367  	js := processQueryNoErr(t, query)
   368  	require.JSONEq(t,
   369  		`{"data": {"me":[{"alive":true,"friend":[{"name":"Rick Grimes"},{"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"name":"Andrea"}],"full_name":"Michonne's large name for hashing"}]}}`,
   370  		js)
   371  }
   372  
   373  func TestHashTokGeqErr(t *testing.T) {
   374  
   375  	query := `
   376  		{
   377  			me(func: ge(full_name, "Michonne's large name for hashing")) {
   378  				full_name
   379  				alive
   380  				friend {
   381  					name
   382  				}
   383  			}
   384  		}
   385  	`
   386  	_, err := processQuery(context.Background(), t, query)
   387  	require.Error(t, err)
   388  }
   389  
   390  func TestNameNotIndexed(t *testing.T) {
   391  
   392  	query := `
   393  		{
   394  			me(func: eq(noindex_name, "Michonne's name not indexed")) {
   395  				full_name
   396  				alive
   397  				friend {
   398  					name
   399  				}
   400  			}
   401  		}
   402  	`
   403  
   404  	_, err := processQuery(context.Background(), t, query)
   405  	require.Error(t, err)
   406  }
   407  
   408  func TestMultipleMinMax(t *testing.T) {
   409  
   410  	query := `
   411  		{
   412  			me(func: uid(0x01)) {
   413  				friend {
   414  					x as age
   415  					n as name
   416  				}
   417  				min(val(x))
   418  				max(val(x))
   419  				min(val(n))
   420  				max(val(n))
   421  			}
   422  		}`
   423  	js := processQueryNoErr(t, query)
   424  	require.JSONEq(t,
   425  		`{"data": {"me":[{"friend":[{"age":15,"name":"Rick Grimes"},{"age":15,"name":"Glenn Rhee"},{"age":17,"name":"Daryl Dixon"},{"age":19,"name":"Andrea"}],"max(val(n))":"Rick Grimes","max(val(x))":19,"min(val(n))":"Andrea","min(val(x))":15}]}}`,
   426  		js)
   427  }
   428  
   429  func TestDuplicateAlias(t *testing.T) {
   430  
   431  	query := `
   432  		{
   433  			me(func: uid(0x01)) {
   434  				friend {
   435  					x as age
   436  				}
   437  				a: min(val(x))
   438  				a: max(val(x))
   439  			}
   440  		}`
   441  
   442  	_, err := processQuery(context.Background(), t, query)
   443  	require.Error(t, err)
   444  }
   445  
   446  func TestGraphQLId(t *testing.T) {
   447  
   448  	q := `query test ($a: string = 1) {
   449  		me(func: uid($a)) {
   450  			name
   451  			gender
   452  			friend(first: 1) {
   453  				name
   454  			}
   455  		}
   456  	}`
   457  	js, err := processQueryWithVars(t, q, map[string]string{"$a": "[1, 31]"})
   458  	require.NoError(t, err)
   459  	require.JSONEq(t, `{"data": {"me":[{"friend":[{"name":"Rick Grimes"}],"gender":"female","name":"Michonne"},{"friend":[{"name":"Glenn Rhee"}],"name":"Andrea"}]}}`, js)
   460  }
   461  
   462  func TestDebugUid(t *testing.T) {
   463  
   464  	query := `
   465  		{
   466  			me(func: uid(0x01)) {
   467  				name
   468  				friend {
   469  					name
   470  					friend
   471  				}
   472  			}
   473  		}`
   474  
   475  	md := metadata.Pairs("debug", "true")
   476  	ctx := context.Background()
   477  	ctx = metadata.NewOutgoingContext(ctx, md)
   478  
   479  	buf, err := processQuery(ctx, t, query)
   480  	require.NoError(t, err)
   481  	var mp map[string]interface{}
   482  	require.NoError(t, json.Unmarshal([]byte(buf), &mp))
   483  	resp := mp["data"].(map[string]interface{})["me"]
   484  	body, err := json.Marshal(resp)
   485  	require.NoError(t, err)
   486  	require.JSONEq(t, `[{"friend":[{"name":"Rick Grimes","uid":"0x17"},{"name":"Glenn Rhee","uid":"0x18"},{"name":"Daryl Dixon","uid":"0x19"},{"name":"Andrea","uid":"0x1f"}],"name":"Michonne","uid":"0x1"}]`, string(body))
   487  }
   488  
   489  func TestUidAlias(t *testing.T) {
   490  
   491  	query := `
   492  		{
   493  			me(func: uid(0x1)) {
   494  				id: uid
   495  				alive
   496  				friend {
   497  					uid: uid
   498  					name
   499  				}
   500  			}
   501  		}
   502  	`
   503  	js := processQueryNoErr(t, query)
   504  	require.JSONEq(t,
   505  		`{"data": {"me":[{"alive":true,"friend":[{"name":"Rick Grimes","uid":"0x17"},{"name":"Glenn Rhee","uid":"0x18"},{"name":"Daryl Dixon","uid":"0x19"},{"name":"Andrea","uid":"0x1f"},{"uid":"0x65"}],"id":"0x1"}]}}`,
   506  		js)
   507  }
   508  
   509  func TestCountAtRoot(t *testing.T) {
   510  
   511  	query := `
   512          {
   513              me(func: gt(count(friend), 0)) {
   514  				count(uid)
   515  			}
   516          }
   517          `
   518  	js := processQueryNoErr(t, query)
   519  	require.JSONEq(t, `{"data": {"me":[{"count": 3}]}}`, js)
   520  }
   521  
   522  func TestCountAtRoot2(t *testing.T) {
   523  
   524  	query := `
   525          {
   526                  me(func: anyofterms(name, "Michonne Rick Andrea")) {
   527  			count(uid)
   528  		}
   529          }
   530          `
   531  	js := processQueryNoErr(t, query)
   532  	require.JSONEq(t, `{"data": {"me":[{"count": 4}]}}`, js)
   533  }
   534  
   535  func TestCountAtRoot3(t *testing.T) {
   536  
   537  	query := `
   538          {
   539  		me(func:anyofterms(name, "Michonne Rick Daryl")) {
   540  			name
   541  			count(uid)
   542  			count(friend)
   543  			friend {
   544  				name
   545  				count(uid)
   546  			}
   547  		}
   548          }
   549          `
   550  	js := processQueryNoErr(t, query)
   551  	require.JSONEq(t, `{"data": {"me":[{"count":3},{"count(friend)":5,"friend":[{"name":"Rick Grimes"},{"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"name":"Andrea"},{"count":5}],"name":"Michonne"},{"count(friend)":1,"friend":[{"name":"Michonne"},{"count":1}],"name":"Rick Grimes"},{"count(friend)":0,"name":"Daryl Dixon"}]}}`, js)
   552  }
   553  
   554  func TestCountAtRootWithAlias4(t *testing.T) {
   555  
   556  	query := `
   557  	{
   558                  me(func:anyofterms(name, "Michonne Rick Daryl")) @filter(le(count(friend), 2)) {
   559  			personCount: count(uid)
   560  		}
   561          }
   562          `
   563  	js := processQueryNoErr(t, query)
   564  	require.JSONEq(t, `{"data": {"me": [{"personCount": 2}]}}`, js)
   565  }
   566  
   567  func TestCountAtRoot5(t *testing.T) {
   568  
   569  	query := `
   570  	{
   571  		me(func: uid(1)) {
   572  			f as friend {
   573  				name
   574  			}
   575  		}
   576  		MichonneFriends(func: uid(f)) {
   577  			count(uid)
   578  		}
   579  	}
   580  
   581  
   582          `
   583  	js := processQueryNoErr(t, query)
   584  	require.JSONEq(t, `{"data": {"MichonneFriends":[{"count":5}],"me":[{"friend":[{"name":"Rick Grimes"},{"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"name":"Andrea"}]}]}}`, js)
   585  }
   586  
   587  func TestHasFuncAtRoot(t *testing.T) {
   588  
   589  	query := `
   590  	{
   591  		me(func: has(friend)) {
   592  			name
   593  			friend {
   594  				count(uid)
   595  			}
   596  		}
   597  	}
   598  	`
   599  
   600  	js := processQueryNoErr(t, query)
   601  	require.JSONEq(t, `{"data": {"me":[{"friend":[{"count":5}],"name":"Michonne"},{"friend":[{"count":1}],"name":"Rick Grimes"},{"friend":[{"count":1}],"name":"Andrea"}]}}`, js)
   602  }
   603  
   604  func TestHasFuncAtRootWithAfter(t *testing.T) {
   605  
   606  	query := `
   607  	{
   608  		me(func: has(friend), after: 0x01) {
   609  			uid
   610  			name
   611  			friend {
   612  				count(uid)
   613  			}
   614  		}
   615  	}
   616  	`
   617  
   618  	js := processQueryNoErr(t, query)
   619  	require.JSONEq(t, `{"data": {"me":[{"friend":[{"count":1}],"name":"Rick Grimes","uid":"0x17"},{"friend":[{"count":1}],"name":"Andrea","uid":"0x1f"}]}}`, js)
   620  }
   621  
   622  func TestHasFuncAtRootFilter(t *testing.T) {
   623  
   624  	query := `
   625  	{
   626  		me(func: anyofterms(name, "Michonne Rick Daryl")) @filter(has(friend)) {
   627  			name
   628  			friend {
   629  				count(uid)
   630  			}
   631  		}
   632  	}
   633  	`
   634  
   635  	js := processQueryNoErr(t, query)
   636  	require.JSONEq(t, `{"data": {"me":[{"friend":[{"count":5}],"name":"Michonne"},{"friend":[{"count":1}],"name":"Rick Grimes"}]}}`, js)
   637  }
   638  
   639  func TestHasFuncAtChild1(t *testing.T) {
   640  
   641  	query := `
   642  	{
   643  		me(func: has(school)) {
   644  			name
   645  			friend @filter(has(scooter)) {
   646  				name
   647  			}
   648  		}
   649  	}
   650  	`
   651  
   652  	js := processQueryNoErr(t, query)
   653  	require.JSONEq(t, `{"data": {"me":[{"name":"Michonne"},{"name":"Rick Grimes"},{"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"name":"Andrea"}]}}`, js)
   654  }
   655  
   656  func TestHasFuncAtChild2(t *testing.T) {
   657  
   658  	query := `
   659  	{
   660  		me(func: has(school)) {
   661  			name
   662  			friend @filter(has(alias)) {
   663  				name
   664  				alias
   665  			}
   666  		}
   667  	}
   668  	`
   669  
   670  	js := processQueryNoErr(t, query)
   671  	require.JSONEq(t, `{"data": {"me":[{"friend":[{"alias":"Zambo Alice","name":"Rick Grimes"},{"alias":"John Alice","name":"Glenn Rhee"},{"alias":"Bob Joe","name":"Daryl Dixon"},{"alias":"Allan Matt","name":"Andrea"},{"alias":"John Oliver"}],"name":"Michonne"},{"name":"Rick Grimes"},{"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"friend":[{"alias":"John Alice","name":"Glenn Rhee"}],"name":"Andrea"}]}}`, js)
   672  }
   673  
   674  func TestHasFuncAtRoot2(t *testing.T) {
   675  
   676  	query := `
   677  	{
   678  		me(func: has(name@en)) {
   679  			name@en
   680  		}
   681  	}
   682  	`
   683  
   684  	js := processQueryNoErr(t, query)
   685  	require.JSONEq(t, `{"data": {"me":[{"name@en":"Alex"},{"name@en":"Amit"},{"name@en":"Andrew"},
   686  		{"name@en":"European badger"},{"name@en":"Honey badger"},{"name@en":"Honey bee"},
   687  		{"name@en":"Artem Tkachenko"},{"name@en":"Baz Luhrmann"},{"name@en":"Strictly Ballroom"},
   688  		{"name@en":"Puccini: La boheme (Sydney Opera)"}, {"name@en":"No. 5 the film"}]}}`, js)
   689  }
   690  
   691  func TestMathVarCrash(t *testing.T) {
   692  
   693  	query := `
   694  		{
   695  			f(func: anyofterms(name, "Rick Michonne Andrea")) {
   696  				age as age
   697  				a as math(age *2)
   698  				val(a)
   699  			}
   700  		}
   701  	`
   702  	_, err := processQuery(context.Background(), t, query)
   703  	require.Error(t, err)
   704  }
   705  
   706  func TestMathVarAlias(t *testing.T) {
   707  
   708  	query := `
   709  		{
   710  			f(func: anyofterms(name, "Rick Michonne Andrea")) {
   711  				ageVar as age
   712  				a: math(ageVar *2)
   713  			}
   714  		}
   715  	`
   716  	js := processQueryNoErr(t, query)
   717  	require.JSONEq(t, `{"data": {"f":[{"a":76.000000,"age":38},{"a":30.000000,"age":15},{"a":38.000000,"age":19}]}}`, js)
   718  }
   719  
   720  func TestMathVarAlias2(t *testing.T) {
   721  
   722  	query := `
   723  		{
   724  			f as me(func: anyofterms(name, "Rick Michonne Andrea")) {
   725  				ageVar as age
   726  				doubleAge: a as math(ageVar *2)
   727  			}
   728  
   729  			me2(func: uid(f)) {
   730  				val(a)
   731  			}
   732  		}
   733  	`
   734  	js := processQueryNoErr(t, query)
   735  	require.JSONEq(t, `{"data": {"me":[{"age":38,"doubleAge":76.000000},{"age":15,"doubleAge":30.000000},{"age":19,"doubleAge":38.000000}],"me2":[{"val(a)":76.000000},{"val(a)":30.000000},{"val(a)":38.000000}]}}`, js)
   736  }
   737  
   738  func TestMathVar3(t *testing.T) {
   739  
   740  	query := `
   741  		{
   742  			f as me(func: anyofterms(name, "Rick Michonne Andrea")) {
   743  				ageVar as age
   744  				a as math(ageVar *2)
   745  			}
   746  
   747  			me2(func: uid(f)) {
   748  				val(a)
   749  			}
   750  		}
   751  	`
   752  	js := processQueryNoErr(t, query)
   753  	require.JSONEq(t, `{"data": {"me":[{"age":38,"val(a)":76.000000},{"age":15,"val(a)":30.000000},{"age":19,"val(a)":38.000000}],"me2":[{"val(a)":76.000000},{"val(a)":30.000000},{"val(a)":38.000000}]}}`, js)
   754  }
   755  
   756  func TestMultipleEquality(t *testing.T) {
   757  
   758  	query := `
   759  	{
   760  		me(func: eq(name, ["Rick Grimes"])) {
   761  			name
   762  			friend {
   763  				name
   764  			}
   765  		}
   766  	}
   767  
   768  
   769          `
   770  	js := processQueryNoErr(t, query)
   771  	require.JSONEq(t, `{"data": {"me":[{"friend":[{"name":"Michonne"}],"name":"Rick Grimes"}]}}`, js)
   772  }
   773  
   774  func TestMultipleEquality2(t *testing.T) {
   775  
   776  	query := `
   777  	{
   778  		me(func: eq(name, ["Badger", "Bobby", "Matt"])) {
   779  			name
   780  			friend {
   781  				name
   782  			}
   783  		}
   784  	}
   785  
   786          `
   787  	js := processQueryNoErr(t, query)
   788  	require.JSONEq(t, `{"data": {"me":[{"name":"Matt"},{"name":"Badger"}]}}`, js)
   789  }
   790  
   791  func TestMultipleEquality3(t *testing.T) {
   792  
   793  	query := `
   794  	{
   795  		me(func: eq(dob, ["1910-01-01", "1909-05-05"])) {
   796  			name
   797  			friend {
   798  				name
   799  			}
   800  		}
   801  	}
   802  
   803          `
   804  	js := processQueryNoErr(t, query)
   805  	require.JSONEq(t, `{"data": {"me":[{"friend":[{"name":"Rick Grimes"},{"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"name":"Andrea"}],"name":"Michonne"},{"name":"Glenn Rhee"}]}}`, js)
   806  }
   807  
   808  func TestMultipleEquality4(t *testing.T) {
   809  
   810  	query := `
   811  	{
   812  		me(func: eq(dob, ["1910-01-01", "1909-05-05"])) {
   813  			name
   814  			friend @filter(eq(name, ["Rick Grimes", "Andrea"])) {
   815  				name
   816  			}
   817  		}
   818  	}
   819  
   820          `
   821  	js := processQueryNoErr(t, query)
   822  	require.JSONEq(t, `{"data": {"me":[{"friend":[{"name":"Rick Grimes"},{"name":"Andrea"}],"name":"Michonne"},{"name":"Glenn Rhee"}]}}`, js)
   823  }
   824  
   825  func TestMultipleEquality5(t *testing.T) {
   826  
   827  	query := `
   828  	{
   829  		me(func: eq(name@en, ["Honey badger", "Honey bee"])) {
   830  			name@en
   831  		}
   832  	}
   833  
   834          `
   835  	js := processQueryNoErr(t, query)
   836  	require.JSONEq(t, `{"data": {"me":[{"name@en":"Honey badger"},{"name@en":"Honey bee"}]}}`, js)
   837  }
   838  
   839  func TestMultipleGtError(t *testing.T) {
   840  
   841  	query := `
   842  	{
   843  		me(func: gt(name, ["Badger", "Bobby"])) {
   844  			name
   845  			friend {
   846  				name
   847  			}
   848  		}
   849  	}
   850  
   851    `
   852  	_, err := processQuery(context.Background(), t, query)
   853  	require.Error(t, err)
   854  }
   855  
   856  func TestMultipleEqQuote(t *testing.T) {
   857  
   858  	query := `
   859  	{
   860  		me(func: eq(name, ["Alice\"", "Michonne"])) {
   861  			name
   862  			friend {
   863  				name
   864  			}
   865  		}
   866  	}
   867  `
   868  	js := processQueryNoErr(t, query)
   869  	require.JSONEq(t, `{"data": {"me":[{"friend":[{"name":"Rick Grimes"},{"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"name":"Andrea"}],"name":"Michonne"},{"name":"Alice\""}]}}`, js)
   870  }
   871  
   872  func TestMultipleEqInt(t *testing.T) {
   873  
   874  	query := `
   875  	{
   876  		me(func: eq(age, [15, 17, 38])) {
   877  			name
   878  			friend {
   879  				name
   880  			}
   881  		}
   882  	}
   883  `
   884  	js := processQueryNoErr(t, query)
   885  	require.JSONEq(t, `{"data": {"me":[{"name":"Michonne","friend":[{"name":"Rick Grimes"},{"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"name":"Andrea"}]},{"name":"Rick Grimes","friend":[{"name":"Michonne"}]},{"name":"Glenn Rhee"},{"name":"Daryl Dixon"}]}}`, js)
   886  }
   887  
   888  func TestUidFunction(t *testing.T) {
   889  
   890  	query := `
   891  	{
   892  		me(func: uid(23, 1, 24, 25, 31)) {
   893  			name
   894  		}
   895  	}`
   896  	js := processQueryNoErr(t, query)
   897  	require.JSONEq(t, `{"data": {"me":[{"name":"Michonne"},{"name":"Rick Grimes"},{"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"name":"Andrea"}]}}`, js)
   898  }
   899  
   900  func TestUidFunctionInFilter(t *testing.T) {
   901  
   902  	query := `
   903  	{
   904  		me(func: uid(23, 1, 24, 25, 31))  @filter(uid(1, 24)) {
   905  			name
   906  		}
   907  	}`
   908  	js := processQueryNoErr(t, query)
   909  	require.JSONEq(t, `{"data": {"me":[{"name":"Michonne"},{"name":"Glenn Rhee"}]}}`, js)
   910  }
   911  
   912  func TestUidFunctionInFilter2(t *testing.T) {
   913  
   914  	query := `
   915  	{
   916  		me(func: uid(23, 1, 24, 25, 31)) {
   917  			name
   918  			# Filtering only Michonne and Rick.
   919  			friend @filter(uid(23, 1)) {
   920  				name
   921  			}
   922  		}
   923  	}`
   924  	js := processQueryNoErr(t, query)
   925  	require.JSONEq(t, `{"data": {"me":[{"name":"Michonne","friend":[{"name":"Rick Grimes"}]},{"name":"Rick Grimes","friend":[{"name":"Michonne"}]},{"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"name":"Andrea"}]}}`, js)
   926  }
   927  
   928  func TestUidFunctionInFilter3(t *testing.T) {
   929  
   930  	query := `
   931  	{
   932  		me(func: anyofterms(name, "Michonne Andrea")) @filter(uid(1)) {
   933  			name
   934  		}
   935  	}`
   936  	js := processQueryNoErr(t, query)
   937  	require.JSONEq(t, `{"data": {"me":[{"name":"Michonne"}]}}`, js)
   938  }
   939  
   940  func TestUidFunctionInFilter4(t *testing.T) {
   941  
   942  	query := `
   943  	{
   944  		me(func: anyofterms(name, "Michonne Andrea")) @filter(not uid(1, 31)) {
   945  			name
   946  		}
   947  	}`
   948  	js := processQueryNoErr(t, query)
   949  	require.JSONEq(t, `{"data": {"me":[{"name":"Andrea With no friends"}]}}`, js)
   950  }
   951  
   952  func TestUidInFunction(t *testing.T) {
   953  
   954  	query := `
   955  	{
   956  		me(func: uid(1, 23, 24)) @filter(uid_in(friend, 23)) {
   957  			name
   958  		}
   959  	}`
   960  	js := processQueryNoErr(t, query)
   961  	require.JSONEq(t, `{"data": {"me":[{"name":"Michonne"}]}}`, js)
   962  }
   963  
   964  func TestUidInFunction1(t *testing.T) {
   965  
   966  	query := `
   967  	{
   968  		me(func: UID(1, 23, 24)) @filter(uid_in(school, 5000)) {
   969  			name
   970  		}
   971  	}`
   972  	js := processQueryNoErr(t, query)
   973  	require.JSONEq(t, `{"data": {"me":[{"name":"Michonne"},{"name":"Glenn Rhee"}]}}`, js)
   974  }
   975  
   976  func TestUidInFunction2(t *testing.T) {
   977  
   978  	query := `
   979  	{
   980  		me(func: uid(1, 23, 24)) {
   981  			friend @filter(uid_in(school, 5000)) {
   982  				name
   983  			}
   984  		}
   985  	}`
   986  	js := processQueryNoErr(t, query)
   987  	require.JSONEq(t, `{"data": {"me":[{"friend":[{"name":"Glenn Rhee"},{"name":"Daryl Dixon"}]},{"friend":[{"name":"Michonne"}]}]}}`,
   988  		js)
   989  }
   990  
   991  func TestUidInFunctionAtRoot(t *testing.T) {
   992  
   993  	query := `
   994  	{
   995  		me(func: uid_in(school, 5000)) {
   996  				name
   997  		}
   998  	}`
   999  
  1000  	_, err := processQuery(context.Background(), t, query)
  1001  	require.Error(t, err)
  1002  }
  1003  
  1004  func TestBinaryJSON(t *testing.T) {
  1005  	query := `
  1006  	{
  1007  		me(func: uid(1)) {
  1008  			name
  1009  			bin_data
  1010  		}
  1011  	}`
  1012  	js := processQueryNoErr(t, query)
  1013  	require.JSONEq(t, `{"data": {"me":[{"name":"Michonne","bin_data":"YmluLWRhdGE="}]}}`, js)
  1014  }
  1015  
  1016  func TestReflexive(t *testing.T) {
  1017  
  1018  	query := `
  1019  	{
  1020  		me(func:anyofterms(name, "Michonne Rick Daryl")) @ignoreReflex {
  1021  			name
  1022  			friend {
  1023  				name
  1024  				friend {
  1025  					name
  1026  				}
  1027  			}
  1028  		}
  1029  	}`
  1030  	js := processQueryNoErr(t, query)
  1031  	require.JSONEq(t, `{"data": {"me":[{"friend":[{"name":"Rick Grimes"},{"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"friend":[{"name":"Glenn Rhee"}],"name":"Andrea"}],"name":"Michonne"},{"friend":[{"friend":[{"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"name":"Andrea"}],"name":"Michonne"}],"name":"Rick Grimes"},{"name":"Daryl Dixon"}]}}`, js)
  1032  }
  1033  
  1034  func TestReflexive2(t *testing.T) {
  1035  
  1036  	query := `
  1037  	{
  1038  		me(func:anyofterms(name, "Michonne Rick Daryl")) @IGNOREREFLEX {
  1039  			name
  1040  			friend {
  1041  				name
  1042  				friend {
  1043  					name
  1044  				}
  1045  			}
  1046  		}
  1047  	}`
  1048  	js := processQueryNoErr(t, query)
  1049  	require.JSONEq(t, `{"data": {"me":[{"friend":[{"name":"Rick Grimes"},{"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"friend":[{"name":"Glenn Rhee"}],"name":"Andrea"}],"name":"Michonne"},{"friend":[{"friend":[{"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"name":"Andrea"}],"name":"Michonne"}],"name":"Rick Grimes"},{"name":"Daryl Dixon"}]}}`, js)
  1050  }
  1051  
  1052  func TestReflexive3(t *testing.T) {
  1053  
  1054  	query := `
  1055  	{
  1056  		me(func:anyofterms(name, "Michonne Rick Daryl")) @IGNOREREFLEX @normalize {
  1057  			Me: name
  1058  			friend {
  1059  				Friend: name
  1060  				friend {
  1061  					Cofriend: name
  1062  				}
  1063  			}
  1064  		}
  1065  	}`
  1066  	js := processQueryNoErr(t, query)
  1067  	require.JSONEq(t, `{"data": {"me":[{"Friend":"Rick Grimes","Me":"Michonne"},{"Friend":"Glenn Rhee","Me":"Michonne"},{"Friend":"Daryl Dixon","Me":"Michonne"},{"Cofriend":"Glenn Rhee","Friend":"Andrea","Me":"Michonne"},{"Cofriend":"Glenn Rhee","Friend":"Michonne","Me":"Rick Grimes"},{"Cofriend":"Daryl Dixon","Friend":"Michonne","Me":"Rick Grimes"},{"Cofriend":"Andrea","Friend":"Michonne","Me":"Rick Grimes"},{"Me":"Daryl Dixon"}]}}`, js)
  1068  }
  1069  
  1070  func TestCascadeUid(t *testing.T) {
  1071  
  1072  	query := `
  1073  		{
  1074  			me(func: uid(0x01)) @cascade {
  1075  				name
  1076  				gender
  1077  				friend {
  1078  					uid
  1079  					name
  1080  					friend{
  1081  						name
  1082  						dob
  1083  						age
  1084  					}
  1085  				}
  1086  			}
  1087  		}
  1088  	`
  1089  
  1090  	js := processQueryNoErr(t, query)
  1091  	require.JSONEq(t, `{"data": {"me":[{"friend":[{"uid":"0x17","friend":[{"age":38,"dob":"1910-01-01T00:00:00Z","name":"Michonne"}],"name":"Rick Grimes"},{"uid":"0x1f","friend":[{"age":15,"dob":"1909-05-05T00:00:00Z","name":"Glenn Rhee"}],"name":"Andrea"}],"gender":"female","name":"Michonne"}]}}`, js)
  1092  }
  1093  
  1094  func TestUseVariableBeforeDefinitionError(t *testing.T) {
  1095  
  1096  	query := `
  1097  {
  1098  	me(func: anyofterms(name, "Michonne Daryl Andrea"), orderasc: val(avgAge)) {
  1099  		name
  1100  		friend {
  1101  			x as age
  1102  		}
  1103  		avgAge as avg(val(x))
  1104  	}
  1105  }`
  1106  
  1107  	_, err := processQuery(context.Background(), t, query)
  1108  	require.Contains(t, err.Error(), "Variable: [avgAge] used before definition.")
  1109  }
  1110  
  1111  func TestAggregateRoot1(t *testing.T) {
  1112  
  1113  	query := `
  1114  		{
  1115  			var(func: anyofterms(name, "Rick Michonne Andrea")) {
  1116  				a as age
  1117  			}
  1118  
  1119  			me() {
  1120  				sum(val(a))
  1121  			}
  1122  		}
  1123  	`
  1124  	js := processQueryNoErr(t, query)
  1125  	require.JSONEq(t, `{"data": {"me":[{"sum(val(a))":72}]}}`, js)
  1126  }
  1127  
  1128  func TestAggregateRoot2(t *testing.T) {
  1129  
  1130  	query := `
  1131  		{
  1132  			var(func: anyofterms(name, "Rick Michonne Andrea")) {
  1133  				a as age
  1134  			}
  1135  
  1136  			me() {
  1137  				avg(val(a))
  1138  				min(val(a))
  1139  				max(val(a))
  1140  			}
  1141  		}
  1142  	`
  1143  	js := processQueryNoErr(t, query)
  1144  	require.JSONEq(t, `{"data": {"me":[{"avg(val(a))":24.000000},{"min(val(a))":15},{"max(val(a))":38}]}}`, js)
  1145  }
  1146  
  1147  func TestAggregateRoot3(t *testing.T) {
  1148  
  1149  	query := `
  1150  		{
  1151  			me1(func: anyofterms(name, "Rick Michonne Andrea")) {
  1152  				a as age
  1153  			}
  1154  
  1155  			me() {
  1156  				sum(val(a))
  1157  			}
  1158  		}
  1159  	`
  1160  	js := processQueryNoErr(t, query)
  1161  	require.JSONEq(t, `{"data": {"me1":[{"age":38},{"age":15},{"age":19}],"me":[{"sum(val(a))":72}]}}`, js)
  1162  }
  1163  
  1164  func TestAggregateRoot4(t *testing.T) {
  1165  
  1166  	query := `
  1167  		{
  1168  			var(func: anyofterms(name, "Rick Michonne Andrea")) {
  1169  				a as age
  1170  			}
  1171  
  1172  			me() {
  1173  				minVal as min(val(a))
  1174  				maxVal as max(val(a))
  1175  				Sum: math(minVal + maxVal)
  1176  			}
  1177  		}
  1178  	`
  1179  	js := processQueryNoErr(t, query)
  1180  	require.JSONEq(t, `{"data": {"me":[{"min(val(a))":15},{"max(val(a))":38},{"Sum":53.000000}]}}`, js)
  1181  }
  1182  
  1183  func TestAggregateRoot5(t *testing.T) {
  1184  
  1185  	query := `
  1186  		{
  1187  			var(func: anyofterms(name, "Rick Michonne Andrea")) {
  1188  				# money edge doesn't exist
  1189  				m as money
  1190  			}
  1191  
  1192  			me() {
  1193  				sum(val(m))
  1194  			}
  1195  		}
  1196  	`
  1197  	js := processQueryNoErr(t, query)
  1198  	require.JSONEq(t, `{"data": {"me":[{"sum(val(m))":0.000000}]}}`, js)
  1199  }
  1200  
  1201  func TestAggregateRoot6(t *testing.T) {
  1202  	query := `
  1203  		{
  1204  			uids as var(func: anyofterms(name, "Rick Michonne Andrea"))
  1205  
  1206  			var(func: uid(uids)) @cascade {
  1207  				reason {
  1208  					killed_zombies as math(1)
  1209  				}
  1210  				zombie_count as sum(val(killed_zombies))
  1211  			}
  1212  
  1213  			me(func: uid(uids)) {
  1214  				money: val(zombie_count)
  1215  			}
  1216  		}
  1217  	`
  1218  	js := processQueryNoErr(t, query)
  1219  	require.JSONEq(t, `{"data": {"me":[]}}`, js)
  1220  }
  1221  
  1222  func TestAggregateRootError(t *testing.T) {
  1223  
  1224  	query := `
  1225  		{
  1226  			var(func: anyofterms(name, "Rick Michonne Andrea")) {
  1227  				a as age
  1228  			}
  1229  
  1230  			var(func: anyofterms(name, "Rick Michonne")) {
  1231  				a2 as age
  1232  			}
  1233  
  1234  			me() {
  1235  				Sum: math(a + a2)
  1236  			}
  1237  		}
  1238  	`
  1239  	_, err := processQuery(context.Background(), t, query)
  1240  	require.Error(t, err)
  1241  	require.Contains(t, err.Error(), "Only aggregated variables allowed within empty block.")
  1242  }
  1243  
  1244  func TestAggregateEmpty1(t *testing.T) {
  1245  	query := `
  1246  	{
  1247  		var(func: has(number)) {
  1248  			number as number
  1249  		}
  1250  		var() {
  1251  			highest as max(val(number))
  1252  		}
  1253  
  1254  		all(func: eq(number, val(highest))) {
  1255  			uid
  1256  			number
  1257  		}
  1258  	}`
  1259  
  1260  	js := processQueryNoErr(t, query)
  1261  	require.JSONEq(t, `{"data": {"all":[]}}`, js)
  1262  }
  1263  
  1264  func TestAggregateEmpty2(t *testing.T) {
  1265  	query := `
  1266  		{
  1267  			var(func: has(number))
  1268  			{
  1269  				highest_number as number
  1270  			}
  1271  			all(func: eq(number, val(highest_number)))
  1272  			{
  1273  				uid
  1274  			}
  1275  		}
  1276  	`
  1277  	js := processQueryNoErr(t, query)
  1278  	require.JSONEq(t, `{"data": {"all":[]}}`, js)
  1279  }
  1280  
  1281  func TestAggregateEmpty3(t *testing.T) {
  1282  	query := `
  1283  		{
  1284  			var(func: has(number))
  1285  			{
  1286  				highest_number as number
  1287  			}
  1288  			all(func: ge(number, val(highest_number)))
  1289  			{
  1290  				uid
  1291  			}
  1292  		}
  1293  	`
  1294  	js := processQueryNoErr(t, query)
  1295  	require.JSONEq(t, `{"data": {"all":[]}}`, js)
  1296  }
  1297  
  1298  func TestFilterLang(t *testing.T) {
  1299  	// This tests the fix for #1334. While getting uids for filter, we fetch data keys when number
  1300  	// of uids is less than number of tokens. Lang tag was not passed correctly while fetching these
  1301  	// data keys.
  1302  
  1303  	query := `
  1304  		{
  1305  			me(func: uid(0x1001, 0x1002, 0x1003)) @filter(ge(name@en, "D"))  {
  1306  				name@en
  1307  			}
  1308  		}
  1309  	`
  1310  	js := processQueryNoErr(t, query)
  1311  	require.JSONEq(t,
  1312  		`{"data": {"me":[{"name@en":"European badger"},{"name@en":"Honey badger"},{"name@en":"Honey bee"}]}}`, js)
  1313  }
  1314  
  1315  func TestMathCeil1(t *testing.T) {
  1316  
  1317  	query := `
  1318  	{
  1319  		me as var(func: eq(name, "XxXUnknownXxX"))
  1320  		var(func: uid(me)) {
  1321  			friend {
  1322  				x as age
  1323  			}
  1324  			x2 as sum(val(x))
  1325  			c as count(friend)
  1326  		}
  1327  
  1328  		me(func: uid(me)) {
  1329  			ceilAge: math(ceil(x2/c))
  1330  		}
  1331  	}
  1332  	`
  1333  	js := processQueryNoErr(t, query)
  1334  	require.JSONEq(t, `{"data": {"me": []}}`, js)
  1335  }
  1336  
  1337  func TestMathCeil2(t *testing.T) {
  1338  
  1339  	query := `
  1340  	{
  1341  		me as var(func: eq(name, "Michonne"))
  1342  		var(func: uid(me)) {
  1343  			friend {
  1344  				x as age
  1345  			}
  1346  			x2 as sum(val(x))
  1347  			c as count(friend)
  1348  		}
  1349  
  1350  		me(func: uid(me)) {
  1351  			ceilAge: math(ceil(x2/c))
  1352  		}
  1353  	}
  1354  	`
  1355  	js := processQueryNoErr(t, query)
  1356  	require.JSONEq(t, `{"data": {"me":[{"ceilAge":14.000000}]}}`, js)
  1357  }
  1358  
  1359  func TestUidAttr(t *testing.T) {
  1360  	tests := []struct {
  1361  		in, out, failure string
  1362  	}{
  1363  		{in: `{q(func:ge(uid, 1)) { uid }}`,
  1364  			failure: `Argument cannot be "uid`},
  1365  		{in: `{q(func:eq(uid, 2)) { uid }}`,
  1366  			failure: `Argument cannot be "uid`},
  1367  		{in: `{q(func:lt(uid, 3)) { uid }}`,
  1368  			failure: `Argument cannot be "uid`},
  1369  		{in: `{q(func:has(uid)) { uid }}`,
  1370  			failure: `Argument cannot be "uid`},
  1371  		{in: `{q(func:anyoftext(uid, "")) { uid }}`,
  1372  			failure: `Argument cannot be "uid`},
  1373  		{in: `{q(func:alloftext(uid, "")) { uid }}`,
  1374  			failure: `Argument cannot be "uid`},
  1375  		{in: `{q(func:regexp(uid)) { uid }}`,
  1376  			failure: `Argument cannot be "uid`},
  1377  		{in: `{q(func:match(uid, "", 8)) { uid }}`,
  1378  			failure: `Argument cannot be "uid`},
  1379  		{in: `{q(func:has(name)) @filter(uid_in(uid, 0x1)) { uid }}`,
  1380  			failure: `Argument cannot be "uid"`},
  1381  		{in: `{q(func:uid(0x1)) { checkpwd(uid, "") }}`,
  1382  			failure: `Argument cannot be "uid"`},
  1383  		{in: `{q(func:uid(0x1)) { uid }}`,
  1384  			out: `{"data":{"q":[{"uid":"0x1"}]}}`},
  1385  		{in: `{q(func:eq(name, "uid")) { uid }}`,
  1386  			out: `{"data":{"q":[]}}`},
  1387  	}
  1388  	for _, tc := range tests {
  1389  		js, err := processQuery(context.Background(), t, tc.in)
  1390  		if tc.failure != "" {
  1391  			require.Error(t, err)
  1392  			require.Contains(t, err.Error(), tc.failure)
  1393  		} else {
  1394  			require.NoError(t, err)
  1395  			require.JSONEq(t, tc.out, js)
  1396  		}
  1397  	}
  1398  }
  1399  
  1400  func TestMultipleValueFilter(t *testing.T) {
  1401  
  1402  	query := `
  1403  	{
  1404  		me(func: ge(graduation, "1930")) {
  1405  			name
  1406  			graduation
  1407  		}
  1408  	}
  1409  	`
  1410  	js := processQueryNoErr(t, query)
  1411  	require.JSONEq(t, `{"data": {"me":[{"name":"Michonne","graduation":["1932-01-01T00:00:00Z"]},{"name":"Andrea","graduation":["1935-01-01T00:00:00Z","1933-01-01T00:00:00Z"]}]}}`, js)
  1412  }
  1413  
  1414  func TestMultipleValueFilter2(t *testing.T) {
  1415  
  1416  	query := `
  1417  	{
  1418  		me(func: le(graduation, "1933")) {
  1419  			name
  1420  			graduation
  1421  		}
  1422  	}
  1423  	`
  1424  	js := processQueryNoErr(t, query)
  1425  	require.JSONEq(t, `{"data": {"me":[{"name":"Michonne","graduation":["1932-01-01T00:00:00Z"]},{"name":"Andrea","graduation":["1935-01-01T00:00:00Z","1933-01-01T00:00:00Z"]}]}}`, js)
  1426  }
  1427  
  1428  func TestMultipleValueArray(t *testing.T) {
  1429  
  1430  	query := `
  1431  	{
  1432  		me(func: uid(1)) {
  1433  			name
  1434  			graduation
  1435  		}
  1436  	}
  1437  	`
  1438  	js := processQueryNoErr(t, query)
  1439  	require.JSONEq(t, `{"data": {"me":[{"name":"Michonne","graduation":["1932-01-01T00:00:00Z"]}]}}`, js)
  1440  }
  1441  
  1442  func TestMultipleValueArray2(t *testing.T) {
  1443  
  1444  	query := `
  1445  	{
  1446  		me(func: uid(1)) {
  1447  			graduation
  1448  			name
  1449  		}
  1450  	}
  1451  	`
  1452  	js := processQueryNoErr(t, query)
  1453  	require.JSONEq(t, `{"data": {"me":[{"name":"Michonne","graduation":["1932-01-01T00:00:00Z"]}]}}`, js)
  1454  }
  1455  
  1456  func TestMultipleValueHasAndCount(t *testing.T) {
  1457  
  1458  	query := `
  1459  	{
  1460  		me(func: has(graduation)) {
  1461  			name
  1462  			count(graduation)
  1463  			graduation
  1464  		}
  1465  	}
  1466  	`
  1467  	js := processQueryNoErr(t, query)
  1468  	require.JSONEq(t, `{"data": {"me":[{"name":"Michonne","count(graduation)":1,"graduation":["1932-01-01T00:00:00Z"]},{"name":"Andrea","count(graduation)":2,"graduation":["1935-01-01T00:00:00Z","1933-01-01T00:00:00Z"]}]}}`, js)
  1469  }
  1470  
  1471  func TestMultipleValueSortError(t *testing.T) {
  1472  
  1473  	query := `
  1474  	{
  1475  		me(func: anyofterms(name, "Michonne Rick"), orderdesc: graduation) {
  1476  			name
  1477  			graduation
  1478  		}
  1479  	}
  1480  	`
  1481  	_, err := processQuery(context.Background(), t, query)
  1482  	require.Error(t, err)
  1483  	require.Contains(t, err.Error(), "Sorting not supported on attr: graduation of type: [scalar]")
  1484  }
  1485  
  1486  func TestMultipleValueGroupByError(t *testing.T) {
  1487  	t.Skip()
  1488  
  1489  	query := `
  1490  	{
  1491  		me(func: uid(1)) {
  1492  			friend @groupby(name, graduation) {
  1493  				count(uid)
  1494  			}
  1495  		}
  1496  	}
  1497  	`
  1498  	_, err := processQuery(context.Background(), t, query)
  1499  	require.Error(t, err)
  1500  	require.Contains(t, err.Error(), "Groupby not allowed for attr: graduation of type list")
  1501  }
  1502  
  1503  func TestMultiPolygonIntersects(t *testing.T) {
  1504  
  1505  	usc, err := ioutil.ReadFile("testdata/us-coordinates.txt")
  1506  	require.NoError(t, err)
  1507  	query := `{
  1508  		me(func: intersects(geometry, "` + strings.TrimSpace(string(usc)) + `" )) {
  1509  			name
  1510  		}
  1511  	}
  1512  	`
  1513  
  1514  	js := processQueryNoErr(t, query)
  1515  	require.JSONEq(t, `{"data": {"me":[{"name":"Googleplex"},{"name":"Shoreline Amphitheater"},{"name":"San Carlos Airport"},{"name":"SF Bay area"},{"name":"Mountain View"},{"name":"San Carlos"}, {"name": "New York"}]}}`, js)
  1516  }
  1517  
  1518  func TestMultiPolygonWithin(t *testing.T) {
  1519  
  1520  	usc, err := ioutil.ReadFile("testdata/us-coordinates.txt")
  1521  	require.NoError(t, err)
  1522  	query := `{
  1523  		me(func: within(geometry, "` + strings.TrimSpace(string(usc)) + `" )) {
  1524  			name
  1525  		}
  1526  	}
  1527  	`
  1528  
  1529  	js := processQueryNoErr(t, query)
  1530  	require.JSONEq(t, `{"data": {"me":[{"name":"Googleplex"},{"name":"Shoreline Amphitheater"},{"name":"San Carlos Airport"},{"name":"Mountain View"},{"name":"San Carlos"}]}}`, js)
  1531  }
  1532  
  1533  func TestNearPointMultiPolygon(t *testing.T) {
  1534  
  1535  	query := `{
  1536  		me(func: near(loc, [1.0, 1.0], 1)) {
  1537  			name
  1538  		}
  1539  	}`
  1540  
  1541  	js := processQueryNoErr(t, query)
  1542  	require.JSONEq(t, `{"data": {"me":[{"name":"Rick Grimes"}]}}`, js)
  1543  }
  1544  
  1545  func TestMultiSort1(t *testing.T) {
  1546  
  1547  	time.Sleep(10 * time.Millisecond)
  1548  
  1549  	query := `{
  1550  		me(func: uid(10005, 10006, 10001, 10002, 10003, 10004, 10007, 10000), orderasc: name, orderasc: age) {
  1551  			name
  1552  			age
  1553  		}
  1554  	}`
  1555  
  1556  	js := processQueryNoErr(t, query)
  1557  	require.JSONEq(t, `{"data": {"me":[{"name":"Alice","age":25},{"name":"Alice","age":75},{"name":"Alice","age":75},{"name":"Bob","age":25},{"name":"Bob","age":75},{"name":"Colin","age":25},{"name":"Elizabeth","age":25},{"name":"Elizabeth","age":75}]}}`, js)
  1558  }
  1559  
  1560  func TestMultiSort2(t *testing.T) {
  1561  
  1562  	query := `{
  1563  		me(func: uid(10005, 10006, 10001, 10002, 10003, 10004, 10007, 10000), orderasc: name, orderdesc: age) {
  1564  			name
  1565  			age
  1566  		}
  1567  	}`
  1568  
  1569  	js := processQueryNoErr(t, query)
  1570  	require.JSONEq(t, `{"data": {"me":[{"name":"Alice","age":75},{"name":"Alice","age":75},{"name":"Alice","age":25},{"name":"Bob","age":75},{"name":"Bob","age":25},{"name":"Colin","age":25},{"name":"Elizabeth","age":75},{"name":"Elizabeth","age":25}]}}`, js)
  1571  }
  1572  
  1573  func TestMultiSort3(t *testing.T) {
  1574  
  1575  	query := `{
  1576  		me(func: uid(10005, 10006, 10001, 10002, 10003, 10004, 10007, 10000), orderasc: age, orderdesc: name) {
  1577  			name
  1578  			age
  1579  		}
  1580  	}`
  1581  
  1582  	js := processQueryNoErr(t, query)
  1583  	require.JSONEq(t, `{"data": {"me":[{"name":"Elizabeth","age":25},{"name":"Colin","age":25},{"name":"Bob","age":25},{"name":"Alice","age":25},{"name":"Elizabeth","age":75},{"name":"Bob","age":75},{"name":"Alice","age":75},{"name":"Alice","age":75}]}}`, js)
  1584  }
  1585  
  1586  func TestMultiSort4(t *testing.T) {
  1587  
  1588  	query := `{
  1589  		me(func: uid(10005, 10006, 10001, 10002, 10003, 10004, 10007, 10000), orderasc: name, orderasc: salary) {
  1590  			name
  1591  			age
  1592  			salary
  1593  		}
  1594  	}`
  1595  	js := processQueryNoErr(t, query)
  1596  	// Null value for third Alice comes at last.
  1597  	require.JSONEq(t, `{"data": {"me":[{"name":"Alice","age":25,"salary":10000.000000},{"name":"Alice","age":75,"salary":10002.000000},{"name":"Alice","age":75},{"name":"Bob","age":75},{"name":"Bob","age":25},{"name":"Colin","age":25},{"name":"Elizabeth","age":75},{"name":"Elizabeth","age":25}]}}`, js)
  1598  }
  1599  
  1600  func TestMultiSort5(t *testing.T) {
  1601  
  1602  	query := `{
  1603  		me(func: uid(10005, 10006, 10001, 10002, 10003, 10004, 10007, 10000), orderasc: name, orderdesc: salary) {
  1604  			name
  1605  			age
  1606  			salary
  1607  		}
  1608  	}`
  1609  	js := processQueryNoErr(t, query)
  1610  	// Null value for third Alice comes at first.
  1611  	require.JSONEq(t, `{"data": {"me":[{"name":"Alice","age":75},{"name":"Alice","age":75,"salary":10002.000000},{"name":"Alice","age":25,"salary":10000.000000},{"name":"Bob","age":25},{"name":"Bob","age":75},{"name":"Colin","age":25},{"name":"Elizabeth","age":25},{"name":"Elizabeth","age":75}]}}`, js)
  1612  }
  1613  
  1614  func TestMultiSort6Paginate(t *testing.T) {
  1615  
  1616  	query := `{
  1617  		me(func: uid(10005, 10006, 10001, 10002, 10003, 10004, 10007, 10000), orderasc: name, orderdesc: age, first: 7) {
  1618  			name
  1619  			age
  1620  		}
  1621  	}`
  1622  
  1623  	js := processQueryNoErr(t, query)
  1624  	require.JSONEq(t, `{"data": {"me":[{"name":"Alice","age":75},{"name":"Alice","age":75},{"name":"Alice","age":25},{"name":"Bob","age":75},{"name":"Bob","age":25},{"name":"Colin","age":25},{"name":"Elizabeth","age":75}]}}`, js)
  1625  }
  1626  
  1627  func TestMultiSort7Paginate(t *testing.T) {
  1628  
  1629  	query := `{
  1630  		me(func: uid(10005, 10006, 10001, 10002, 10003, 10004, 10007, 10000), orderasc: name, orderasc: age, first: 7) {
  1631  			name
  1632  			age
  1633  		}
  1634  	}`
  1635  
  1636  	js := processQueryNoErr(t, query)
  1637  	require.JSONEq(t, `{"data": {"me":[{"name":"Alice","age":25},{"name":"Alice","age":75},{"name":"Alice","age":75},{"name":"Bob","age":25},{"name":"Bob","age":75},{"name":"Colin","age":25},{"name":"Elizabeth","age":25}]}}`, js)
  1638  }
  1639  
  1640  func TestMultiSortPaginateWithOffset(t *testing.T) {
  1641  	t.Parallel()
  1642  	tests := []struct {
  1643  		name   string
  1644  		query  string
  1645  		result string
  1646  	}{
  1647  		{
  1648  			"Offset in middle of bucket",
  1649  			`{
  1650  			me(func: uid(10005, 10006, 10001, 10002, 10003, 10004, 10007, 10000), orderasc: name, orderasc: age, first: 6, offset: 1) {
  1651  				name
  1652  				age
  1653  			}
  1654  		}`,
  1655  			`{"data": {"me":[{"name":"Alice","age":75},{"name":"Alice","age":75},{"name":"Bob","age":25},{"name":"Bob","age":75},{"name":"Colin","age":25},{"name":"Elizabeth","age":25}]}}`,
  1656  		},
  1657  		{
  1658  			"Offset at boundary of bucket",
  1659  			`{
  1660  			me(func: uid(10005, 10006, 10001, 10002, 10003, 10004, 10007, 10000), orderasc: name, orderasc: age, first: 4, offset: 3) {
  1661  				name
  1662  				age
  1663  			}
  1664  		}`,
  1665  			`{"data": {"me":[{"name":"Bob","age":25},{"name":"Bob","age":75},{"name":"Colin","age":25},{"name":"Elizabeth","age":25}]}}`,
  1666  		},
  1667  		{
  1668  			"Offset in middle of second bucket",
  1669  			`{
  1670  			me(func: uid(10005, 10006, 10001, 10002, 10003, 10004, 10007, 10000), orderasc: name, orderasc: age, first: 3, offset: 4) {
  1671  				name
  1672  				age
  1673  			}
  1674  		}`,
  1675  			`{"data": {"me":[{"name":"Bob","age":75},{"name":"Colin","age":25},{"name":"Elizabeth","age":25}]}}`,
  1676  		},
  1677  		{
  1678  			"Offset equal to number of uids",
  1679  			`{
  1680  			me(func: uid(10005, 10006, 10001, 10002, 10003, 10004, 10007, 10000), orderasc: name, orderasc: age, first: 3, offset: 8) {
  1681  				name
  1682  				age
  1683  			}
  1684  		}`,
  1685  			`{"data": {"me":[]}}`,
  1686  		},
  1687  		{
  1688  			"Offset larger than records",
  1689  			`{
  1690  			me(func: uid(10005, 10006, 10001, 10002, 10003, 10004, 10007, 10000), orderasc: name, orderasc: age, first: 10, offset: 10000) {
  1691  				name
  1692  				age
  1693  			}
  1694  		}`,
  1695  			`{"data": {"me":[]}}`,
  1696  		},
  1697  	}
  1698  
  1699  	for _, tt := range tests {
  1700  		t.Run(tt.name, func(t *testing.T) {
  1701  			js := processQueryNoErr(t, tt.query)
  1702  			require.JSONEq(t, tt.result, js)
  1703  		})
  1704  	}
  1705  }
  1706  
  1707  func TestFilterRootOverride(t *testing.T) {
  1708  
  1709  	query := `{
  1710  		a as var(func: eq(name, "Michonne")) @filter(eq(name, "Rick Grimes"))
  1711  
  1712  		me(func: uid(a)) {
  1713  			uid
  1714  			name
  1715  		}
  1716  	}
  1717  	`
  1718  	js := processQueryNoErr(t, query)
  1719  	require.JSONEq(t, `{"data": {"me": []}}`, js)
  1720  }
  1721  
  1722  func TestFilterRoot(t *testing.T) {
  1723  
  1724  	query := `{
  1725  		me(func: eq(name, "Michonne")) @filter(eq(name, "Rick Grimes")) {
  1726  			uid
  1727  			name
  1728  		}
  1729  	}
  1730  	`
  1731  	js := processQueryNoErr(t, query)
  1732  	require.JSONEq(t, `{"data": {"me": []}}`, js)
  1733  }
  1734  
  1735  func TestMathAlias(t *testing.T) {
  1736  
  1737  	query := `{
  1738  		me(func:allofterms(name, "Michonne")) {
  1739  			p as count(friend)
  1740  			score: math(p + 1)
  1741  			name
  1742  		}
  1743  	}`
  1744  
  1745  	js := processQueryNoErr(t, query)
  1746  	require.JSONEq(t, `{"data": {"me":[{"count(friend)":5,"score":6.000000,"name":"Michonne"}]}}`, js)
  1747  }
  1748  
  1749  func TestUidVariable(t *testing.T) {
  1750  
  1751  	query := `{
  1752  		var(func:allofterms(name, "Michonne")) {
  1753  			friend {
  1754  				f as uid
  1755  			}
  1756  		}
  1757  
  1758  		me(func: uid(f)) {
  1759  			name
  1760  		}
  1761  	}`
  1762  
  1763  	js := processQueryNoErr(t, query)
  1764  	require.JSONEq(t, `{"data": {"me":[{"name":"Rick Grimes"},{"name":"Glenn Rhee"},{"name":"Daryl Dixon"},{"name":"Andrea"}]}}`, js)
  1765  }
  1766  
  1767  func TestMultipleValueVarError(t *testing.T) {
  1768  
  1769  	query := `{
  1770  		var(func:ge(graduation, "1930")) {
  1771  			o as graduation
  1772  		}
  1773  
  1774  		me(func: uid(o)) {
  1775  			graduation
  1776  		}
  1777  	}`
  1778  
  1779  	_, err := processQuery(context.Background(), t, query)
  1780  	require.Error(t, err)
  1781  	require.Contains(t, err.Error(), "Value variables not supported for predicate with list type.")
  1782  }
  1783  
  1784  func TestReturnEmptyBlock(t *testing.T) {
  1785  
  1786  	query := `{
  1787  		me(func:allofterms(name, "Michonne")) @filter(eq(name, "Rick Grimes")) {
  1788  		}
  1789  
  1790  		me2(func: eq(name, "XYZ"))
  1791  
  1792  		me3(func: eq(name, "Michonne")) {
  1793  			name
  1794  		}
  1795  	}`
  1796  
  1797  	js := processQueryNoErr(t, query)
  1798  	require.JSONEq(t, `{"data": {"me":[],"me2":[],"me3":[{"name":"Michonne"}]}}`, js)
  1799  }
  1800  
  1801  func TestExpandVal(t *testing.T) {
  1802  	query := `
  1803  	{
  1804  		var(func: uid(11)) {
  1805  			pred as name
  1806  		}
  1807  
  1808  		me(func: uid(11)) {
  1809  			expand(val(pred))
  1810  		}
  1811  	}
  1812  	`
  1813  	js := processQueryNoErr(t, query)
  1814  	require.JSONEq(t,
  1815  		`{"data":{"me":[{"name":"name"}]}}`, js)
  1816  }
  1817  
  1818  func TestGroupByGeoCrash(t *testing.T) {
  1819  
  1820  	query := `
  1821  	{
  1822  	  q(func: uid(1, 23, 24, 25, 31)) @groupby(loc) {
  1823  	    count(uid)
  1824  	  }
  1825  	}
  1826  	`
  1827  	js := processQueryNoErr(t, query)
  1828  	require.Contains(t, js, `{"loc":{"type":"Point","coordinates":[1.1,2]},"count":2}`)
  1829  }
  1830  
  1831  func TestPasswordError(t *testing.T) {
  1832  
  1833  	query := `
  1834  	{
  1835  		q(func: uid(1)) {
  1836  			checkpwd(name, "Michonne")
  1837  		}
  1838  	}
  1839  	`
  1840  	_, err := processQuery(context.Background(), t, query)
  1841  	require.Error(t, err)
  1842  	require.Contains(t,
  1843  		err.Error(), "checkpwd fn can only be used on attr: [name] with schema type password. Got type: string")
  1844  }
  1845  
  1846  func TestCountPanic(t *testing.T) {
  1847  
  1848  	query := `
  1849  	{
  1850  		q(func: uid(1, 300)) {
  1851  			uid
  1852  			name
  1853  			count(name)
  1854  		}
  1855  	}
  1856  	`
  1857  	js := processQueryNoErr(t, query)
  1858  	require.JSONEq(t, `{"data": {"q":[{"uid":"0x1","name":"Michonne","count(name)":1},{"uid":"0x12c","count(name)":0}]}}`, js)
  1859  }
  1860  
  1861  func TestUidWithoutDebug(t *testing.T) {
  1862  
  1863  	query := `
  1864  	{
  1865  		q(func: uid(1, 24)) {
  1866  			uid
  1867  			friend
  1868  		}
  1869  	}
  1870  	`
  1871  	js := processQueryNoErr(t, query)
  1872  	require.JSONEq(t, `{"data":{"q":[{"uid":"0x1"},{"uid":"0x18"}]}}`, js)
  1873  }
  1874  
  1875  func TestUidWithoutDebug2(t *testing.T) {
  1876  
  1877  	query := `
  1878  	{
  1879  		q(func: uid(1)) {
  1880  			uid
  1881  			friend {
  1882  				uid
  1883  			}
  1884  		}
  1885  	}
  1886  	`
  1887  	js := processQueryNoErr(t, query)
  1888  	require.JSONEq(t, `{"data":{"q":[{"uid":"0x1","friend":[{"uid":"0x17"},{"uid":"0x18"},{"uid":"0x19"},{"uid":"0x1f"},{"uid":"0x65"}]}]}}`, js)
  1889  }
  1890  
  1891  func TestExpandAll_empty_panic(t *testing.T) {
  1892  
  1893  	query := `
  1894  		{
  1895  			me(func: uid(0x01)) @filter(eq(name,"foobar")){
  1896  				expand(_all_)
  1897  			}
  1898  		}
  1899  	`
  1900  	js := processQueryNoErr(t, query)
  1901  	require.JSONEq(t, `{"data":{"me":[]}}`, js)
  1902  }