From ee55158d07cb1ad3e7db049711900218f496ee01 Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Tue, 20 Nov 2012 19:00:38 +0000 Subject: [PATCH] LUCENE-4567: avoid NPE if no suggestions were built git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1411796 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 4 ++++ .../search/suggest/analyzing/AnalyzingSuggester.java | 8 ++++++++ .../search/suggest/fst/WFSTCompletionLookup.java | 7 +++++++ .../suggest/analyzing/AnalyzingSuggesterTest.java | 9 +++++++++ .../search/suggest/analyzing/FuzzySuggesterTest.java | 10 ++++++++-- .../lucene/search/suggest/fst/WFSTCompletionTest.java | 8 ++++++++ 6 files changed, 44 insertions(+), 2 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 97af442b27a..76267f8b5ae 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -147,6 +147,10 @@ Bug Fixes allow 1+maxMergeCount merges threads to be created, instead of just maxMergeCount (Radim Kolar, Mike McCandless) +* LUCENE-4567: Fixed NullPointerException in analzying, fuzzy, and + WFST suggesters when no suggestions were added (selckin via Mike + McCandless) + Optimizations * LUCENE-2221: oal.util.BitUtil was modified to use Long.bitCount and diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingSuggester.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingSuggester.java index 1647571728c..5b96f0d61fc 100644 --- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingSuggester.java +++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingSuggester.java @@ -23,6 +23,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.StringReader; import java.util.ArrayList; +import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.List; @@ -530,6 +531,10 @@ public class AnalyzingSuggester extends Lookup { public boolean store(OutputStream output) throws IOException { DataOutput dataOut = new OutputStreamDataOutput(output); try { + if (fst == null) { + return false; + } + fst.save(dataOut); dataOut.writeVInt(maxAnalyzedPathsForOneInput); } finally { @@ -557,6 +562,9 @@ public class AnalyzingSuggester extends Lookup { if (onlyMorePopular) { throw new IllegalArgumentException("this suggester only works with onlyMorePopular=false"); } + if (fst == null) { + return Collections.emptyList(); + } //System.out.println("lookup key=" + key + " num=" + num); final BytesRef utf8Key = new BytesRef(key); diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/WFSTCompletionLookup.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/WFSTCompletionLookup.java index 2c938632f23..6b2ba97c5b1 100644 --- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/WFSTCompletionLookup.java +++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/WFSTCompletionLookup.java @@ -147,6 +147,10 @@ public class WFSTCompletionLookup extends Lookup { throw new IllegalArgumentException("this suggester only works with onlyMorePopular=false"); } + if (fst == null) { + return Collections.emptyList(); + } + BytesRef scratch = new BytesRef(key); int prefixLength = scratch.length; Arc arc = new Arc(); @@ -219,6 +223,9 @@ public class WFSTCompletionLookup extends Lookup { * or null if it does not exist. */ public Object get(CharSequence key) { + if (fst == null) { + return null; + } Arc arc = new Arc(); Long result = null; try { diff --git a/lucene/suggest/src/test/org/apache/lucene/search/suggest/analyzing/AnalyzingSuggesterTest.java b/lucene/suggest/src/test/org/apache/lucene/search/suggest/analyzing/AnalyzingSuggesterTest.java index 2ac25c79a80..0057d9aa1a4 100644 --- a/lucene/suggest/src/test/org/apache/lucene/search/suggest/analyzing/AnalyzingSuggesterTest.java +++ b/lucene/suggest/src/test/org/apache/lucene/search/suggest/analyzing/AnalyzingSuggesterTest.java @@ -134,6 +134,15 @@ public class AnalyzingSuggesterTest extends LuceneTestCase { assertEquals(50, results.get(0).value, 0.01F); } + public void testEmpty() throws Exception { + Analyzer standard = new MockAnalyzer(random(), MockTokenizer.WHITESPACE, true, MockTokenFilter.ENGLISH_STOPSET, false); + AnalyzingSuggester suggester = new AnalyzingSuggester(standard); + suggester.build(new TermFreqArrayIterator(new TermFreq[0])); + + List result = suggester.lookup("a", false, 20); + assertTrue(result.isEmpty()); + } + public void testNoSeps() throws Exception { TermFreq[] keys = new TermFreq[] { new TermFreq("ab cd", 0), diff --git a/lucene/suggest/src/test/org/apache/lucene/search/suggest/analyzing/FuzzySuggesterTest.java b/lucene/suggest/src/test/org/apache/lucene/search/suggest/analyzing/FuzzySuggesterTest.java index f7398a8e62f..b473e4dfc45 100644 --- a/lucene/suggest/src/test/org/apache/lucene/search/suggest/analyzing/FuzzySuggesterTest.java +++ b/lucene/suggest/src/test/org/apache/lucene/search/suggest/analyzing/FuzzySuggesterTest.java @@ -263,8 +263,14 @@ public class FuzzySuggesterTest extends LuceneTestCase { assertEquals("wi fi network is fast", results.get(1).key); assertEquals(10, results.get(1).value); } - - + + public void testEmpty() throws Exception { + FuzzySuggester suggester = new FuzzySuggester(new MockAnalyzer(random(), MockTokenizer.KEYWORD, false)); + suggester.build(new TermFreqArrayIterator(new TermFreq[0])); + + List result = suggester.lookup("a", false, 20); + assertTrue(result.isEmpty()); + } public void testInputPathRequired() throws Exception { diff --git a/lucene/suggest/src/test/org/apache/lucene/search/suggest/fst/WFSTCompletionTest.java b/lucene/suggest/src/test/org/apache/lucene/search/suggest/fst/WFSTCompletionTest.java index d50e71010cb..65e281a8e66 100644 --- a/lucene/suggest/src/test/org/apache/lucene/search/suggest/fst/WFSTCompletionTest.java +++ b/lucene/suggest/src/test/org/apache/lucene/search/suggest/fst/WFSTCompletionTest.java @@ -209,4 +209,12 @@ public class WFSTCompletionTest extends LuceneTestCase { new TermFreq(key2, 50), })); } + + public void testEmpty() throws Exception { + WFSTCompletionLookup suggester = new WFSTCompletionLookup(false); + + suggester.build(new TermFreqArrayIterator(new TermFreq[0])); + List result = suggester.lookup("a", false, 20); + assertTrue(result.isEmpty()); + } }