diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 263555d02ab1..0fe4de95595f 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -1001,6 +1001,8 @@ Bug Fixes * GITHUB#13799: Disable intra-merge parallelism for all structures but kNN vectors. (Ben Trent) +* GITHUB##14732: Fix IndexSortSortedNumericDocValuesRangeQuery for int sort (Mayya Sharipova) + Build --------------------- diff --git a/lucene/core/src/java/org/apache/lucene/search/IndexSortSortedNumericDocValuesRangeQuery.java b/lucene/core/src/java/org/apache/lucene/search/IndexSortSortedNumericDocValuesRangeQuery.java index 1d862958c2a6..176a15067180 100644 --- a/lucene/core/src/java/org/apache/lucene/search/IndexSortSortedNumericDocValuesRangeQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/IndexSortSortedNumericDocValuesRangeQuery.java @@ -213,7 +213,8 @@ public int count(LeafReaderContext context) throws IOException { // The index sort optimization is only supported for Type.INT and Type.LONG if (sortFieldType == Type.INT || sortFieldType == Type.LONG) { Object missingValue = sortField.getMissingValue(); - final long missingLongValue = missingValue == null ? 0L : (long) missingValue; + final long missingLongValue = + missingValue == null ? 0L : ((Number) missingValue).longValue(); // all documents have docValues or missing value falls outside the range if ((pointValues != null && pointValues.getDocCount() == reader.maxDoc()) || (missingLongValue < lowerValue || missingLongValue > upperValue)) { @@ -612,7 +613,7 @@ private IteratorAndCount getDocIdSetIterator( Object missingValue = sortField.getMissingValue(); LeafReader reader = context.reader(); PointValues pointValues = reader.getPointValues(field); - final long missingLongValue = missingValue == null ? 0L : (long) missingValue; + final long missingLongValue = missingValue == null ? 0L : ((Number) missingValue).longValue(); // all documents have docValues or missing value falls outside the range if ((pointValues != null && pointValues.getDocCount() == reader.maxDoc()) || (missingLongValue < lowerValue || missingLongValue > upperValue)) { diff --git a/lucene/core/src/test/org/apache/lucene/search/TestIndexSortSortedNumericDocValuesRangeQuery.java b/lucene/core/src/test/org/apache/lucene/search/TestIndexSortSortedNumericDocValuesRangeQuery.java index a807a88c8ec0..631f35abbe28 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestIndexSortSortedNumericDocValuesRangeQuery.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestIndexSortSortedNumericDocValuesRangeQuery.java @@ -22,6 +22,7 @@ import java.util.Random; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.IntPoint; import org.apache.lucene.document.LongPoint; import org.apache.lucene.document.SortedNumericDocValuesField; import org.apache.lucene.document.StringField; @@ -94,6 +95,59 @@ public void testSameHitsAsPointRangeQuery() throws IOException { } } + public void testSameHitsAsPointRangeQueryIntSort() throws IOException { + final int iters = atLeast(10); + for (int iter = 0; iter < iters; ++iter) { + Directory dir = newDirectory(); + + IndexWriterConfig iwc = new IndexWriterConfig(new MockAnalyzer(random())); + boolean reverse = random().nextBoolean(); + SortField sortField = new SortedNumericSortField("dv", SortField.Type.INT, reverse); + boolean enableMissingValue = random().nextBoolean(); + if (enableMissingValue) { + int missingValue = + random().nextBoolean() + ? TestUtil.nextInt(random(), -100, 10000) + : (random().nextBoolean() ? Integer.MIN_VALUE : Integer.MAX_VALUE); + sortField.setMissingValue(missingValue); + } + iwc.setIndexSort(new Sort(sortField)); + + RandomIndexWriter iw = new RandomIndexWriter(random(), dir, iwc); + + final int numDocs = atLeast(100); + for (int i = 0; i < numDocs; ++i) { + Document doc = new Document(); + final int numValues = TestUtil.nextInt(random(), 0, 1); + for (int j = 0; j < numValues; ++j) { + final int value = TestUtil.nextInt(random(), -100, 10000); + doc.add(new SortedNumericDocValuesField("dv", value)); + doc.add(new IntPoint("idx", value)); + } + iw.addDocument(doc); + } + if (random().nextBoolean()) { + iw.deleteDocuments(IntPoint.newRangeQuery("idx", 0, 10)); + } + final IndexReader reader = iw.getReader(); + final IndexSearcher searcher = newSearcher(reader); + iw.close(); + + for (int i = 0; i < 100; ++i) { + final int min = + random().nextBoolean() ? Integer.MIN_VALUE : TestUtil.nextInt(random(), -100, 10000); + final int max = + random().nextBoolean() ? Integer.MAX_VALUE : TestUtil.nextInt(random(), -100, 10000); + final Query q1 = IntPoint.newRangeQuery("idx", min, max); + final Query q2 = createQuery("dv", min, max); + assertSameHits(searcher, q1, q2, false); + } + + reader.close(); + dir.close(); + } + } + private static void assertSameHits(IndexSearcher searcher, Query q1, Query q2, boolean scores) throws IOException { final int maxDoc = searcher.getIndexReader().maxDoc();