diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 82f278627f4..e2d711cf4a7 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -484,6 +484,10 @@ Bug Fixes high frequency terms in extremely large indices (Robert Muir, Mike McCandless) +* LUCENE-6093: Don't throw NullPointerException from + BlendedInfixSuggester for lookups that do not end in a prefix + token. (jane chang via Mike McCandless) + Documentation * LUCENE-5392: Add/improve analysis package documentation to reflect diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingInfixSuggester.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingInfixSuggester.java index ea732ab4be4..b38d54d7a4f 100644 --- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingInfixSuggester.java +++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingInfixSuggester.java @@ -576,7 +576,11 @@ public class AnalyzingInfixSuggester extends Lookup implements Closeable { /** * Create the results based on the search hits. - * Can be overridden by subclass to add particular behavior (e.g. weight transformation) + * Can be overridden by subclass to add particular behavior (e.g. weight transformation). + * Note that there is no prefix toke (the {@code prefixToken} argument will + * be null) whenever the final token in the incoming request was in fact finished + * (had trailing characters, such as white-space). + * * @throws IOException If there are problems reading fields from the underlying Lucene index. */ protected List createResults(IndexSearcher searcher, TopFieldDocs hits, int num, diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/BlendedInfixSuggester.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/BlendedInfixSuggester.java index 7c05665d935..e49a88691eb 100644 --- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/BlendedInfixSuggester.java +++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/BlendedInfixSuggester.java @@ -261,8 +261,8 @@ public class BlendedInfixSuggester extends AnalyzingInfixSuggester { String docTerm = term.utf8ToString(); - if (matchedTokens.contains(docTerm) || docTerm.startsWith(prefixToken)) { - + if (matchedTokens.contains(docTerm) || (prefixToken != null && docTerm.startsWith(prefixToken))) { + DocsAndPositionsEnum docPosEnum = it.docsAndPositions(null, null, DocsAndPositionsEnum.FLAG_OFFSETS); docPosEnum.nextDoc(); diff --git a/lucene/suggest/src/test/org/apache/lucene/search/suggest/analyzing/BlendedInfixSuggesterTest.java b/lucene/suggest/src/test/org/apache/lucene/search/suggest/analyzing/BlendedInfixSuggesterTest.java index 9fd393a19aa..cb22d36a8ac 100644 --- a/lucene/suggest/src/test/org/apache/lucene/search/suggest/analyzing/BlendedInfixSuggesterTest.java +++ b/lucene/suggest/src/test/org/apache/lucene/search/suggest/analyzing/BlendedInfixSuggesterTest.java @@ -165,6 +165,33 @@ public class BlendedInfixSuggesterTest extends LuceneTestCase { suggester.close(); } + /** + * Handle trailing spaces that result in no prefix token LUCENE-6093 + */ + public void testNullPrefixToken() throws IOException { + + BytesRef payload = new BytesRef("lake"); + + Input keys[] = new Input[]{ + new Input("top of the lake", 8, payload) + }; + + Path tempDir = createTempDir("BlendedInfixSuggesterTest"); + + Analyzer a = new StandardAnalyzer(CharArraySet.EMPTY_SET); + BlendedInfixSuggester suggester = new BlendedInfixSuggester(newFSDirectory(tempDir), a, a, + AnalyzingInfixSuggester.DEFAULT_MIN_PREFIX_CHARS, + BlendedInfixSuggester.BlenderType.POSITION_LINEAR, + BlendedInfixSuggester.DEFAULT_NUM_FACTOR, false); + suggester.build(new InputArrayIterator(keys)); + + getInResults(suggester, "of ", payload, 1); + getInResults(suggester, "the ", payload, 1); + getInResults(suggester, "lake ", payload, 1); + + suggester.close(); + } + public void /*testT*/rying() throws IOException { BytesRef lake = new BytesRef("lake");