github.com/unigraph-dev/dgraph@v1.1.1-0.20200923154953-8b52b426f765/query/common_test.go (about) 1 /* 2 * Copyright 2017-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 "fmt" 23 "testing" 24 25 "github.com/stretchr/testify/require" 26 27 "github.com/dgraph-io/dgo" 28 "github.com/dgraph-io/dgo/protos/api" 29 "github.com/dgraph-io/dgraph/testutil" 30 "github.com/dgraph-io/dgraph/x" 31 "google.golang.org/grpc" 32 ) 33 34 func getNewClient() *dgo.Dgraph { 35 conn, err := grpc.Dial(testutil.SockAddr, grpc.WithInsecure()) 36 x.Check(err) 37 return dgo.NewDgraphClient(api.NewDgraphClient(conn)) 38 } 39 40 func setSchema(schema string) { 41 err := client.Alter(context.Background(), &api.Operation{ 42 Schema: schema, 43 }) 44 if err != nil { 45 panic(fmt.Sprintf("Could not alter schema. Got error %v", err.Error())) 46 } 47 } 48 49 func dropPredicate(pred string) { 50 err := client.Alter(context.Background(), &api.Operation{ 51 DropAttr: pred, 52 }) 53 if err != nil { 54 panic(fmt.Sprintf("Could not drop predicate. Got error %v", err.Error())) 55 } 56 } 57 58 func processQuery(ctx context.Context, t *testing.T, query string) (string, error) { 59 txn := client.NewTxn() 60 defer txn.Discard(ctx) 61 62 res, err := txn.Query(ctx, query) 63 if err != nil { 64 return "", err 65 } 66 67 response := map[string]interface{}{} 68 response["data"] = json.RawMessage(string(res.Json)) 69 70 jsonResponse, err := json.Marshal(response) 71 require.NoError(t, err) 72 return string(jsonResponse), err 73 } 74 75 func processQueryNoErr(t *testing.T, query string) string { 76 res, err := processQuery(context.Background(), t, query) 77 require.NoError(t, err) 78 return res 79 } 80 81 func processQueryWithVars(t *testing.T, query string, 82 vars map[string]string) (string, error) { 83 txn := client.NewTxn() 84 defer txn.Discard(context.Background()) 85 86 res, err := txn.QueryWithVars(context.Background(), query, vars) 87 if err != nil { 88 return "", err 89 } 90 91 response := map[string]interface{}{} 92 response["data"] = json.RawMessage(string(res.Json)) 93 94 jsonResponse, err := json.Marshal(response) 95 require.NoError(t, err) 96 return string(jsonResponse), err 97 } 98 99 func addTriplesToCluster(triples string) { 100 txn := client.NewTxn() 101 ctx := context.Background() 102 defer txn.Discard(ctx) 103 104 _, err := txn.Mutate(ctx, &api.Mutation{ 105 SetNquads: []byte(triples), 106 CommitNow: true, 107 }) 108 if err != nil { 109 panic(fmt.Sprintf("Could not add triples. Got error %v", err.Error())) 110 } 111 112 } 113 114 func deleteTriplesInCluster(triples string) { 115 txn := client.NewTxn() 116 ctx := context.Background() 117 defer txn.Discard(ctx) 118 119 _, err := txn.Mutate(ctx, &api.Mutation{ 120 DelNquads: []byte(triples), 121 CommitNow: true, 122 }) 123 if err != nil { 124 panic(fmt.Sprintf("Could not delete triples. Got error %v", err.Error())) 125 } 126 } 127 128 func addGeoPointToCluster(uid uint64, pred string, point []float64) { 129 triple := fmt.Sprintf( 130 `<%d> <%s> "{'type':'Point', 'coordinates':[%v, %v]}"^^<geo:geojson> .`, 131 uid, pred, point[0], point[1]) 132 addTriplesToCluster(triple) 133 } 134 135 func addGeoPolygonToCluster(uid uint64, pred string, polygon [][][]float64) { 136 coordinates := "[" 137 for i, ring := range polygon { 138 coordinates += "[" 139 for j, point := range ring { 140 coordinates += fmt.Sprintf("[%v, %v]", point[0], point[1]) 141 142 if j != len(ring)-1 { 143 coordinates += "," 144 } 145 } 146 147 coordinates += "]" 148 if i != len(polygon)-1 { 149 coordinates += "," 150 } 151 } 152 coordinates += "]" 153 154 triple := fmt.Sprintf( 155 `<%d> <%s> "{'type':'Polygon', 'coordinates': %s}"^^<geo:geojson> .`, 156 uid, pred, coordinates) 157 addTriplesToCluster(triple) 158 } 159 160 func addGeoMultiPolygonToCluster(uid uint64, polygons [][][][]float64) { 161 coordinates := "[" 162 for i, polygon := range polygons { 163 coordinates += "[" 164 for j, ring := range polygon { 165 coordinates += "[" 166 for k, point := range ring { 167 coordinates += fmt.Sprintf("[%v, %v]", point[0], point[1]) 168 169 if k != len(ring)-1 { 170 coordinates += "," 171 } 172 } 173 174 coordinates += "]" 175 if j != len(polygon)-1 { 176 coordinates += "," 177 } 178 } 179 180 coordinates += "]" 181 if i != len(polygons)-1 { 182 coordinates += "," 183 } 184 } 185 coordinates += "]" 186 187 triple := fmt.Sprintf( 188 `<%d> <geometry> "{'type':'MultiPolygon', 'coordinates': %s}"^^<geo:geojson> .`, 189 uid, coordinates) 190 addTriplesToCluster(triple) 191 } 192 193 const testSchema = ` 194 type Person { 195 name: string 196 pet: Animal 197 } 198 199 type Animal { 200 name: string 201 } 202 203 type CarModel { 204 make: string 205 model: string 206 year: int 207 previous_model: CarModel 208 } 209 210 type SchoolInfo { 211 name: string 212 abbr: string 213 school: [uid] 214 district: [uid] 215 state: [uid] 216 county: [uid] 217 } 218 219 type User { 220 name: string 221 password: password 222 } 223 224 type Node { 225 node: uid 226 name: string 227 } 228 229 name : string @index(term, exact, trigram) @count @lang . 230 alias : string @index(exact, term, fulltext) . 231 dob : dateTime @index(year) . 232 dob_day : dateTime @index(day) . 233 film.film.initial_release_date : dateTime @index(year) . 234 loc : geo @index(geo) . 235 genre : [uid] @reverse . 236 survival_rate : float . 237 alive : bool @index(bool) . 238 age : int @index(int) . 239 shadow_deep : int . 240 friend : [uid] @reverse @count . 241 geometry : geo @index(geo) . 242 value : string @index(trigram) . 243 full_name : string @index(hash) . 244 nick_name : string @index(term) . 245 royal_title : string @index(hash, term, fulltext) @lang . 246 noindex_name : string . 247 school : [uid] @count . 248 lossy : string @index(term) @lang . 249 occupations : [string] @index(term) . 250 graduation : [dateTime] @index(year) @count . 251 salary : float @index(float) . 252 password : password . 253 pass : password . 254 symbol : string @index(exact) . 255 room : string @index(term) . 256 office.room : [uid] . 257 best_friend : uid @reverse . 258 pet : [uid] . 259 node : [uid] . 260 model : string @index(term) @lang . 261 make : string @index(term) . 262 year : int . 263 previous_model : uid @reverse . 264 created_at : datetime @index(hour) . 265 updated_at : datetime @index(year) . 266 number : int @index(int) . 267 ` 268 269 func populateCluster() { 270 err := client.Alter(context.Background(), &api.Operation{DropAll: true}) 271 if err != nil { 272 panic(fmt.Sprintf("Could not perform DropAll op. Got error %v", err.Error())) 273 } 274 275 setSchema(testSchema) 276 testutil.AssignUids(100000) 277 278 addTriplesToCluster(` 279 <1> <name> "Michonne" . 280 <2> <name> "King Lear" . 281 <3> <name> "Margaret" . 282 <4> <name> "Leonard" . 283 <5> <name> "Garfield" . 284 <6> <name> "Bear" . 285 <7> <name> "Nemo" . 286 <11> <name> "name" . 287 <23> <name> "Rick Grimes" . 288 <24> <name> "Glenn Rhee" . 289 <25> <name> "Daryl Dixon" . 290 <31> <name> "Andrea" . 291 <33> <name> "San Mateo High School" . 292 <34> <name> "San Mateo School District" . 293 <35> <name> "San Mateo County" . 294 <36> <name> "California" . 295 <110> <name> "Alice" . 296 <240> <name> "Andrea With no friends" . 297 <1000> <name> "Alice" . 298 <1001> <name> "Bob" . 299 <1002> <name> "Matt" . 300 <1003> <name> "John" . 301 <2300> <name> "Andre" . 302 <2301> <name> "Alice\"" . 303 <2333> <name> "Helmut" . 304 <3500> <name> "" . 305 <3500> <name> "상현"@ko . 306 <3501> <name> "Alex" . 307 <3501> <name> "Alex"@en . 308 <3502> <name> "" . 309 <3502> <name> "Amit"@en . 310 <3502> <name> "अमित"@hi . 311 <3503> <name> "Andrew"@en . 312 <3503> <name> ""@hi . 313 <4097> <name> "Badger" . 314 <4097> <name> "European badger"@en . 315 <4097> <name> "European badger barger European"@xx . 316 <4097> <name> "Borsuk europejski"@pl . 317 <4097> <name> "Europäischer Dachs"@de . 318 <4097> <name> "Барсук"@ru . 319 <4097> <name> "Blaireau européen"@fr . 320 <4098> <name> "Honey badger"@en . 321 <4099> <name> "Honey bee"@en . 322 <4100> <name> "Artem Tkachenko"@en . 323 <4100> <name> "Артём Ткаченко"@ru . 324 <5000> <name> "School A" . 325 <5001> <name> "School B" . 326 <5101> <name> "Googleplex" . 327 <5102> <name> "Shoreline Amphitheater" . 328 <5103> <name> "San Carlos Airport" . 329 <5104> <name> "SF Bay area" . 330 <5105> <name> "Mountain View" . 331 <5106> <name> "San Carlos" . 332 <5107> <name> "New York" . 333 <8192> <name> "Regex Master" . 334 <10000> <name> "Alice" . 335 <10001> <name> "Elizabeth" . 336 <10002> <name> "Alice" . 337 <10003> <name> "Bob" . 338 <10004> <name> "Alice" . 339 <10005> <name> "Bob" . 340 <10006> <name> "Colin" . 341 <10007> <name> "Elizabeth" . 342 343 <11000> <name> "Baz Luhrmann"@en . 344 <11001> <name> "Strictly Ballroom"@en . 345 <11002> <name> "Puccini: La boheme (Sydney Opera)"@en . 346 <11003> <name> "No. 5 the film"@en . 347 <11100> <name> "expand" . 348 349 <1> <full_name> "Michonne's large name for hashing" . 350 351 <1> <noindex_name> "Michonne's name not indexed" . 352 353 <1> <friend> <23> . 354 <1> <friend> <24> . 355 <1> <friend> <25> . 356 <1> <friend> <31> . 357 <1> <friend> <101> . 358 <31> <friend> <24> . 359 <23> <friend> <1> . 360 361 <2> <best_friend> <64> (since=2019-03-28T14:41:57+30:00) . 362 <3> <best_friend> <64> (since=2018-03-24T14:41:57+05:30) . 363 <4> <best_friend> <64> (since=2019-03-27) . 364 365 <1> <age> "38" . 366 <23> <age> "15" . 367 <24> <age> "15" . 368 <25> <age> "17" . 369 <31> <age> "19" . 370 <10000> <age> "25" . 371 <10001> <age> "75" . 372 <10002> <age> "75" . 373 <10003> <age> "75" . 374 <10004> <age> "75" . 375 <10005> <age> "25" . 376 <10006> <age> "25" . 377 <10007> <age> "25" . 378 379 <1> <alive> "true" . 380 <23> <alive> "true" . 381 <25> <alive> "false" . 382 <31> <alive> "false" . 383 384 <1> <gender> "female" . 385 <23> <gender> "male" . 386 387 <4001> <office> "office 1" . 388 <4002> <room> "room 1" . 389 <4003> <room> "room 2" . 390 <4004> <room> "" . 391 <4001> <office.room> <4002> . 392 <4001> <office.room> <4003> . 393 <4001> <office.room> <4004> . 394 395 <3001> <symbol> "AAPL" . 396 <3002> <symbol> "AMZN" . 397 <3003> <symbol> "AMD" . 398 <3004> <symbol> "FB" . 399 <3005> <symbol> "GOOG" . 400 <3006> <symbol> "MSFT" . 401 402 <1> <dob> "1910-01-01" . 403 <23> <dob> "1910-01-02" . 404 <24> <dob> "1909-05-05" . 405 <25> <dob> "1909-01-10" . 406 <31> <dob> "1901-01-15" . 407 408 <1> <path> <31> (weight = 0.1, weight1 = 0.2) . 409 <1> <path> <24> (weight = 0.2) . 410 <31> <path> <1000> (weight = 0.1) . 411 <1000> <path> <1001> (weight = 0.1) . 412 <1000> <path> <1002> (weight = 0.7) . 413 <1001> <path> <1002> (weight = 0.1) . 414 <1002> <path> <1003> (weight = 0.6) . 415 <1001> <path> <1003> (weight = 1.5) . 416 <1003> <path> <1001> . 417 418 <1> <follow> <31> . 419 <1> <follow> <24> . 420 <31> <follow> <1001> . 421 <1001> <follow> <1000> . 422 <1002> <follow> <1000> . 423 <1001> <follow> <1003> . 424 <1003> <follow> <1002> . 425 426 <1> <survival_rate> "98.99" . 427 <23> <survival_rate> "1.6" . 428 <24> <survival_rate> "1.6" . 429 <25> <survival_rate> "1.6" . 430 <31> <survival_rate> "1.6" . 431 432 <1> <school> <5000> . 433 <23> <school> <5001> . 434 <24> <school> <5000> . 435 <25> <school> <5000> . 436 <31> <school> <5001> . 437 <101> <school> <5001> . 438 439 <1> <_xid_> "mich" . 440 <24> <_xid_> "g\"lenn" . 441 <110> <_xid_> "a.bc" . 442 443 <23> <alias> "Zambo Alice" . 444 <24> <alias> "John Alice" . 445 <25> <alias> "Bob Joe" . 446 <31> <alias> "Allan Matt" . 447 <101> <alias> "John Oliver" . 448 449 <1> <bin_data> "YmluLWRhdGE=" . 450 451 <1> <graduation> "1932-01-01" . 452 <31> <graduation> "1933-01-01" . 453 <31> <graduation> "1935-01-01" . 454 455 <10000> <salary> "10000" . 456 <10002> <salary> "10002" . 457 458 <1> <address> "31, 32 street, Jupiter" . 459 <23> <address> "21, mark street, Mars" . 460 461 <1> <dob_day> "1910-01-01" . 462 <23> <dob_day> "1910-01-02" . 463 <24> <dob_day> "1909-05-05" . 464 <25> <dob_day> "1909-01-10" . 465 <31> <dob_day> "1901-01-15" . 466 467 <1> <power> "13.25"^^<xs:float> . 468 469 <1> <sword_present> "true" . 470 471 <1> <son> <2300> . 472 <1> <son> <2333> . 473 474 <5010> <nick_name> "Two Terms" . 475 476 <4097> <lossy> "Badger" . 477 <4097> <lossy> "European badger"@en . 478 <4097> <lossy> "European badger barger European"@xx . 479 <4097> <lossy> "Borsuk europejski"@pl . 480 <4097> <lossy> "Europäischer Dachs"@de . 481 <4097> <lossy> "Барсук"@ru . 482 <4097> <lossy> "Blaireau européen"@fr . 483 <4098> <lossy> "Honey badger"@en . 484 485 <23> <film.film.initial_release_date> "1900-01-02" . 486 <24> <film.film.initial_release_date> "1909-05-05" . 487 <25> <film.film.initial_release_date> "1929-01-10" . 488 <31> <film.film.initial_release_date> "1801-01-15" . 489 490 <0x10000> <royal_title> "Her Majesty Elizabeth the Second, by the Grace of God of the United Kingdom of Great Britain and Northern Ireland and of Her other Realms and Territories Queen, Head of the Commonwealth, Defender of the Faith"@en . 491 <0x10000> <royal_title> "Sa Majesté Elizabeth Deux, par la grâce de Dieu Reine du Royaume-Uni, du Canada et de ses autres royaumes et territoires, Chef du Commonwealth, Défenseur de la Foi"@fr . 492 493 <32> <school> <33> . 494 <33> <district> <34> . 495 <34> <county> <35> . 496 <35> <state> <36> . 497 498 <36> <abbr> "CA" . 499 500 <1> <password> "123456" . 501 <32> <password> "123456" . 502 <23> <pass> "654321" . 503 504 <23> <shadow_deep> "4" . 505 <24> <shadow_deep> "14" . 506 507 <1> <dgraph.type> "User" . 508 <2> <dgraph.type> "Person" . 509 <3> <dgraph.type> "Person" . 510 <4> <dgraph.type> "Person" . 511 <5> <dgraph.type> "Animal" . 512 <5> <dgraph.type> "Pet" . 513 <6> <dgraph.type> "Animal" . 514 <6> <dgraph.type> "Pet" . 515 <32> <dgraph.type> "SchoolInfo" . 516 <33> <dgraph.type> "SchoolInfo" . 517 <34> <dgraph.type> "SchoolInfo" . 518 <35> <dgraph.type> "SchoolInfo" . 519 <36> <dgraph.type> "SchoolInfo" . 520 <11100> <dgraph.type> "Node" . 521 522 <2> <pet> <5> . 523 <3> <pet> <6> . 524 <4> <pet> <7> . 525 526 <2> <enemy> <3> . 527 <2> <enemy> <4> . 528 529 <11000> <director.film> <11001> . 530 <11000> <director.film> <11002> . 531 <11000> <director.film> <11003> . 532 533 <11100> <node> <11100> . 534 535 <200> <make> "Ford" . 536 <200> <model> "Focus" . 537 <200> <year> "2008" . 538 <200> <dgraph.type> "CarModel" . 539 540 <201> <make> "Ford" . 541 <201> <model> "Focus" . 542 <201> <year> "2009" . 543 <201> <dgraph.type> "CarModel" . 544 <201> <previous_model> <200> . 545 546 <202> <make> "Toyota" . 547 <202> <year> "2009" . 548 <202> <model> "Prius" . 549 <202> <model> "プリウス"@jp . 550 <202> <dgraph.type> "CarModel" . 551 `) 552 553 addGeoPointToCluster(1, "loc", []float64{1.1, 2.0}) 554 addGeoPointToCluster(24, "loc", []float64{1.10001, 2.000001}) 555 addGeoPointToCluster(25, "loc", []float64{1.1, 2.0}) 556 addGeoPointToCluster(5101, "geometry", []float64{-122.082506, 37.4249518}) 557 addGeoPointToCluster(5102, "geometry", []float64{-122.080668, 37.426753}) 558 addGeoPointToCluster(5103, "geometry", []float64{-122.2527428, 37.513653}) 559 560 addGeoPolygonToCluster(23, "loc", [][][]float64{ 561 {{0.0, 0.0}, {2.0, 0.0}, {2.0, 2.0}, {0.0, 2.0}, {0.0, 0.0}}, 562 }) 563 addGeoPolygonToCluster(5104, "geometry", [][][]float64{ 564 {{-121.6, 37.1}, {-122.4, 37.3}, {-122.6, 37.8}, {-122.5, 38.3}, {-121.9, 38}, 565 {-121.6, 37.1}}, 566 }) 567 addGeoPolygonToCluster(5105, "geometry", [][][]float64{ 568 {{-122.06, 37.37}, {-122.1, 37.36}, {-122.12, 37.4}, {-122.11, 37.43}, 569 {-122.04, 37.43}, {-122.06, 37.37}}, 570 }) 571 addGeoPolygonToCluster(5106, "geometry", [][][]float64{ 572 {{-122.25, 37.49}, {-122.28, 37.49}, {-122.27, 37.51}, {-122.25, 37.52}, 573 {-122.25, 37.49}}, 574 }) 575 576 addGeoMultiPolygonToCluster(5107, [][][][]float64{ 577 {{{-74.29504394531249, 40.19146303804063}, {-74.59716796875, 40.39258071969131}, 578 {-74.6466064453125, 40.20824570152502}, {-74.454345703125, 40.06125658140474}, 579 {-74.28955078125, 40.17467622056341}, {-74.29504394531249, 40.19146303804063}}}, 580 {{{-74.102783203125, 40.8595252289932}, {-74.2730712890625, 40.718119379753446}, 581 {-74.0478515625, 40.66813955408042}, {-73.98193359375, 40.772221877329024}, 582 {-74.102783203125, 40.8595252289932}}}, 583 }) 584 585 // Add data for regex tests. 586 nextId := uint64(0x2000) 587 patterns := []string{"mississippi", "missouri", "mission", "missionary", 588 "whissle", "transmission", "zipped", "monosiphonic", "vasopressin", "vapoured", 589 "virtuously", "zurich", "synopsis", "subsensuously", 590 "admission", "commission", "submission", "subcommission", "retransmission", "omission", 591 "permission", "intermission", "dimission", "discommission", 592 } 593 for _, p := range patterns { 594 triples := fmt.Sprintf(` 595 <%d> <value> "%s" . 596 <0x1234> <pattern> <%d> . 597 `, nextId, p, nextId) 598 addTriplesToCluster(triples) 599 nextId++ 600 } 601 602 // Add data for datetime tests 603 addTriplesToCluster(` 604 <301> <created_at> "2019-03-28T14:41:57+30:00" (modified_at=2019-05-28T14:41:57+30:00) . 605 <302> <created_at> "2019-03-28T13:41:57+29:00" (modified_at=2019-03-28T14:41:57+30:00) . 606 <303> <created_at> "2019-03-27T14:41:57+06:00" (modified_at=2019-03-29) . 607 <304> <created_at> "2019-03-28T15:41:57+30:00" (modified_at=2019-03-27T14:41:57+06:00) . 608 <305> <created_at> "2019-03-28T13:41:57+30:00" (modified_at=2019-03-28) . 609 <306> <created_at> "2019-03-24T14:41:57+05:30" (modified_at=2019-03-28T13:41:57+30:00) . 610 <307> <created_at> "2019-05-28T14:41:57+30:00" . 611 612 <301> <updated_at> "2019-03-28T14:41:57+30:00" (modified_at=2019-05-28) . 613 <302> <updated_at> "2019-03-28T13:41:57+29:00" (modified_at=2019-03-28T14:41:57+30:00) . 614 <303> <updated_at> "2019-03-27T14:41:57+06:00" (modified_at=2019-03-28T13:41:57+29:00) . 615 <304> <updated_at> "2019-03-27T09:41:57" . 616 <305> <updated_at> "2019-03-28T13:41:57+30:00" (modified_at=2019-03-28T15:41:57+30:00) . 617 <306> <updated_at> "2019-03-24T14:41:57+05:30" (modified_at=2019-03-28T13:41:57+30:00) . 618 <307> <updated_at> "2019-05-28" (modified_at=2019-03-24T14:41:57+05:30) . 619 `) 620 }