From 1a94c25a04b1de80f8ae6e9c35f60ff97e9ec190 Mon Sep 17 00:00:00 2001 From: Nicholas Knize Date: Fri, 22 Jul 2016 10:59:48 -0500 Subject: [PATCH] LUCENE-7381: Fix equals relation in RangeFieldQuery. Fix relation logic in BaseRangeFieldQueryTestCase. --- .../lucene/document/RangeFieldQuery.java | 16 ++++++----- .../search/BaseRangeFieldQueryTestCase.java | 28 +++++++++++++++++-- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/RangeFieldQuery.java b/lucene/sandbox/src/java/org/apache/lucene/document/RangeFieldQuery.java index 8f9ca6ddd1d..bb2e7e0e48a 100644 --- a/lucene/sandbox/src/java/org/apache/lucene/document/RangeFieldQuery.java +++ b/lucene/sandbox/src/java/org/apache/lucene/document/RangeFieldQuery.java @@ -124,8 +124,9 @@ abstract class RangeFieldQuery extends Query { @Override public void visit(int docID, byte[] leaf) throws IOException { // add the document iff: - if (// target is within cell and queryType is INTERSECTS or CONTAINS: - (comparator.isWithin(leaf) && queryType != QueryType.WITHIN) + if (Arrays.equals(ranges, leaf) + // target is within cell and queryType is INTERSECTS or CONTAINS: + || (comparator.isWithin(leaf) && queryType != QueryType.WITHIN) // target contains cell and queryType is INTERSECTS or WITHIN: || (comparator.contains(leaf) && queryType != QueryType.CONTAINS) // target is not disjoint (crosses) and queryType is INTERSECTS @@ -139,12 +140,12 @@ abstract class RangeFieldQuery extends Query { // compute range relation for BKD traversal if (comparator.isDisjoint(node)) { return Relation.CELL_OUTSIDE_QUERY; - } else if (comparator.contains(node)) { - // target contains cell; add iff queryType is not a CONTAINS query: - return (queryType == QueryType.CONTAINS) ? Relation.CELL_OUTSIDE_QUERY : Relation.CELL_INSIDE_QUERY; } else if (comparator.isWithin(node)) { // target within cell; continue traversing: return Relation.CELL_CROSSES_QUERY; + } else if (comparator.contains(node)) { + // target contains cell; add iff queryType is not a CONTAINS query: + return (queryType == QueryType.CONTAINS) ? Relation.CELL_OUTSIDE_QUERY : Relation.CELL_INSIDE_QUERY; } // target intersects cell; continue traversing: return Relation.CELL_CROSSES_QUERY; @@ -170,8 +171,9 @@ abstract class RangeFieldQuery extends Query { if (values.getDocCount(field) == reader.maxDoc()) { // if query crosses, docs need to be further scrutinized byte[] range = getInternalRange(values.getMinPackedValue(field), values.getMaxPackedValue(field)); - // if the internal node is not contained by the query, all docs do not match - if (((comparator.contains(range) && queryType == QueryType.CONTAINS)) == false) { + // if the internal node is not equal and not contained by the query, all docs do not match + if ((!Arrays.equals(ranges, range) + && (comparator.contains(range) && queryType != QueryType.CONTAINS)) == false) { allDocsMatch = false; } } else { diff --git a/lucene/sandbox/src/test/org/apache/lucene/search/BaseRangeFieldQueryTestCase.java b/lucene/sandbox/src/test/org/apache/lucene/search/BaseRangeFieldQueryTestCase.java index dadb5886340..d9cb830c120 100644 --- a/lucene/sandbox/src/test/org/apache/lucene/search/BaseRangeFieldQueryTestCase.java +++ b/lucene/sandbox/src/test/org/apache/lucene/search/BaseRangeFieldQueryTestCase.java @@ -17,6 +17,7 @@ package org.apache.lucene.search; import java.io.IOException; +import java.util.Arrays; import java.util.HashSet; import java.util.Set; @@ -262,10 +263,11 @@ public abstract class BaseRangeFieldQueryTestCase extends LuceneTestCase { if (hits.get(docID) != expected) { StringBuilder b = new StringBuilder(); + b.append("FAIL (iter " + iter + "): "); if (expected == true) { - b.append("FAILS: id=" + id + (boxes[id].length > 1 ? " (MultiValue) " : " ") + "should match but did not\n"); + b.append("id=" + id + (boxes[id].length > 1 ? " (MultiValue) " : " ") + "should match but did not\n"); } else { - b.append("FAIL: id=" + id + " should not match but did\n"); + b.append("id=" + id + " should not match but did\n"); } b.append(" queryBox=" + queryBox + "\n"); b.append(" box" + ((boxes[id].length > 1) ? "es=" : "=" ) + boxes[id][0]); @@ -292,6 +294,9 @@ public abstract class BaseRangeFieldQueryTestCase extends LuceneTestCase { } protected boolean expectedBBoxQueryResult(Box queryBox, Box box, Box.QueryType queryType) { + if (box.equals(queryBox)) { + return true; + } Box.QueryType relation = box.relate(queryBox); if (queryType == Box.QueryType.INTERSECTS) { return relation != null; @@ -345,6 +350,25 @@ public abstract class BaseRangeFieldQueryTestCase extends LuceneTestCase { } } + @Override + public boolean equals(Object o) { + return o != null + && getClass() == o.getClass() + && equalTo(getClass().cast(o)); + } + + private boolean equalTo(Box o) { + return Arrays.equals(min, o.min) + && Arrays.equals(max, o.max); + } + + @Override + public int hashCode() { + int result = Arrays.hashCode(min); + result = 31 * result + Arrays.hashCode(max); + return result; + } + QueryType relate(Box other) { // check disjoint for (int d=0; d