diff --git a/lucene/core/src/java/org/apache/lucene/search/FieldCacheImpl.java b/lucene/core/src/java/org/apache/lucene/search/FieldCacheImpl.java index b5bcc5f92f9..01227a84f0f 100644 --- a/lucene/core/src/java/org/apache/lucene/search/FieldCacheImpl.java +++ b/lucene/core/src/java/org/apache/lucene/search/FieldCacheImpl.java @@ -372,6 +372,10 @@ class FieldCacheImpl implements FieldCache { } }; } else { + final FieldInfo info = reader.getFieldInfos().fieldInfo(field); + if (info != null && info.hasDocValues()) { + throw new IllegalStateException("Type mismatch: " + field + " was indexed as " + info.getDocValuesType()); + } return (Bytes) caches.get(Byte.TYPE).get(reader, new CacheKey(field, parser), setDocsWithField); } } @@ -458,6 +462,10 @@ class FieldCacheImpl implements FieldCache { } }; } else { + final FieldInfo info = reader.getFieldInfos().fieldInfo(field); + if (info != null && info.hasDocValues()) { + throw new IllegalStateException("Type mismatch: " + field + " was indexed as " + info.getDocValuesType()); + } return (Shorts) caches.get(Short.TYPE).get(reader, new CacheKey(field, parser), setDocsWithField); } } @@ -542,6 +550,10 @@ class FieldCacheImpl implements FieldCache { } }; } else { + final FieldInfo info = reader.getFieldInfos().fieldInfo(field); + if (info != null && info.hasDocValues()) { + throw new IllegalStateException("Type mismatch: " + field + " was indexed as " + info.getDocValuesType()); + } return (Ints) caches.get(Integer.TYPE).get(reader, new CacheKey(field, parser), setDocsWithField); } } @@ -728,6 +740,10 @@ class FieldCacheImpl implements FieldCache { } }; } else { + final FieldInfo info = reader.getFieldInfos().fieldInfo(field); + if (info != null && info.hasDocValues()) { + throw new IllegalStateException("Type mismatch: " + field + " was indexed as " + info.getDocValuesType()); + } return (Floats) caches.get(Float.TYPE).get(reader, new CacheKey(field, parser), setDocsWithField); } } @@ -831,6 +847,10 @@ class FieldCacheImpl implements FieldCache { } }; } else { + final FieldInfo info = reader.getFieldInfos().fieldInfo(field); + if (info != null && info.hasDocValues()) { + throw new IllegalStateException("Type mismatch: " + field + " was indexed as " + info.getDocValuesType()); + } return (Longs) caches.get(Long.TYPE).get(reader, new CacheKey(field, parser), setDocsWithField); } } @@ -934,6 +954,10 @@ class FieldCacheImpl implements FieldCache { } }; } else { + final FieldInfo info = reader.getFieldInfos().fieldInfo(field); + if (info != null && info.hasDocValues()) { + throw new IllegalStateException("Type mismatch: " + field + " was indexed as " + info.getDocValuesType()); + } return (Doubles) caches.get(Double.TYPE).get(reader, new CacheKey(field, parser), setDocsWithField); } } @@ -1064,9 +1088,12 @@ class FieldCacheImpl implements FieldCache { return valuesIn; } else { final FieldInfo info = reader.getFieldInfos().fieldInfo(field); - if (info != null && !info.isIndexed() && info.hasDocValues()) { + if (info != null && info.hasDocValues()) { // we don't try to build a sorted instance from numeric/binary doc // values because dedup can be very costly + throw new IllegalStateException("Type mismatch: " + field + " was indexed as " + info.getDocValuesType()); + } + if (info != null && !info.isIndexed()) { throw new IllegalArgumentException("Cannot get terms index for \"" + field + "\": it isn't indexed and doesn't have sorted doc values"); } @@ -1220,6 +1247,11 @@ class FieldCacheImpl implements FieldCache { return valuesIn; } + final FieldInfo info = reader.getFieldInfos().fieldInfo(field); + if (info != null && info.hasDocValues()) { + throw new IllegalStateException("Type mismatch: " + field + " was indexed as " + info.getDocValuesType()); + } + return (BinaryDocValues) caches.get(BinaryDocValues.class).get(reader, new CacheKey(field, acceptableOverheadRatio), false); } diff --git a/lucene/core/src/test/org/apache/lucene/search/TestFieldCache.java b/lucene/core/src/test/org/apache/lucene/search/TestFieldCache.java index 9325efdbc6e..61966569c02 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestFieldCache.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestFieldCache.java @@ -29,11 +29,15 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import org.apache.lucene.analysis.MockAnalyzer; +import org.apache.lucene.document.BinaryDocValuesField; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.IntField; +import org.apache.lucene.document.NumericDocValuesField; +import org.apache.lucene.document.SortedDocValuesField; import org.apache.lucene.document.StringField; import org.apache.lucene.index.*; +import org.apache.lucene.search.FieldCache.Ints; import org.apache.lucene.store.Directory; import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; @@ -431,4 +435,76 @@ public class TestFieldCache extends LuceneTestCase { } assertFalse(failed.get()); } + + public void testDocValuesIntegration() throws Exception { + Directory dir = newDirectory(); + RandomIndexWriter iw = new RandomIndexWriter(random(), dir); + Document doc = new Document(); + doc.add(new BinaryDocValuesField("binary", new BytesRef("binary value"))); + doc.add(new SortedDocValuesField("sorted", new BytesRef("sorted value"))); + doc.add(new NumericDocValuesField("numeric", 42)); + iw.addDocument(doc); + DirectoryReader ir = iw.getReader(); + iw.close(); + AtomicReader ar = getOnlySegmentReader(ir); + + BytesRef scratch = new BytesRef(); + + // Binary type: can be retrieved via getTerms() + try { + FieldCache.DEFAULT.getInts(ar, "binary", false); + fail(); + } catch (IllegalStateException expected) {} + + BinaryDocValues binary = FieldCache.DEFAULT.getTerms(ar, "binary"); + binary.get(0, scratch); + assertEquals("binary value", scratch.utf8ToString()); + + try { + FieldCache.DEFAULT.getTermsIndex(ar, "binary"); + fail(); + } catch (IllegalStateException expected) {} + + Bits bits = FieldCache.DEFAULT.getDocsWithField(ar, "binary"); + assertTrue(bits instanceof Bits.MatchAllBits); + + // Sorted type: can be retrieved via getTerms() or getTermsIndex() + try { + FieldCache.DEFAULT.getInts(ar, "sorted", false); + fail(); + } catch (IllegalStateException expected) {} + + binary = FieldCache.DEFAULT.getTerms(ar, "sorted"); + binary.get(0, scratch); + assertEquals("sorted value", scratch.utf8ToString()); + + SortedDocValues sorted = FieldCache.DEFAULT.getTermsIndex(ar, "sorted"); + assertEquals(0, sorted.getOrd(0)); + assertEquals(1, sorted.getValueCount()); + sorted.get(0, scratch); + assertEquals("sorted value", scratch.utf8ToString()); + + bits = FieldCache.DEFAULT.getDocsWithField(ar, "sorted"); + assertTrue(bits instanceof Bits.MatchAllBits); + + // Numeric type: can be retrieved via getInts() and so on + Ints numeric = FieldCache.DEFAULT.getInts(ar, "numeric", false); + assertEquals(42, numeric.get(0)); + + try { + FieldCache.DEFAULT.getTerms(ar, "numeric"); + fail(); + } catch (IllegalStateException expected) {} + + try { + FieldCache.DEFAULT.getTermsIndex(ar, "numeric"); + fail(); + } catch (IllegalStateException expected) {} + + bits = FieldCache.DEFAULT.getDocsWithField(ar, "numeric"); + assertTrue(bits instanceof Bits.MatchAllBits); + + ir.close(); + dir.close(); + } }