mirror of https://github.com/apache/lucene.git
LUCENE-10087: Validate number of dimensions and bytes per dimension for numeric SortFields. (#283)
This commit is contained in:
parent
bc161e6dcc
commit
7eb35be045
|
@ -19,6 +19,10 @@ package org.apache.lucene.search;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import org.apache.lucene.document.DoublePoint;
|
||||||
|
import org.apache.lucene.document.FloatPoint;
|
||||||
|
import org.apache.lucene.document.IntPoint;
|
||||||
|
import org.apache.lucene.document.LongPoint;
|
||||||
import org.apache.lucene.index.DocValues;
|
import org.apache.lucene.index.DocValues;
|
||||||
import org.apache.lucene.index.IndexSorter;
|
import org.apache.lucene.index.IndexSorter;
|
||||||
import org.apache.lucene.index.SortFieldProvider;
|
import org.apache.lucene.index.SortFieldProvider;
|
||||||
|
@ -68,25 +72,25 @@ public class SortField {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort using term values as encoded Integers. Sort values are Integer and lower values are at
|
* Sort using term values as encoded Integers. Sort values are Integer and lower values are at
|
||||||
* the front.
|
* the front. Fields must either be not indexed, or indexed with {@link IntPoint}.
|
||||||
*/
|
*/
|
||||||
INT,
|
INT,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort using term values as encoded Floats. Sort values are Float and lower values are at the
|
* Sort using term values as encoded Floats. Sort values are Float and lower values are at the
|
||||||
* front.
|
* front. Fields must either be not indexed, or indexed with {@link FloatPoint}.
|
||||||
*/
|
*/
|
||||||
FLOAT,
|
FLOAT,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort using term values as encoded Longs. Sort values are Long and lower values are at the
|
* Sort using term values as encoded Longs. Sort values are Long and lower values are at the
|
||||||
* front.
|
* front. Fields must either be not indexed, or indexed with {@link LongPoint}.
|
||||||
*/
|
*/
|
||||||
LONG,
|
LONG,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort using term values as encoded Doubles. Sort values are Double and lower values are at the
|
* Sort using term values as encoded Doubles. Sort values are Double and lower values are at the
|
||||||
* front.
|
* front. Fields must either be not indexed, or indexed with {@link DoublePoint}.
|
||||||
*/
|
*/
|
||||||
DOUBLE,
|
DOUBLE,
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.lucene.search.comparators;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import org.apache.lucene.index.DocValues;
|
import org.apache.lucene.index.DocValues;
|
||||||
|
import org.apache.lucene.index.FieldInfo;
|
||||||
import org.apache.lucene.index.LeafReaderContext;
|
import org.apache.lucene.index.LeafReaderContext;
|
||||||
import org.apache.lucene.index.NumericDocValues;
|
import org.apache.lucene.index.NumericDocValues;
|
||||||
import org.apache.lucene.index.PointValues;
|
import org.apache.lucene.index.PointValues;
|
||||||
|
@ -90,6 +91,26 @@ public abstract class NumericComparator<T extends Number> extends FieldComparato
|
||||||
this.docValues = getNumericDocValues(context, field);
|
this.docValues = getNumericDocValues(context, field);
|
||||||
this.pointValues = canSkipDocuments ? context.reader().getPointValues(field) : null;
|
this.pointValues = canSkipDocuments ? context.reader().getPointValues(field) : null;
|
||||||
if (pointValues != null) {
|
if (pointValues != null) {
|
||||||
|
FieldInfo info = context.reader().getFieldInfos().fieldInfo(field);
|
||||||
|
if (info == null || info.getPointDimensionCount() == 0) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Field "
|
||||||
|
+ field
|
||||||
|
+ " doesn't index points according to FieldInfos yet returns non-null PointValues");
|
||||||
|
} else if (info.getPointDimensionCount() > 1) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Field " + field + " is indexed with multiple dimensions, sorting is not supported");
|
||||||
|
} else if (info.getPointNumBytes() != bytesCount) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Field "
|
||||||
|
+ field
|
||||||
|
+ " is indexed with "
|
||||||
|
+ info.getPointNumBytes()
|
||||||
|
+ " bytes per dimension, but "
|
||||||
|
+ NumericComparator.this
|
||||||
|
+ " expected "
|
||||||
|
+ bytesCount);
|
||||||
|
}
|
||||||
this.enableSkipping = true; // skipping is enabled when points are available
|
this.enableSkipping = true; // skipping is enabled when points are available
|
||||||
this.maxDoc = context.reader().maxDoc();
|
this.maxDoc = context.reader().maxDoc();
|
||||||
this.maxValueAsBytes =
|
this.maxValueAsBytes =
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FloatDocValuesField;
|
import org.apache.lucene.document.FloatDocValuesField;
|
||||||
import org.apache.lucene.document.FloatPoint;
|
import org.apache.lucene.document.FloatPoint;
|
||||||
import org.apache.lucene.document.IntPoint;
|
import org.apache.lucene.document.IntPoint;
|
||||||
|
import org.apache.lucene.document.IntRange;
|
||||||
import org.apache.lucene.document.LongPoint;
|
import org.apache.lucene.document.LongPoint;
|
||||||
import org.apache.lucene.document.NumericDocValuesField;
|
import org.apache.lucene.document.NumericDocValuesField;
|
||||||
import org.apache.lucene.document.StoredField;
|
import org.apache.lucene.document.StoredField;
|
||||||
|
@ -33,6 +34,7 @@ import org.apache.lucene.index.DirectoryReader;
|
||||||
import org.apache.lucene.index.IndexReader;
|
import org.apache.lucene.index.IndexReader;
|
||||||
import org.apache.lucene.index.IndexWriter;
|
import org.apache.lucene.index.IndexWriter;
|
||||||
import org.apache.lucene.index.IndexWriterConfig;
|
import org.apache.lucene.index.IndexWriterConfig;
|
||||||
|
import org.apache.lucene.index.RandomIndexWriter;
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
import org.apache.lucene.store.Directory;
|
import org.apache.lucene.store.Directory;
|
||||||
import org.apache.lucene.util.LuceneTestCase;
|
import org.apache.lucene.util.LuceneTestCase;
|
||||||
|
@ -583,4 +585,49 @@ public class TestSortOptimization extends LuceneTestCase {
|
||||||
reader.close();
|
reader.close();
|
||||||
dir.close();
|
dir.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testPointValidation() throws IOException {
|
||||||
|
final Directory dir = newDirectory();
|
||||||
|
final RandomIndexWriter writer = new RandomIndexWriter(random(), dir);
|
||||||
|
Document doc = new Document();
|
||||||
|
|
||||||
|
doc.add(new IntPoint("intField", 4));
|
||||||
|
doc.add(new NumericDocValuesField("intField", 4));
|
||||||
|
|
||||||
|
doc.add(new LongPoint("longField", 42));
|
||||||
|
doc.add(new NumericDocValuesField("longField", 42));
|
||||||
|
|
||||||
|
doc.add(new IntRange("intRange", new int[] {1}, new int[] {10}));
|
||||||
|
doc.add(new NumericDocValuesField("intRange", 4));
|
||||||
|
|
||||||
|
writer.addDocument(doc);
|
||||||
|
IndexReader reader = writer.getReader();
|
||||||
|
writer.close();
|
||||||
|
|
||||||
|
IndexSearcher searcher = newSearcher(reader);
|
||||||
|
assertThrows(
|
||||||
|
IllegalArgumentException.class,
|
||||||
|
() ->
|
||||||
|
searcher.search(
|
||||||
|
new MatchAllDocsQuery(),
|
||||||
|
1,
|
||||||
|
new Sort(new SortField("intField", SortField.Type.LONG))));
|
||||||
|
assertThrows(
|
||||||
|
IllegalArgumentException.class,
|
||||||
|
() ->
|
||||||
|
searcher.search(
|
||||||
|
new MatchAllDocsQuery(),
|
||||||
|
1,
|
||||||
|
new Sort(new SortField("longField", SortField.Type.INT))));
|
||||||
|
assertThrows(
|
||||||
|
IllegalArgumentException.class,
|
||||||
|
() ->
|
||||||
|
searcher.search(
|
||||||
|
new MatchAllDocsQuery(),
|
||||||
|
1,
|
||||||
|
new Sort(new SortField("intRange", SortField.Type.INT))));
|
||||||
|
|
||||||
|
reader.close();
|
||||||
|
dir.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue