From ce8eaf138c43bad3b81a8cc0a8e580a7d78aa01a Mon Sep 17 00:00:00 2001 From: Adrien Grand Date: Tue, 24 Jan 2023 10:51:49 +0000 Subject: [PATCH] MemoryIndex should not fail integer fields that enable doc values. (#12109) When a field indexes numeric doc values, `MemoryIndex` does an unchecked cast to `java.lang.Long`. However, the new `IntField` represents the value as a `java.lang.Integer` so this cast fails. This commit aligns `MemoryIndex` with `IndexingChain` by casting to `Number` and calling `Number#longValue` instead of casting to `Long`. --- .../lucene/index/memory/MemoryIndex.java | 5 +- .../lucene/index/memory/TestMemoryIndex.java | 47 +++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java b/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java index b43440083c7..58d948c807c 100644 --- a/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java +++ b/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java @@ -596,7 +596,7 @@ public class MemoryIndex { + fieldName + "]"); } - info.numericProducer.dvLongValues = new long[] {(long) docValuesValue}; + info.numericProducer.dvLongValues = new long[] {((Number) docValuesValue).longValue()}; info.numericProducer.count++; break; case SORTED_NUMERIC: @@ -605,7 +605,8 @@ public class MemoryIndex { } info.numericProducer.dvLongValues = ArrayUtil.grow(info.numericProducer.dvLongValues, info.numericProducer.count + 1); - info.numericProducer.dvLongValues[info.numericProducer.count++] = (long) docValuesValue; + info.numericProducer.dvLongValues[info.numericProducer.count++] = + ((Number) docValuesValue).longValue(); break; case BINARY: case SORTED: diff --git a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java index 2d719bc763e..8ac20164103 100644 --- a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java +++ b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java @@ -39,6 +39,7 @@ import org.apache.lucene.document.DoublePoint; import org.apache.lucene.document.Field; import org.apache.lucene.document.FieldType; import org.apache.lucene.document.FloatPoint; +import org.apache.lucene.document.IntField; import org.apache.lucene.document.IntPoint; import org.apache.lucene.document.LongPoint; import org.apache.lucene.document.NumericDocValuesField; @@ -793,4 +794,50 @@ public class TestMemoryIndex extends LuceneTestCase { } return false; } + + public void testIntegerNumericDocValue() throws IOException { + // MemoryIndex used to fail when doc values are enabled and numericValue() returns an Integer + // such as with IntField. + FieldType ft = new FieldType(); + ft.setDocValuesType(DocValuesType.NUMERIC); + ft.freeze(); + Field field = + new Field("field", ft) { + { + fieldsData = 35; + } + }; + + FieldType multiFt = new FieldType(); + multiFt.setDocValuesType(DocValuesType.SORTED_NUMERIC); + multiFt.freeze(); + Field multiField = + new Field("multi_field", multiFt) { + { + fieldsData = 42; + } + }; + + Field intField = new IntField("int_field", 50); + + MemoryIndex index = MemoryIndex.fromDocument(Arrays.asList(field, multiField, intField), null); + IndexSearcher searcher = index.createSearcher(); + + NumericDocValues ndv = + searcher.getIndexReader().leaves().get(0).reader().getNumericDocValues("field"); + assertTrue(ndv.advanceExact(0)); + assertEquals(35, ndv.longValue()); + + SortedNumericDocValues sndv = + searcher.getIndexReader().leaves().get(0).reader().getSortedNumericDocValues("multi_field"); + assertTrue(sndv.advanceExact(0)); + assertEquals(1, sndv.docValueCount()); + assertEquals(42, sndv.nextValue()); + + sndv = + searcher.getIndexReader().leaves().get(0).reader().getSortedNumericDocValues("int_field"); + assertTrue(sndv.advanceExact(0)); + assertEquals(1, sndv.docValueCount()); + assertEquals(50, sndv.nextValue()); + } }