Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(537)

Side by Side Diff: service/datastore/query.go

Issue 1309803004: Add transaction buffer filter. (Closed) Base URL: https://github.com/luci/gae.git@add_query_support
Patch Set: Fix builtin+ancestor+multi-eq+multiIterator bug, add more txnBuf test Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« service/datastore/key.go ('K') | « service/datastore/key.go ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package datastore 5 package datastore
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "fmt" 9 "fmt"
10 "sort" 10 "sort"
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 } 463 }
464 464
465 // Finalize converts this Query to a FinalizedQuery. If the Query has any 465 // Finalize converts this Query to a FinalizedQuery. If the Query has any
466 // inconsistencies or violates any of the query rules, that will be returned 466 // inconsistencies or violates any of the query rules, that will be returned
467 // here. 467 // here.
468 func (q *Query) Finalize() (*FinalizedQuery, error) { 468 func (q *Query) Finalize() (*FinalizedQuery, error) {
469 if q.err != nil || q.finalized != nil { 469 if q.err != nil || q.finalized != nil {
470 return q.finalized, q.err 470 return q.finalized, q.err
471 } 471 }
472 472
473 ancSlice, hasAncestor := q.eqFilts["__ancestor__"]
474 ancestor := (*Key)(nil)
475 if hasAncestor {
Vadim Sh. 2015/09/28 18:52:56 nit: ancestor := (*Key)(nil) if slice, ok := q.eqF
iannucci 2015/09/29 03:21:37 Nope, you're right. nil ancestor means no ancestor
476 ancestor = ancSlice[0].Value().(*Key)
477 }
478
473 err := func() error { 479 err := func() error {
480
474 if q.kind == "" { // kindless query checks 481 if q.kind == "" { // kindless query checks
475 if q.ineqFiltProp != "" && q.ineqFiltProp != "__key__" { 482 if q.ineqFiltProp != "" && q.ineqFiltProp != "__key__" {
476 return fmt.Errorf( 483 return fmt.Errorf(
477 "kindless queries can only filter on __k ey__, got %q", q.ineqFiltProp) 484 "kindless queries can only filter on __k ey__, got %q", q.ineqFiltProp)
478 } 485 }
479 » » » if len(q.eqFilts) > 0 { 486 » » » allowedEqs := 0
480 » » » » return fmt.Errorf("kindless queries not have any equality filters") 487 » » » if hasAncestor {
488 » » » » allowedEqs = 1
489 » » » }
490 » » » if len(q.eqFilts) > allowedEqs {
491 » » » » return fmt.Errorf("kindless queries may not have any equality filters")
481 } 492 }
482 for _, o := range q.order { 493 for _, o := range q.order {
483 if o.Property != "__key__" || o.Descending { 494 if o.Property != "__key__" || o.Descending {
484 return fmt.Errorf("invalid order for kin dless query: %#v", o) 495 return fmt.Errorf("invalid order for kin dless query: %#v", o)
485 } 496 }
486 } 497 }
487 } 498 }
488 499
489 if q.keysOnly && q.project != nil && q.project.Len() > 0 { 500 if q.keysOnly && q.project != nil && q.project.Len() > 0 {
490 return errors.New("cannot project a keysOnly query") 501 return errors.New("cannot project a keysOnly query")
491 } 502 }
492 503
493 if q.ineqFiltProp != "" { 504 if q.ineqFiltProp != "" {
494 if len(q.order) > 0 && q.order[0].Property != q.ineqFilt Prop { 505 if len(q.order) > 0 && q.order[0].Property != q.ineqFilt Prop {
495 return fmt.Errorf( 506 return fmt.Errorf(
496 "first sort order must match inequality filter: %q v %q", 507 "first sort order must match inequality filter: %q v %q",
497 q.order[0].Property, q.ineqFiltProp) 508 q.order[0].Property, q.ineqFiltProp)
498 } 509 }
499 if q.ineqFiltLowSet && q.ineqFiltHighSet { 510 if q.ineqFiltLowSet && q.ineqFiltHighSet {
500 if q.ineqFiltHigh.Less(&q.ineqFiltLow) && 511 if q.ineqFiltHigh.Less(&q.ineqFiltLow) &&
501 (q.ineqFiltHigh.Equal(&q.ineqFiltLow) && 512 (q.ineqFiltHigh.Equal(&q.ineqFiltLow) &&
502 (!q.ineqFiltLowIncl || !q.ineqFi ltHighIncl)) { 513 (!q.ineqFiltLowIncl || !q.ineqFi ltHighIncl)) {
503 return ErrNullQuery 514 return ErrNullQuery
504 } 515 }
505 } 516 }
517 if q.ineqFiltProp == "__key__" {
518 if q.ineqFiltLowSet {
519 if q.ineqFiltLow.Type() != PTKey {
520 return fmt.Errorf(
521 "inequality filters on _ _key__ must use *ds.Key values")
522 }
523 if hasAncestor && !q.ineqFiltLow.Value() .(*Key).HasAncestor(ancestor) {
524 return fmt.Errorf(
525 "inequality filters on _ _key__ must be descendants of the __ancestor__")
526 }
527 }
528 if q.ineqFiltHighSet {
529 if q.ineqFiltHigh.Type() != PTKey {
530 return fmt.Errorf(
531 "inequality filters on _ _key__ must use *ds.Key values")
532 }
533 if hasAncestor && !q.ineqFiltHigh.Value( ).(*Key).HasAncestor(ancestor) {
534 return fmt.Errorf(
535 "inequality filters on _ _key__ must be descendants of the __ancestor__")
536 }
537 }
538 }
506 } 539 }
507 540
508 err := error(nil) 541 err := error(nil)
509 if q.project != nil { 542 if q.project != nil {
510 q.project.Iter(func(p string) bool { 543 q.project.Iter(func(p string) bool {
511 if _, iseq := q.eqFilts[p]; iseq { 544 if _, iseq := q.eqFilts[p]; iseq {
512 err = fmt.Errorf("cannot project on equa lity filter field: %s", p) 545 err = fmt.Errorf("cannot project on equa lity filter field: %s", p)
513 return false 546 return false
514 } 547 }
515 return true 548 return true
516 }) 549 })
517 } 550 }
518 return err 551 return err
519 }() 552 }()
520 if err != nil { 553 if err != nil {
521 q.err = err 554 q.err = err
522 return nil, err 555 return nil, err
523 } 556 }
524 557
525 ret := &FinalizedQuery{ 558 ret := &FinalizedQuery{
526 original: q, 559 original: q,
527 kind: q.kind, 560 kind: q.kind,
528 561
529 keysOnly: q.keysOnly, 562 keysOnly: q.keysOnly,
530 » » eventuallyConsistent: q.eventualConsistency || q.eqFilts["__ance stor__"] == nil, 563 » » eventuallyConsistent: q.eventualConsistency || !hasAncestor,
531 limit: q.limit, 564 limit: q.limit,
532 offset: q.offset, 565 offset: q.offset,
533 start: q.start, 566 start: q.start,
534 end: q.end, 567 end: q.end,
535 568
536 eqFilts: q.eqFilts, 569 eqFilts: q.eqFilts,
537 570
538 ineqFiltProp: q.ineqFiltProp, 571 ineqFiltProp: q.ineqFiltProp,
539 ineqFiltLow: q.ineqFiltLow, 572 ineqFiltLow: q.ineqFiltLow,
540 ineqFiltLowIncl: q.ineqFiltLowIncl, 573 ineqFiltLowIncl: q.ineqFiltLowIncl,
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 if q.keysOnly { 733 if q.keysOnly {
701 p("KeysOnly") 734 p("KeysOnly")
702 } 735 }
703 736
704 if _, err := ret.WriteRune(')'); err != nil { 737 if _, err := ret.WriteRune(')'); err != nil {
705 panic(err) 738 panic(err)
706 } 739 }
707 740
708 return ret.String() 741 return ret.String()
709 } 742 }
OLDNEW
« service/datastore/key.go ('K') | « service/datastore/key.go ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698