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

Side by Side Diff: impl/memory/datastore_index_selection.go

Issue 1380613002: Fix bugs in impl/memory queries. (Closed) Base URL: https://github.com/luci/gae.git@add_appid
Patch Set: 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
« no previous file with comments | « no previous file | impl/memory/datastore_query_execution.go » ('j') | 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 memory 5 package memory
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "fmt" 9 "fmt"
10 "sort" 10 "sort"
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 for i, sb := range sortBy[numEqFilts:] { 161 for i, sb := range sortBy[numEqFilts:] {
162 if q.suffixFormat[i] != sb { 162 if q.suffixFormat[i] != sb {
163 return false 163 return false
164 } 164 }
165 } 165 }
166 166
167 if id.Builtin() && numEqFilts == 0 { 167 if id.Builtin() && numEqFilts == 0 {
168 if len(q.eqFilters) > 1 || (len(q.eqFilters) == 1 && q.eqFilters ["__ancestor__"] == nil) { 168 if len(q.eqFilters) > 1 || (len(q.eqFilters) == 1 && q.eqFilters ["__ancestor__"] == nil) {
169 return false 169 return false
170 } 170 }
171 if len(sortBy) > 1 && q.eqFilters["__ancestor__"] != nil {
172 return false
173 }
171 } 174 }
172 175
173 // Make sure the equalities section doesn't contain any properties we do n't 176 // Make sure the equalities section doesn't contain any properties we do n't
174 // want in our query. 177 // want in our query.
175 // 178 //
176 // numByProp && totalEqFilts will be used to see if this is a perfect ma tch 179 // numByProp && totalEqFilts will be used to see if this is a perfect ma tch
177 // later. 180 // later.
178 numByProp := make(map[string]int, len(q.eqFilters)) 181 numByProp := make(map[string]int, len(q.eqFilters))
179 totalEqFilts := 0 182 totalEqFilts := 0
180 183
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 // anything which is a descendant or an exact match. Removing t he last byte 371 // anything which is a descendant or an exact match. Removing t he last byte
369 // from the key (the terminating null) allows this trick to work . Otherwise 372 // from the key (the terminating null) allows this trick to work . Otherwise
370 // it would be a closed range of EXACTLY this key. 373 // it would be a closed range of EXACTLY this key.
371 chopped := []byte(anc[:len(anc)-1]) 374 chopped := []byte(anc[:len(anc)-1])
372 if q.suffixFormat[0].Descending { 375 if q.suffixFormat[0].Descending {
373 chopped = serialize.Invert(chopped) 376 chopped = serialize.Invert(chopped)
374 } 377 }
375 def.prefix = serialize.Join(def.prefix, chopped) 378 def.prefix = serialize.Join(def.prefix, chopped)
376 379
377 // Update start and end, since we know that if they contain anyt hing, they 380 // Update start and end, since we know that if they contain anyt hing, they
378 » » // contain values for the __key__ field. 381 » » // contain values for the __key__ field. This is necessary becau se bytes
382 » » // are shifting from the suffix to the prefix, and start/end sho uld only
383 » » // contain suffix (variable) bytes.
379 if def.start != nil { 384 if def.start != nil {
380 » » » offset := 0 385 » » » if !bytes.HasPrefix(def.start, chopped) {
381 » » » if len(q.suffixFormat) > 1 {
382 » » » » chunks, _ := parseSuffix(q.aid, q.ns, q.suffixFo rmat, def.start, 1)
383 » » » » offset = len(chunks[0])
384 » » » }
385 » » » if !bytes.HasPrefix(def.start[offset:], chopped) {
386 // again, shouldn't happen, but if it does, we w ant to know about it. 386 // again, shouldn't happen, but if it does, we w ant to know about it.
387 impossible(fmt.Errorf( 387 impossible(fmt.Errorf(
388 "start suffix for implied ancestor doesn 't start with ancestor! start:%v ancestor:%v", 388 "start suffix for implied ancestor doesn 't start with ancestor! start:%v ancestor:%v",
389 def.start, chopped)) 389 def.start, chopped))
390 } 390 }
391 » » » def.start = def.start[:offset+len(chopped)] 391 » » » def.start = def.start[len(chopped):]
392 } 392 }
393 if def.end != nil { 393 if def.end != nil {
394 » » » offset := 0 394 » » » if !bytes.HasPrefix(def.end, chopped) {
395 » » » if len(q.suffixFormat) > 1 {
396 » » » » chunks, _ := parseSuffix(q.aid, q.ns, q.suffixFo rmat, def.end, 1)
397 » » » » offset = len(chunks[0])
398 » » » }
399 » » » if !bytes.HasPrefix(def.end[offset:], chopped) {
400 impossible(fmt.Errorf( 395 impossible(fmt.Errorf(
401 "end suffix for implied ancestor doesn't start with ancestor! end:%v ancestor:%v", 396 "end suffix for implied ancestor doesn't start with ancestor! end:%v ancestor:%v",
402 def.end, chopped)) 397 def.end, chopped))
403 } 398 }
404 » » » def.end = def.end[:offset+len(chopped)] 399 » » » def.end = def.end[len(chopped):]
405 } 400 }
406 } 401 }
407 402
408 return def 403 return def
409 } 404 }
410 405
411 type constraints struct { 406 type constraints struct {
412 constraints map[string][][]byte 407 constraints map[string][][]byte
413 original map[string][][]byte 408 original map[string][][]byte
414 residualMapping map[string]int 409 residualMapping map[string]int
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 if bestIdx == nil { 542 if bestIdx == nil {
548 // something is really wrong here... if relevantIdxs is !nil, then we 543 // something is really wrong here... if relevantIdxs is !nil, then we
549 // should always be able to make progress in this loop. 544 // should always be able to make progress in this loop.
550 impossible(fmt.Errorf("deadlock: cannot fulfil query?")) 545 impossible(fmt.Errorf("deadlock: cannot fulfil query?"))
551 } 546 }
552 ret = append(ret, generate(q, bestIdx, constraints)) 547 ret = append(ret, generate(q, bestIdx, constraints))
553 } 548 }
554 549
555 return ret, nil 550 return ret, nil
556 } 551 }
OLDNEW
« no previous file with comments | « no previous file | impl/memory/datastore_query_execution.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698