From db01548109792eab06ee0875dda67b2b6a8ea92f Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Sat, 4 Jul 2015 10:14:27 +0000 Subject: [PATCH] LUCENE-6657: don't throw NPE when a given segment never saw all terms used in the TAQ git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1689133 13f79535-47bb-0310-9956-ffa450edef68 --- .../lucene/search/TermAutomatonQuery.java | 10 ++-- .../lucene/search/TestTermAutomatonQuery.java | 47 +++++++++++++++++++ 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/TermAutomatonQuery.java b/lucene/sandbox/src/java/org/apache/lucene/search/TermAutomatonQuery.java index f1631bdf9f5..2a172d9af36 100644 --- a/lucene/sandbox/src/java/org/apache/lucene/search/TermAutomatonQuery.java +++ b/lucene/sandbox/src/java/org/apache/lucene/search/TermAutomatonQuery.java @@ -34,7 +34,6 @@ import org.apache.lucene.index.TermState; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.search.similarities.Similarity; import org.apache.lucene.search.spans.SpanNearQuery; -import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.automaton.Automaton; import org.apache.lucene.util.automaton.Operations; @@ -386,20 +385,25 @@ public class TermAutomatonQuery extends Query { // Initialize the enums; null for a given slot means that term didn't appear in this reader EnumAndScorer[] enums = new EnumAndScorer[idToTerm.size()]; + boolean any = false; for(Map.Entry ent : termStates.entrySet()) { TermContext termContext = ent.getValue(); assert termContext.topReaderContext == ReaderUtil.getTopLevelContext(context) : "The top-reader used to create Weight (" + termContext.topReaderContext + ") is not the same as the current reader's top-reader (" + ReaderUtil.getTopLevelContext(context); BytesRef term = idToTerm.get(ent.getKey()); TermState state = termContext.get(context.ord); if (state != null) { - TermsEnum termsEnum = context.reader().terms(field).iterator(); termsEnum.seekExact(term, state); enums[ent.getKey()] = new EnumAndScorer(ent.getKey(), termsEnum.postings(null, PostingsEnum.POSITIONS)); + any = true; } } - return new TermAutomatonScorer(this, enums, anyTermID, idToTerm, similarity.simScorer(stats, context)); + if (any) { + return new TermAutomatonScorer(this, enums, anyTermID, idToTerm, similarity.simScorer(stats, context)); + } else { + return null; + } } @Override diff --git a/lucene/sandbox/src/test/org/apache/lucene/search/TestTermAutomatonQuery.java b/lucene/sandbox/src/test/org/apache/lucene/search/TestTermAutomatonQuery.java index 564a5393a53..cf4561e01c6 100644 --- a/lucene/sandbox/src/test/org/apache/lucene/search/TestTermAutomatonQuery.java +++ b/lucene/sandbox/src/test/org/apache/lucene/search/TestTermAutomatonQuery.java @@ -738,4 +738,51 @@ public class TestTermAutomatonQuery extends LuceneTestCase { r.close(); dir.close(); } + + public void testTermDoesNotExist() throws Exception { + Directory dir = newDirectory(); + RandomIndexWriter w = new RandomIndexWriter(random(), dir); + Document doc = new Document(); + doc.add(newTextField("field", "x y z", Field.Store.NO)); + w.addDocument(doc); + + IndexReader r = w.getReader(); + IndexSearcher s = newSearcher(r); + + TokenStream ts = new CannedTokenStream(new Token[] { + token("a", 1, 1), + }); + + TermAutomatonQuery q = new TokenStreamToTermAutomatonQuery().toQuery("field", ts); + // System.out.println("DOT: " + q.toDot()); + assertEquals(0, s.search(q, 1).totalHits); + + w.close(); + r.close(); + dir.close(); + } + + public void testOneTermDoesNotExist() throws Exception { + Directory dir = newDirectory(); + RandomIndexWriter w = new RandomIndexWriter(random(), dir); + Document doc = new Document(); + doc.add(newTextField("field", "x y z", Field.Store.NO)); + w.addDocument(doc); + + IndexReader r = w.getReader(); + IndexSearcher s = newSearcher(r); + + TokenStream ts = new CannedTokenStream(new Token[] { + token("a", 1, 1), + token("x", 1, 1), + }); + + TermAutomatonQuery q = new TokenStreamToTermAutomatonQuery().toQuery("field", ts); + // System.out.println("DOT: " + q.toDot()); + assertEquals(0, s.search(q, 1).totalHits); + + w.close(); + r.close(); + dir.close(); + } }