Fix NPE in BinaryRangeFieldRangeQuery when field does not exist or is of wrong type (#11950)

This commit is contained in:
Greg Miller 2022-11-25 11:38:41 -08:00 committed by GitHub
parent 4e93f29318
commit 2e83c3b40f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 3 deletions

View File

@ -160,6 +160,9 @@ Bug Fixes
* GITHUB#11954: Remove QueryTimeout#isTimeoutEnabled method and move check to caller. (Shubham Chaudhary)
* GITHUB#11950: Fix NPE in BinaryRangeFieldRangeQuery variants when the queried field doesn't exist
in a segment or is of the wrong type. (Greg Miller)
Optimizations
---------------------
* GITHUB#11738: Optimize MultiTermQueryConstantScoreWrapper when a term is present that matches all

View File

@ -29,6 +29,7 @@ class BinaryRangeDocValues extends BinaryDocValues {
private int docID = -1;
BinaryRangeDocValues(BinaryDocValues in, int numDims, int numBytesPerDimension) {
assert in != null;
this.in = in;
this.numBytesPerDimension = numBytesPerDimension;
this.numDims = numDims;

View File

@ -20,7 +20,6 @@ package org.apache.lucene.document;
import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;
import org.apache.lucene.index.BinaryDocValues;
import org.apache.lucene.index.DocValues;
import org.apache.lucene.index.LeafReader;
import org.apache.lucene.index.LeafReaderContext;
@ -91,9 +90,15 @@ abstract class BinaryRangeFieldRangeQuery extends Query {
}
private BinaryRangeDocValues getValues(LeafReader reader, String field) throws IOException {
BinaryDocValues binaryDocValues = reader.getBinaryDocValues(field);
if (reader.getFieldInfos().fieldInfo(field) == null) {
// Returning null when the field doesn't exist in the segment allows us to return a null
// Scorer, which is
// just a bit more efficient:
return null;
}
return new BinaryRangeDocValues(binaryDocValues, numDims, numBytesPerDimension);
return new BinaryRangeDocValues(
DocValues.getBinary(reader, field), numDims, numBytesPerDimension);
}
@Override

View File

@ -20,9 +20,11 @@ package org.apache.lucene.search;
import java.io.IOException;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.DoubleRangeDocValuesField;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.FloatRangeDocValuesField;
import org.apache.lucene.document.IntRangeDocValuesField;
import org.apache.lucene.document.LongRangeDocValuesField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.store.Directory;
import org.apache.lucene.tests.index.RandomIndexWriter;
@ -226,4 +228,30 @@ public class TestRangeFieldsDocValuesQuery extends LuceneTestCase {
Query q4 = LongRangeDocValuesField.newSlowIntersectsQuery("foo", longMin, longMax);
assertEquals("foo:[[101, 124, 137] TO [138, 145, 156]]", q4.toString());
}
public void testNoData() throws IOException {
Directory dir = newDirectory();
RandomIndexWriter iw = new RandomIndexWriter(random(), dir);
Document doc = new Document();
doc.add(new StringField("foo", "abc", Store.NO));
iw.addDocument(doc);
final IndexReader reader = iw.getReader();
final IndexSearcher searcher = newSearcher(reader);
iw.close();
// test on field that doesn't exist
Query q1 =
LongRangeDocValuesField.newSlowIntersectsQuery("bar", new long[] {20}, new long[] {27});
TopDocs r = searcher.search(q1, 10);
assertEquals(0, r.totalHits.value);
// test on field of wrong type
Query q2 =
LongRangeDocValuesField.newSlowIntersectsQuery("foo", new long[] {20}, new long[] {27});
expectThrows(IllegalStateException.class, () -> searcher.search(q2, 10));
reader.close();
dir.close();
}
}