mirror of https://github.com/apache/lucene.git
LUCENE-5450: fix getField() NPE issues with span queries that have empty clauses
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1569503 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e04cf308ea
commit
2991d657e4
|
@ -65,6 +65,14 @@ Optimizations
|
||||||
on Windows if NIOFSDirectory is used, mmapped files are still locked.
|
on Windows if NIOFSDirectory is used, mmapped files are still locked.
|
||||||
(Michael Poindexter, Robert Muir, Uwe Schindler)
|
(Michael Poindexter, Robert Muir, Uwe Schindler)
|
||||||
|
|
||||||
|
======================= Lucene 4.8.0 =======================
|
||||||
|
|
||||||
|
Bug fixes
|
||||||
|
|
||||||
|
* LUCENE-5450: Fix getField() NPE issues with SpanOr/SpanNear when they have an
|
||||||
|
empty list of clauses. This can happen for example, when a wildcard matches
|
||||||
|
no terms. (Tim Allison via Robert Muir)
|
||||||
|
|
||||||
======================= Lucene 4.7.0 =======================
|
======================= Lucene 4.7.0 =======================
|
||||||
|
|
||||||
New Features
|
New Features
|
||||||
|
|
|
@ -64,9 +64,9 @@ public class SpanNearQuery extends SpanQuery implements Cloneable {
|
||||||
this.clauses = new ArrayList<SpanQuery>(clauses.length);
|
this.clauses = new ArrayList<SpanQuery>(clauses.length);
|
||||||
for (int i = 0; i < clauses.length; i++) {
|
for (int i = 0; i < clauses.length; i++) {
|
||||||
SpanQuery clause = clauses[i];
|
SpanQuery clause = clauses[i];
|
||||||
if (i == 0) { // check field
|
if (field == null) { // check field
|
||||||
field = clause.getField();
|
field = clause.getField();
|
||||||
} else if (!clause.getField().equals(field)) {
|
} else if (clause.getField() != null && !clause.getField().equals(field)) {
|
||||||
throw new IllegalArgumentException("Clauses must have same field.");
|
throw new IllegalArgumentException("Clauses must have same field.");
|
||||||
}
|
}
|
||||||
this.clauses.add(clause);
|
this.clauses.add(clause);
|
||||||
|
|
|
@ -62,7 +62,7 @@ public class SpanNotQuery extends SpanQuery implements Cloneable {
|
||||||
this.pre = (pre >=0) ? pre : 0;
|
this.pre = (pre >=0) ? pre : 0;
|
||||||
this.post = (post >= 0) ? post : 0;
|
this.post = (post >= 0) ? post : 0;
|
||||||
|
|
||||||
if (!include.getField().equals(exclude.getField()))
|
if (include.getField() != null && exclude.getField() != null && !include.getField().equals(exclude.getField()))
|
||||||
throw new IllegalArgumentException("Clauses must have same field.");
|
throw new IllegalArgumentException("Clauses must have same field.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class SpanOrQuery extends SpanQuery implements Cloneable {
|
||||||
public final void addClause(SpanQuery clause) {
|
public final void addClause(SpanQuery clause) {
|
||||||
if (field == null) {
|
if (field == null) {
|
||||||
field = clause.getField();
|
field = clause.getField();
|
||||||
} else if (!clause.getField().equals(field)) {
|
} else if (clause.getField() != null && !clause.getField().equals(field)) {
|
||||||
throw new IllegalArgumentException("Clauses must have same field.");
|
throw new IllegalArgumentException("Clauses must have same field.");
|
||||||
}
|
}
|
||||||
this.clauses.add(clause);
|
this.clauses.add(clause);
|
||||||
|
@ -132,7 +132,6 @@ public class SpanOrQuery extends SpanQuery implements Cloneable {
|
||||||
final SpanOrQuery that = (SpanOrQuery) o;
|
final SpanOrQuery that = (SpanOrQuery) o;
|
||||||
|
|
||||||
if (!clauses.equals(that.clauses)) return false;
|
if (!clauses.equals(that.clauses)) return false;
|
||||||
if (!clauses.isEmpty() && !field.equals(that.field)) return false;
|
|
||||||
|
|
||||||
return getBoost() == that.getBoost();
|
return getBoost() == that.getBoost();
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,11 @@ public abstract class SpanQuery extends Query {
|
||||||
* to search for spans. */
|
* to search for spans. */
|
||||||
public abstract Spans getSpans(AtomicReaderContext context, Bits acceptDocs, Map<Term,TermContext> termContexts) throws IOException;
|
public abstract Spans getSpans(AtomicReaderContext context, Bits acceptDocs, Map<Term,TermContext> termContexts) throws IOException;
|
||||||
|
|
||||||
/** Returns the name of the field matched by this query.*/
|
/**
|
||||||
|
* Returns the name of the field matched by this query.
|
||||||
|
* <p>
|
||||||
|
* Note that this may return null if the query matches no terms.
|
||||||
|
*/
|
||||||
public abstract String getField();
|
public abstract String getField();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -24,6 +24,8 @@ import org.apache.lucene.index.RandomIndexWriter;
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
import org.apache.lucene.search.FuzzyQuery;
|
import org.apache.lucene.search.FuzzyQuery;
|
||||||
import org.apache.lucene.search.IndexSearcher;
|
import org.apache.lucene.search.IndexSearcher;
|
||||||
|
import org.apache.lucene.search.PrefixQuery;
|
||||||
|
import org.apache.lucene.search.RegexpQuery;
|
||||||
import org.apache.lucene.search.WildcardQuery;
|
import org.apache.lucene.search.WildcardQuery;
|
||||||
import org.apache.lucene.store.Directory;
|
import org.apache.lucene.store.Directory;
|
||||||
import org.apache.lucene.util.LuceneTestCase;
|
import org.apache.lucene.util.LuceneTestCase;
|
||||||
|
@ -95,4 +97,133 @@ public class TestSpanMultiTermQueryWrapper extends LuceneTestCase {
|
||||||
SpanPositionRangeQuery sprq = new SpanPositionRangeQuery(sfq, 0, 100);
|
SpanPositionRangeQuery sprq = new SpanPositionRangeQuery(sfq, 0, 100);
|
||||||
assertEquals(1, searcher.search(sprq, 10).totalHits);
|
assertEquals(1, searcher.search(sprq, 10).totalHits);
|
||||||
}
|
}
|
||||||
|
public void testNoSuchMultiTermsInNear() throws Exception {
|
||||||
|
//test to make sure non existent multiterms aren't throwing null pointer exceptions
|
||||||
|
FuzzyQuery fuzzyNoSuch = new FuzzyQuery(new Term("field", "noSuch"), 1, 0, 1, false);
|
||||||
|
SpanQuery spanNoSuch = new SpanMultiTermQueryWrapper<FuzzyQuery>(fuzzyNoSuch);
|
||||||
|
SpanQuery term = new SpanTermQuery(new Term("field", "brown"));
|
||||||
|
SpanQuery near = new SpanNearQuery(new SpanQuery[]{term, spanNoSuch}, 1, true);
|
||||||
|
assertEquals(0, searcher.search(near, 10).totalHits);
|
||||||
|
//flip order
|
||||||
|
near = new SpanNearQuery(new SpanQuery[]{spanNoSuch, term}, 1, true);
|
||||||
|
assertEquals(0, searcher.search(near, 10).totalHits);
|
||||||
|
|
||||||
|
WildcardQuery wcNoSuch = new WildcardQuery(new Term("field", "noSuch*"));
|
||||||
|
SpanQuery spanWCNoSuch = new SpanMultiTermQueryWrapper<WildcardQuery>(wcNoSuch);
|
||||||
|
near = new SpanNearQuery(new SpanQuery[]{term, spanWCNoSuch}, 1, true);
|
||||||
|
assertEquals(0, searcher.search(near, 10).totalHits);
|
||||||
|
|
||||||
|
RegexpQuery rgxNoSuch = new RegexpQuery(new Term("field", "noSuch"));
|
||||||
|
SpanQuery spanRgxNoSuch = new SpanMultiTermQueryWrapper<RegexpQuery>(rgxNoSuch);
|
||||||
|
near = new SpanNearQuery(new SpanQuery[]{term, spanRgxNoSuch}, 1, true);
|
||||||
|
assertEquals(0, searcher.search(near, 10).totalHits);
|
||||||
|
|
||||||
|
PrefixQuery prfxNoSuch = new PrefixQuery(new Term("field", "noSuch"));
|
||||||
|
SpanQuery spanPrfxNoSuch = new SpanMultiTermQueryWrapper<PrefixQuery>(prfxNoSuch);
|
||||||
|
near = new SpanNearQuery(new SpanQuery[]{term, spanPrfxNoSuch}, 1, true);
|
||||||
|
assertEquals(0, searcher.search(near, 10).totalHits);
|
||||||
|
|
||||||
|
//test single noSuch
|
||||||
|
near = new SpanNearQuery(new SpanQuery[]{spanPrfxNoSuch}, 1, true);
|
||||||
|
assertEquals(0, searcher.search(near, 10).totalHits);
|
||||||
|
|
||||||
|
//test double noSuch
|
||||||
|
near = new SpanNearQuery(new SpanQuery[]{spanPrfxNoSuch, spanPrfxNoSuch}, 1, true);
|
||||||
|
assertEquals(0, searcher.search(near, 10).totalHits);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNoSuchMultiTermsInNotNear() throws Exception {
|
||||||
|
//test to make sure non existent multiterms aren't throwing non-matching field exceptions
|
||||||
|
FuzzyQuery fuzzyNoSuch = new FuzzyQuery(new Term("field", "noSuch"), 1, 0, 1, false);
|
||||||
|
SpanQuery spanNoSuch = new SpanMultiTermQueryWrapper<FuzzyQuery>(fuzzyNoSuch);
|
||||||
|
SpanQuery term = new SpanTermQuery(new Term("field", "brown"));
|
||||||
|
SpanNotQuery notNear = new SpanNotQuery(term, spanNoSuch, 0,0);
|
||||||
|
assertEquals(1, searcher.search(notNear, 10).totalHits);
|
||||||
|
|
||||||
|
//flip
|
||||||
|
notNear = new SpanNotQuery(spanNoSuch, term, 0,0);
|
||||||
|
assertEquals(0, searcher.search(notNear, 10).totalHits);
|
||||||
|
|
||||||
|
//both noSuch
|
||||||
|
notNear = new SpanNotQuery(spanNoSuch, spanNoSuch, 0,0);
|
||||||
|
assertEquals(0, searcher.search(notNear, 10).totalHits);
|
||||||
|
|
||||||
|
WildcardQuery wcNoSuch = new WildcardQuery(new Term("field", "noSuch*"));
|
||||||
|
SpanQuery spanWCNoSuch = new SpanMultiTermQueryWrapper<WildcardQuery>(wcNoSuch);
|
||||||
|
notNear = new SpanNotQuery(term, spanWCNoSuch, 0,0);
|
||||||
|
assertEquals(1, searcher.search(notNear, 10).totalHits);
|
||||||
|
|
||||||
|
RegexpQuery rgxNoSuch = new RegexpQuery(new Term("field", "noSuch"));
|
||||||
|
SpanQuery spanRgxNoSuch = new SpanMultiTermQueryWrapper<RegexpQuery>(rgxNoSuch);
|
||||||
|
notNear = new SpanNotQuery(term, spanRgxNoSuch, 1, 1);
|
||||||
|
assertEquals(1, searcher.search(notNear, 10).totalHits);
|
||||||
|
|
||||||
|
PrefixQuery prfxNoSuch = new PrefixQuery(new Term("field", "noSuch"));
|
||||||
|
SpanQuery spanPrfxNoSuch = new SpanMultiTermQueryWrapper<PrefixQuery>(prfxNoSuch);
|
||||||
|
notNear = new SpanNotQuery(term, spanPrfxNoSuch, 1, 1);
|
||||||
|
assertEquals(1, searcher.search(notNear, 10).totalHits);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNoSuchMultiTermsInOr() throws Exception {
|
||||||
|
//test to make sure non existent multiterms aren't throwing null pointer exceptions
|
||||||
|
FuzzyQuery fuzzyNoSuch = new FuzzyQuery(new Term("field", "noSuch"), 1, 0, 1, false);
|
||||||
|
SpanQuery spanNoSuch = new SpanMultiTermQueryWrapper<FuzzyQuery>(fuzzyNoSuch);
|
||||||
|
SpanQuery term = new SpanTermQuery(new Term("field", "brown"));
|
||||||
|
SpanOrQuery near = new SpanOrQuery(new SpanQuery[]{term, spanNoSuch});
|
||||||
|
assertEquals(1, searcher.search(near, 10).totalHits);
|
||||||
|
|
||||||
|
//flip
|
||||||
|
near = new SpanOrQuery(new SpanQuery[]{spanNoSuch, term});
|
||||||
|
assertEquals(1, searcher.search(near, 10).totalHits);
|
||||||
|
|
||||||
|
|
||||||
|
WildcardQuery wcNoSuch = new WildcardQuery(new Term("field", "noSuch*"));
|
||||||
|
SpanQuery spanWCNoSuch = new SpanMultiTermQueryWrapper<WildcardQuery>(wcNoSuch);
|
||||||
|
near = new SpanOrQuery(new SpanQuery[]{term, spanWCNoSuch});
|
||||||
|
assertEquals(1, searcher.search(near, 10).totalHits);
|
||||||
|
|
||||||
|
RegexpQuery rgxNoSuch = new RegexpQuery(new Term("field", "noSuch"));
|
||||||
|
SpanQuery spanRgxNoSuch = new SpanMultiTermQueryWrapper<RegexpQuery>(rgxNoSuch);
|
||||||
|
near = new SpanOrQuery(new SpanQuery[]{term, spanRgxNoSuch});
|
||||||
|
assertEquals(1, searcher.search(near, 10).totalHits);
|
||||||
|
|
||||||
|
PrefixQuery prfxNoSuch = new PrefixQuery(new Term("field", "noSuch"));
|
||||||
|
SpanQuery spanPrfxNoSuch = new SpanMultiTermQueryWrapper<PrefixQuery>(prfxNoSuch);
|
||||||
|
near = new SpanOrQuery(new SpanQuery[]{term, spanPrfxNoSuch});
|
||||||
|
assertEquals(1, searcher.search(near, 10).totalHits);
|
||||||
|
|
||||||
|
near = new SpanOrQuery(new SpanQuery[]{spanPrfxNoSuch});
|
||||||
|
assertEquals(0, searcher.search(near, 10).totalHits);
|
||||||
|
|
||||||
|
near = new SpanOrQuery(new SpanQuery[]{spanPrfxNoSuch, spanPrfxNoSuch});
|
||||||
|
assertEquals(0, searcher.search(near, 10).totalHits);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testNoSuchMultiTermsInSpanFirst() throws Exception {
|
||||||
|
//this hasn't been a problem
|
||||||
|
FuzzyQuery fuzzyNoSuch = new FuzzyQuery(new Term("field", "noSuch"), 1, 0, 1, false);
|
||||||
|
SpanQuery spanNoSuch = new SpanMultiTermQueryWrapper<FuzzyQuery>(fuzzyNoSuch);
|
||||||
|
SpanQuery spanFirst = new SpanFirstQuery(spanNoSuch, 10);
|
||||||
|
|
||||||
|
assertEquals(0, searcher.search(spanFirst, 10).totalHits);
|
||||||
|
|
||||||
|
WildcardQuery wcNoSuch = new WildcardQuery(new Term("field", "noSuch*"));
|
||||||
|
SpanQuery spanWCNoSuch = new SpanMultiTermQueryWrapper<WildcardQuery>(wcNoSuch);
|
||||||
|
spanFirst = new SpanFirstQuery(spanWCNoSuch, 10);
|
||||||
|
assertEquals(0, searcher.search(spanFirst, 10).totalHits);
|
||||||
|
|
||||||
|
RegexpQuery rgxNoSuch = new RegexpQuery(new Term("field", "noSuch"));
|
||||||
|
SpanQuery spanRgxNoSuch = new SpanMultiTermQueryWrapper<RegexpQuery>(rgxNoSuch);
|
||||||
|
spanFirst = new SpanFirstQuery(spanRgxNoSuch, 10);
|
||||||
|
assertEquals(0, searcher.search(spanFirst, 10).totalHits);
|
||||||
|
|
||||||
|
PrefixQuery prfxNoSuch = new PrefixQuery(new Term("field", "noSuch"));
|
||||||
|
SpanQuery spanPrfxNoSuch = new SpanMultiTermQueryWrapper<PrefixQuery>(prfxNoSuch);
|
||||||
|
spanFirst = new SpanFirstQuery(spanPrfxNoSuch, 10);
|
||||||
|
assertEquals(0, searcher.search(spanFirst, 10).totalHits);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue