Test for errors in .Contains() and .NextPath()

This commit is contained in:
Andrew Dunham 2015-04-15 15:28:46 -07:00
parent 7de923d40a
commit 430ff507f0
8 changed files with 71 additions and 11 deletions

View file

@ -190,8 +190,13 @@ func (it *And) checkContainsList(val graph.Value, lastResult graph.Value) bool {
for i, c := range it.checkList { for i, c := range it.checkList {
ok = c.Contains(val) ok = c.Contains(val)
if !ok { if !ok {
if err := c.Err(); err != nil {
it.err = err
return false
}
if lastResult != nil { if lastResult != nil {
for j := 0; j < i; j++ { for j := 0; j < i; j++ {
// TODO(andrew-d): Should this result actually be used?
it.checkList[j].Contains(lastResult) it.checkList[j].Contains(lastResult)
} }
} }
@ -249,10 +254,18 @@ func (it *And) NextPath() bool {
if it.primaryIt.NextPath() { if it.primaryIt.NextPath() {
return true return true
} }
if err := it.primaryIt.Err(); err != nil {
it.err = err
return false
}
for _, sub := range it.internalIterators { for _, sub := range it.internalIterators {
if sub.NextPath() { if sub.NextPath() {
return true return true
} }
if err := sub.Err(); err != nil {
it.err = err
return false
}
} }
return false return false
} }

View file

@ -193,11 +193,16 @@ func (it *HasA) NextPath() bool {
if it.primaryIt.NextPath() { if it.primaryIt.NextPath() {
return true return true
} }
result := it.NextContains() if err := it.primaryIt.Err(); err != nil {
glog.V(4).Infoln("HASA", it.UID(), "NextPath Returns", result, "") it.err = err
return false
}
result := it.NextContains() // Sets it.err if there's an error
if it.err != nil { if it.err != nil {
return false return false
} }
glog.V(4).Infoln("HASA", it.UID(), "NextPath Returns", result, "")
return result return result
} }

View file

@ -126,6 +126,9 @@ func (it *LinksTo) Contains(val graph.Value) bool {
it.result = val it.result = val
return graph.ContainsLogOut(it, val, true) return graph.ContainsLogOut(it, val, true)
} }
if err := it.primaryIt.Err(); err != nil {
it.err = err
}
return graph.ContainsLogOut(it, val, false) return graph.ContainsLogOut(it, val, false)
} }
@ -213,7 +216,11 @@ func (it *LinksTo) Close() error {
// We won't ever have a new result, but our subiterators might. // We won't ever have a new result, but our subiterators might.
func (it *LinksTo) NextPath() bool { func (it *LinksTo) NextPath() bool {
return it.primaryIt.NextPath() ret := it.primaryIt.NextPath()
if !ret {
it.err = it.primaryIt.Err()
}
return ret
} }
// Register the LinksTo. // Register the LinksTo.

View file

@ -230,6 +230,9 @@ func (it *Materialize) Contains(v graph.Value) bool {
if !it.hasRun { if !it.hasRun {
it.materializeSet() it.materializeSet()
} }
if it.err != nil {
return false
}
if it.aborted { if it.aborted {
return it.subIt.Contains(v) return it.subIt.Contains(v)
} }
@ -249,6 +252,9 @@ func (it *Materialize) NextPath() bool {
if !it.hasRun { if !it.hasRun {
it.materializeSet() it.materializeSet()
} }
if it.err != nil {
return false
}
if it.aborted { if it.aborted {
return it.subIt.NextPath() return it.subIt.NextPath()
} }

View file

@ -113,6 +113,13 @@ func (it *Not) Contains(val graph.Value) bool {
return graph.ContainsLogOut(it, val, false) return graph.ContainsLogOut(it, val, false)
} }
if err := it.primaryIt.Err(); err != nil {
it.err = err
// Explicitly return 'false', since an error occurred.
return false
}
it.result = val it.result = val
return graph.ContainsLogOut(it, val, true) return graph.ContainsLogOut(it, val, true)
} }

View file

@ -38,6 +38,7 @@ type Optional struct {
subIt graph.Iterator subIt graph.Iterator
lastCheck bool lastCheck bool
result graph.Value result graph.Value
err error
} }
// Creates a new optional iterator. // Creates a new optional iterator.
@ -77,7 +78,7 @@ func (it *Optional) ResultTree() *graph.ResultTree {
} }
func (it *Optional) Err() error { func (it *Optional) Err() error {
return it.subIt.Err() return it.err
} }
func (it *Optional) Result() graph.Value { func (it *Optional) Result() graph.Value {
@ -89,7 +90,11 @@ func (it *Optional) Result() graph.Value {
// optional subbranch. // optional subbranch.
func (it *Optional) NextPath() bool { func (it *Optional) NextPath() bool {
if it.lastCheck { if it.lastCheck {
return it.subIt.NextPath() ret := it.subIt.NextPath()
if !ret {
it.err = it.subIt.Err()
}
return ret
} }
return false return false
} }
@ -105,6 +110,7 @@ func (it *Optional) SubIterators() []graph.Iterator {
func (it *Optional) Contains(val graph.Value) bool { func (it *Optional) Contains(val graph.Value) bool {
checked := it.subIt.Contains(val) checked := it.subIt.Contains(val)
it.lastCheck = checked it.lastCheck = checked
it.err = it.subIt.Err()
it.result = val it.result = val
return true return true
} }

View file

@ -174,7 +174,7 @@ func (it *Or) Result() graph.Value {
} }
// Checks a value against the iterators, in order. // Checks a value against the iterators, in order.
func (it *Or) subItsContain(val graph.Value) bool { func (it *Or) subItsContain(val graph.Value) (bool, error) {
var subIsGood = false var subIsGood = false
for i, sub := range it.internalIterators { for i, sub := range it.internalIterators {
subIsGood = sub.Contains(val) subIsGood = sub.Contains(val)
@ -182,15 +182,21 @@ func (it *Or) subItsContain(val graph.Value) bool {
it.currentIterator = i it.currentIterator = i
break break
} }
if err := sub.Err(); err != nil {
return false, err
}
} }
return subIsGood return subIsGood, nil
} }
// Check a value against the entire graph.iterator, in order. // Check a value against the entire graph.iterator, in order.
func (it *Or) Contains(val graph.Value) bool { func (it *Or) Contains(val graph.Value) bool {
graph.ContainsLogIn(it, val) graph.ContainsLogIn(it, val)
anyGood := it.subItsContain(val) anyGood, err := it.subItsContain(val)
if !anyGood { if err != nil {
it.err = err
return false
} else if !anyGood {
return graph.ContainsLogOut(it, val, false) return graph.ContainsLogOut(it, val, false)
} }
it.result = val it.result = val
@ -231,7 +237,12 @@ func (it *Or) Size() (int64, bool) {
// shortcircuiting, only allow new results from the currently checked graph.iterator // shortcircuiting, only allow new results from the currently checked graph.iterator
func (it *Or) NextPath() bool { func (it *Or) NextPath() bool {
if it.currentIterator != -1 { if it.currentIterator != -1 {
return it.internalIterators[it.currentIterator].NextPath() currIt := it.internalIterators[it.currentIterator]
ret := currIt.NextPath()
if !ret {
it.err = currIt.Err()
}
return ret
} }
return false return false
} }

View file

@ -155,6 +155,7 @@ func (it *Comparison) NextPath() bool {
for { for {
hasNext := it.subIt.NextPath() hasNext := it.subIt.NextPath()
if !hasNext { if !hasNext {
it.err = it.subIt.Err()
return false return false
} }
if it.doComparison(it.subIt.Result()) { if it.doComparison(it.subIt.Result()) {
@ -174,7 +175,11 @@ func (it *Comparison) Contains(val graph.Value) bool {
if !it.doComparison(val) { if !it.doComparison(val) {
return false return false
} }
return it.subIt.Contains(val) ret := it.subIt.Contains(val)
if !ret {
it.err = it.subIt.Err()
}
return ret
} }
// If we failed the check, then the subiterator should not contribute to the result // If we failed the check, then the subiterator should not contribute to the result