You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by mi...@apache.org on 2016/07/08 17:08:05 UTC

lucene-solr:master: LUCENE-7276: MatchNoDocsQuery now inclues an optional reason for why it was used

Repository: lucene-solr
Updated Branches:
  refs/heads/master be8d56ada -> cbbc50526


LUCENE-7276: MatchNoDocsQuery now inclues an optional reason for why it was used


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/cbbc5052
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/cbbc5052
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/cbbc5052

Branch: refs/heads/master
Commit: cbbc505268e8fa994fa21383ed49a91b2e923f66
Parents: be8d56a
Author: Mike McCandless <mi...@apache.org>
Authored: Fri Jul 8 13:07:54 2016 -0400
Committer: Mike McCandless <mi...@apache.org>
Committed: Fri Jul 8 13:07:54 2016 -0400

----------------------------------------------------------------------
 lucene/CHANGES.txt                              |  3 ++
 .../org/apache/lucene/document/BinaryPoint.java |  2 +-
 .../org/apache/lucene/search/BooleanQuery.java  |  4 +-
 .../apache/lucene/search/MatchNoDocsQuery.java  | 17 +++++++-
 .../apache/lucene/search/MultiPhraseQuery.java  |  2 +-
 .../org/apache/lucene/search/PhraseQuery.java   |  2 +-
 .../lucene/search/TestMatchNoDocsQuery.java     | 46 ++++++++++++++++----
 .../org/apache/lucene/search/join/JoinUtil.java |  4 +-
 .../apache/lucene/queries/CommonTermsQuery.java |  2 +-
 .../queryparser/simple/SimpleQueryParser.java   |  2 +-
 .../precedence/TestPrecedenceQueryParser.java   | 23 ++++++++--
 .../standard/TestMultiFieldQPHelper.java        | 24 +++++++---
 .../flexible/standard/TestQPHelper.java         | 36 ++++++++++-----
 .../queryparser/util/QueryParserTestBase.java   | 37 +++++++++++-----
 .../org/apache/lucene/document/LatLonPoint.java |  4 +-
 15 files changed, 154 insertions(+), 54 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cbbc5052/lucene/CHANGES.txt
----------------------------------------------------------------------
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index f609e83..bed9b80 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -89,6 +89,9 @@ Improvements
   control whether to split on whitespace prior to text analysis.  Default
   behavior remains unchanged: split-on-whitespace=true. (Steve Rowe)
 
+* LUCENE-7276: MatchNoDocsQuery now includes an optional reason for
+  why it was used (Jim Ferenczi via Mike McCandless)
+
 Optimizations
 
 * LUCENE-7330, LUCENE-7339: Speed up conjunction queries. (Adrien Grand)

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cbbc5052/lucene/core/src/java/org/apache/lucene/document/BinaryPoint.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/document/BinaryPoint.java b/lucene/core/src/java/org/apache/lucene/document/BinaryPoint.java
index 3b0a0e9..3388170 100644
--- a/lucene/core/src/java/org/apache/lucene/document/BinaryPoint.java
+++ b/lucene/core/src/java/org/apache/lucene/document/BinaryPoint.java
@@ -212,7 +212,7 @@ public final class BinaryPoint extends Field {
 
     if (bytesPerDim == -1) {
       // There are no points, and we cannot guess the bytesPerDim here, so we return an equivalent query:
-      return new MatchNoDocsQuery();
+      return new MatchNoDocsQuery("empty BinaryPoint.newSetQuery");
     }
 
     // Don't unexpectedly change the user's incoming values array:

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cbbc5052/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java b/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java
index b48f801..c22b1bb 100644
--- a/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java
@@ -207,7 +207,7 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
   @Override
   public Query rewrite(IndexReader reader) throws IOException {
     if (clauses.size() == 0) {
-      return new MatchNoDocsQuery();
+      return new MatchNoDocsQuery("empty BooleanQuery");
     }
     
     // optimize 1-clause queries
@@ -226,7 +226,7 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
             return new BoostQuery(new ConstantScoreQuery(query), 0);
           case MUST_NOT:
             // no positive clauses
-            return new MatchNoDocsQuery();
+            return new MatchNoDocsQuery("pure negative BooleanQuery");
           default:
             throw new AssertionError();
         }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cbbc5052/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java b/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java
index d373b46..825e082 100644
--- a/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java
@@ -28,6 +28,19 @@ import org.apache.lucene.index.Term;
  */
 
 public class MatchNoDocsQuery extends Query {
+
+  private final String reason;
+
+  /** Default constructor */
+  public MatchNoDocsQuery() {
+    this("");
+  }
+
+  /** Provides a reason explaining why this query was used */
+  public MatchNoDocsQuery(String reason) {
+    this.reason = reason;
+  }
+  
   @Override
   public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
     return new Weight(this) {
@@ -37,7 +50,7 @@ public class MatchNoDocsQuery extends Query {
 
       @Override
       public Explanation explain(LeafReaderContext context, int doc) throws IOException {
-        return Explanation.noMatch("");
+        return Explanation.noMatch(reason);
       }
 
       @Override
@@ -73,7 +86,7 @@ public class MatchNoDocsQuery extends Query {
 
   @Override
   public String toString(String field) {
-    return "";
+    return "MatchNoDocsQuery(\"" + reason + "\")";
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cbbc5052/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java b/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
index 2d5c389..00af26c 100644
--- a/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
@@ -317,7 +317,7 @@ public class MultiPhraseQuery extends Query {
   @Override
   public Query rewrite(IndexReader reader) throws IOException {
     if (termArrays.length == 0) {
-      return new MatchNoDocsQuery();
+      return new MatchNoDocsQuery("empty MultiPhraseQuery");
     } else if (termArrays.length == 1) {                 // optimize one-term case
       Term[] terms = termArrays[0];
       BooleanQuery.Builder builder = new BooleanQuery.Builder();

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cbbc5052/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java b/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java
index 459d664..64c0946 100644
--- a/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java
@@ -271,7 +271,7 @@ public class PhraseQuery extends Query {
   @Override
   public Query rewrite(IndexReader reader) throws IOException {
     if (terms.length == 0) {
-      return   new MatchNoDocsQuery();
+      return new MatchNoDocsQuery("empty PhraseQuery");
     } else if (terms.length == 1) {
       return new TermQuery(terms[0]);
     } else if (positions[0] != 0) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cbbc5052/lucene/core/src/test/org/apache/lucene/search/TestMatchNoDocsQuery.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestMatchNoDocsQuery.java b/lucene/core/src/test/org/apache/lucene/search/TestMatchNoDocsQuery.java
index 0a97c58..55514dc 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestMatchNoDocsQuery.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestMatchNoDocsQuery.java
@@ -23,10 +23,10 @@ import org.apache.lucene.analysis.MockAnalyzer;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.index.DirectoryReader;
-import org.apache.lucene.index.IndexWriter;
 import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.Term;
 import org.apache.lucene.store.Directory;
-
 import org.apache.lucene.util.LuceneTestCase;
 
 /**
@@ -41,23 +41,52 @@ public class TestMatchNoDocsQuery extends LuceneTestCase {
     analyzer = new MockAnalyzer(random());
   }
 
+  public void testSimple() throws Exception {
+    MatchNoDocsQuery query = new MatchNoDocsQuery();
+    assertEquals(query.toString(), "MatchNoDocsQuery(\"\")");
+    query = new MatchNoDocsQuery("field 'title' not found");
+    assertEquals(query.toString(), "MatchNoDocsQuery(\"field 'title' not found\")");
+    Query rewrite = query.rewrite(null);
+    assertTrue(rewrite instanceof MatchNoDocsQuery);
+    assertEquals(rewrite.toString(), "MatchNoDocsQuery(\"field 'title' not found\")");
+  }
+  
   public void testQuery() throws Exception {
     Directory dir = newDirectory();
     IndexWriter iw = new IndexWriter(dir, newIndexWriterConfig(analyzer).setMaxBufferedDocs(2).setMergePolicy(newLogMergePolicy()));
     addDoc("one", iw);
     addDoc("two", iw);
-    addDoc("three four", iw);
+    addDoc("three", iw);
     IndexReader ir = DirectoryReader.open(iw);
+    IndexSearcher searcher = new IndexSearcher(ir);
+    
+    Query query = new MatchNoDocsQuery("field not found");
+    assertEquals(searcher.count(query), 0);
 
-    IndexSearcher is = newSearcher(ir);
     ScoreDoc[] hits;
-
-    hits = is.search(new MatchNoDocsQuery(), 1000).scoreDocs;
+    hits = searcher.search(new MatchNoDocsQuery(), 1000).scoreDocs;
     assertEquals(0, hits.length);
+    assertEquals(query.toString(), "MatchNoDocsQuery(\"field not found\")");
 
-    MatchNoDocsQuery mndq = new MatchNoDocsQuery();
-    hits = is.search(mndq, 1000).scoreDocs;
+    BooleanQuery.Builder bq = new BooleanQuery.Builder();
+    bq.add(new BooleanClause(new TermQuery(new Term("key", "five")), BooleanClause.Occur.SHOULD));
+    bq.add(new BooleanClause(new MatchNoDocsQuery("field not found"), BooleanClause.Occur.MUST));
+    query = bq.build();
+    assertEquals(searcher.count(query), 0);
+    hits = searcher.search(new MatchNoDocsQuery(), 1000).scoreDocs;
     assertEquals(0, hits.length);
+    assertEquals(query.toString(), "key:five +MatchNoDocsQuery(\"field not found\")");
+
+    bq = new BooleanQuery.Builder();
+    bq.add(new BooleanClause(new TermQuery(new Term("key", "one")), BooleanClause.Occur.SHOULD));
+    bq.add(new BooleanClause(new MatchNoDocsQuery("field not found"), BooleanClause.Occur.SHOULD));
+    query = bq.build();
+    assertEquals(query.toString(), "key:one MatchNoDocsQuery(\"field not found\")");
+    assertEquals(searcher.count(query), 1);
+    hits = searcher.search(query, 1000).scoreDocs;
+    Query rewrite = query.rewrite(ir);
+    assertEquals(1, hits.length);
+    assertEquals(rewrite.toString(), "key:one MatchNoDocsQuery(\"field not found\")");
 
     iw.close();
     ir.close();
@@ -77,5 +106,4 @@ public class TestMatchNoDocsQuery extends LuceneTestCase {
     doc.add(f);
     iw.addDocument(doc);
   }
-
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cbbc5052/lucene/join/src/java/org/apache/lucene/search/join/JoinUtil.java
----------------------------------------------------------------------
diff --git a/lucene/join/src/java/org/apache/lucene/search/join/JoinUtil.java b/lucene/join/src/java/org/apache/lucene/search/join/JoinUtil.java
index dd25343..b0133e5 100644
--- a/lucene/join/src/java/org/apache/lucene/search/join/JoinUtil.java
+++ b/lucene/join/src/java/org/apache/lucene/search/join/JoinUtil.java
@@ -494,7 +494,7 @@ public final class JoinUtil {
     int numSegments = indexReader.leaves().size();
     final long valueCount;
     if (numSegments == 0) {
-      return new MatchNoDocsQuery();
+      return new MatchNoDocsQuery("JoinUtil.createJoinQuery with no segments");
     } else if (numSegments == 1) {
       // No need to use the ordinal map, because there is just one segment.
       ordinalMap = null;
@@ -503,7 +503,7 @@ public final class JoinUtil {
       if (joinSortedDocValues != null) {
         valueCount = joinSortedDocValues.getValueCount();
       } else {
-        return new MatchNoDocsQuery();
+        return new MatchNoDocsQuery("JoinUtil.createJoinQuery: no join values");
       }
     } else {
       if (ordinalMap == null) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cbbc5052/lucene/queries/src/java/org/apache/lucene/queries/CommonTermsQuery.java
----------------------------------------------------------------------
diff --git a/lucene/queries/src/java/org/apache/lucene/queries/CommonTermsQuery.java b/lucene/queries/src/java/org/apache/lucene/queries/CommonTermsQuery.java
index febfc86..857f4d3 100644
--- a/lucene/queries/src/java/org/apache/lucene/queries/CommonTermsQuery.java
+++ b/lucene/queries/src/java/org/apache/lucene/queries/CommonTermsQuery.java
@@ -119,7 +119,7 @@ public class CommonTermsQuery extends Query {
   @Override
   public Query rewrite(IndexReader reader) throws IOException {
     if (this.terms.isEmpty()) {
-      return new MatchNoDocsQuery();
+      return new MatchNoDocsQuery("CommonTermsQuery with no terms");
     } else if (this.terms.size() == 1) {
       return newTermQuery(this.terms.get(0), null);
     }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cbbc5052/lucene/queryparser/src/java/org/apache/lucene/queryparser/simple/SimpleQueryParser.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/simple/SimpleQueryParser.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/simple/SimpleQueryParser.java
index b87541b..3f9d9a4 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/simple/SimpleQueryParser.java
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/simple/SimpleQueryParser.java
@@ -150,7 +150,7 @@ public class SimpleQueryParser extends QueryBuilder {
     State state = new State(data, buffer, 0, data.length);
     parseSubQuery(state);
     if (state.top == null) {
-      return new MatchNoDocsQuery();
+      return new MatchNoDocsQuery("empty string passed to query parser");
     } else {
       return state.top;
     }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cbbc5052/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/precedence/TestPrecedenceQueryParser.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/precedence/TestPrecedenceQueryParser.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/precedence/TestPrecedenceQueryParser.java
index 5156f73..88e8b9b 100644
--- a/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/precedence/TestPrecedenceQueryParser.java
+++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/precedence/TestPrecedenceQueryParser.java
@@ -38,6 +38,7 @@ import org.apache.lucene.queryparser.util.QueryParserTestBase; // javadocs
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.BoostQuery;
 import org.apache.lucene.search.FuzzyQuery;
+import org.apache.lucene.search.MatchNoDocsQuery;
 import org.apache.lucene.search.PhraseQuery;
 import org.apache.lucene.search.PrefixQuery;
 import org.apache.lucene.search.Query;
@@ -61,7 +62,7 @@ import org.junit.BeforeClass;
  * 
  * @see QueryParserTestBase
  */
-//TODO: refactor this to actually extend that class, overriding the tests
+//TODO: refactor this to actually extend that class (QueryParserTestBase), overriding the tests
 //that it adjusts to fit the precedence requirement, adding its extra tests.
 public class TestPrecedenceQueryParser extends LuceneTestCase {
 
@@ -166,6 +167,20 @@ public class TestPrecedenceQueryParser extends LuceneTestCase {
     }
   }
 
+  public void assertMatchNoDocsQuery(String queryString, Analyzer a) throws Exception {
+    assertMatchNoDocsQuery(getQuery(queryString, a));
+  }
+
+  public void assertMatchNoDocsQuery(Query query) throws Exception {
+    if (query instanceof MatchNoDocsQuery) {
+      // good
+    } else if (query instanceof BooleanQuery && ((BooleanQuery) query).clauses().size() == 0) {
+      // good
+    } else {
+      fail("expected MatchNoDocsQuery or an empty BooleanQuery but got: " + query);
+    }
+  }
+
   public void assertWildcardQueryEquals(String query, boolean lowercase,
       String result) throws Exception {
     PrecedenceQueryParser qp = getParser(null);
@@ -282,7 +297,7 @@ public class TestPrecedenceQueryParser extends LuceneTestCase {
 
   public void testNumber() throws Exception {
     // The numbers go away because SimpleAnalzyer ignores them
-    assertQueryEquals("3", null, "");
+    assertMatchNoDocsQuery("3", null);
     assertQueryEquals("term 1.0 1 2", null, "term");
     assertQueryEquals("term term1 term2", null, "term term term");
 
@@ -367,8 +382,8 @@ public class TestPrecedenceQueryParser extends LuceneTestCase {
     // QueryParser behavior
     assertQueryEquals("term AND NOT phrase term", qpAnalyzer,
         "(+term -(phrase1 phrase2)) term");
-    assertQueryEquals("stop", qpAnalyzer, "");
-    assertQueryEquals("stop OR stop AND stop", qpAnalyzer, "");
+    assertMatchNoDocsQuery("stop", qpAnalyzer);
+    assertMatchNoDocsQuery("stop OR stop AND stop", qpAnalyzer);
     assertTrue(getQuery("term term term", qpAnalyzer) instanceof BooleanQuery);
     assertTrue(getQuery("term +stop", qpAnalyzer) instanceof TermQuery);
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cbbc5052/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestMultiFieldQPHelper.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestMultiFieldQPHelper.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestMultiFieldQPHelper.java
index 28e815d..95e299a 100644
--- a/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestMultiFieldQPHelper.java
+++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestMultiFieldQPHelper.java
@@ -32,6 +32,7 @@ import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfi
 import org.apache.lucene.search.BooleanClause.Occur;
 import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.MatchNoDocsQuery;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.ScoreDoc;
 import org.apache.lucene.store.Directory;
@@ -55,9 +56,22 @@ public class TestMultiFieldQPHelper extends LuceneTestCase {
     assertStopQueryEquals("one stop", "b:one t:one");
     assertStopQueryEquals("one (stop)", "b:one t:one");
     assertStopQueryEquals("one ((stop))", "b:one t:one");
-    assertStopQueryEquals("stop", "");
-    assertStopQueryEquals("(stop)", "");
-    assertStopQueryEquals("((stop))", "");
+    assertStopQueryIsMatchNoDocsQuery("stop");
+    assertStopQueryIsMatchNoDocsQuery("(stop)");
+    assertStopQueryIsMatchNoDocsQuery("((stop))");
+  }
+
+  // verify parsing of query using a stopping analyzer
+  private void assertStopQueryIsMatchNoDocsQuery(String qtxt) throws Exception {
+    String[] fields = { "b", "t" };
+    Occur occur[] = { Occur.SHOULD, Occur.SHOULD };
+    TestQPHelper.QPTestAnalyzer a = new TestQPHelper.QPTestAnalyzer();
+    StandardQueryParser mfqp = new StandardQueryParser();
+    mfqp.setMultiFields(fields);
+    mfqp.setAnalyzer(a);
+
+    Query q = mfqp.parse(qtxt, null);
+    assertTrue(q instanceof MatchNoDocsQuery);
   }
 
   // verify parsing of query using a stopping analyzer
@@ -205,12 +219,12 @@ public class TestMultiFieldQPHelper extends LuceneTestCase {
 
     String[] queries6 = { "((+stop))", "+((stop))" };
     q = QueryParserUtil.parse(queries6, fields, stopA);
-    assertEquals(" ", q.toString());
+    assertEquals("MatchNoDocsQuery(\"\") MatchNoDocsQuery(\"\")", q.toString());
+    //assertEquals(" ", q.toString());
 
     String[] queries7 = { "one ((+stop)) +more", "+((stop)) +two" };
     q = QueryParserUtil.parse(queries7, fields, stopA);
     assertEquals("(b:one +b:more) (+t:two)", q.toString());
-
   }
 
   public void testStaticMethod2() throws QueryNodeException {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cbbc5052/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestQPHelper.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestQPHelper.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestQPHelper.java
index e7d0c89..91b799d 100644
--- a/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestQPHelper.java
+++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestQPHelper.java
@@ -53,8 +53,8 @@ import org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessor
 import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
 import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler;
 import org.apache.lucene.queryparser.flexible.standard.nodes.WildcardQueryNode;
-import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.BooleanClause.Occur;
+import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.BoostQuery;
 import org.apache.lucene.search.FuzzyQuery;
@@ -245,6 +245,20 @@ public class TestQPHelper extends LuceneTestCase {
     }
   }
 
+  public void assertMatchNoDocsQuery(String queryString, Analyzer a) throws Exception {
+    assertMatchNoDocsQuery(getQuery(queryString, a));
+  }
+
+  public void assertMatchNoDocsQuery(Query query) throws Exception {
+    if (query instanceof MatchNoDocsQuery) {
+      // good
+    } else if (query instanceof BooleanQuery && ((BooleanQuery) query).clauses().size() == 0) {
+      // good
+    } else {
+      fail("expected MatchNoDocsQuery or an empty BooleanQuery but got: " + query);
+    }
+  }
+
   public void assertQueryEqualsAllowLeadingWildcard(String query, Analyzer a, String result)
       throws Exception {
     Query q = getQueryAllowLeadingWildcard(query, a);
@@ -522,7 +536,7 @@ public class TestQPHelper extends LuceneTestCase {
 
   public void testNumber() throws Exception {
     // The numbers go away because SimpleAnalzyer ignores them
-    assertQueryEquals("3", null, "");
+    assertMatchNoDocsQuery("3", null);
     assertQueryEquals("term 1.0 1 2", null, "term");
     assertQueryEquals("term term1 term2", null, "term term term");
 
@@ -659,14 +673,14 @@ public class TestQPHelper extends LuceneTestCase {
     assertQueryEquals("term AND NOT phrase term", qpAnalyzer,
         "+term -(phrase1 phrase2) term");
 
-    assertQueryEquals("stop^3", qpAnalyzer, "");
-    assertQueryEquals("stop", qpAnalyzer, "");
-    assertQueryEquals("(stop)^3", qpAnalyzer, "");
-    assertQueryEquals("((stop))^3", qpAnalyzer, "");
-    assertQueryEquals("(stop^3)", qpAnalyzer, "");
-    assertQueryEquals("((stop)^3)", qpAnalyzer, "");
-    assertQueryEquals("(stop)", qpAnalyzer, "");
-    assertQueryEquals("((stop))", qpAnalyzer, "");
+    assertMatchNoDocsQuery("stop^3", qpAnalyzer);
+    assertMatchNoDocsQuery("stop", qpAnalyzer);
+    assertMatchNoDocsQuery("(stop)^3", qpAnalyzer);
+    assertMatchNoDocsQuery("((stop))^3", qpAnalyzer);
+    assertMatchNoDocsQuery("(stop^3)", qpAnalyzer);
+    assertMatchNoDocsQuery("((stop)^3)", qpAnalyzer);
+    assertMatchNoDocsQuery("(stop)", qpAnalyzer);
+    assertMatchNoDocsQuery("((stop))", qpAnalyzer);
     assertTrue(getQuery("term term term", qpAnalyzer) instanceof BooleanQuery);
     assertTrue(getQuery("term +stop", qpAnalyzer) instanceof TermQuery);
   }
@@ -992,7 +1006,7 @@ public class TestQPHelper extends LuceneTestCase {
     q = qp2.parse("the^3", "field");
     // "the" is a stop word so the result is an empty query:
     assertNotNull(q);
-    assertEquals("", q.toString());
+    assertMatchNoDocsQuery(q);
     assertFalse(q instanceof BoostQuery);
   }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cbbc5052/lucene/queryparser/src/test/org/apache/lucene/queryparser/util/QueryParserTestBase.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/util/QueryParserTestBase.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/util/QueryParserTestBase.java
index f1eccf4..d58f660 100644
--- a/lucene/queryparser/src/test/org/apache/lucene/queryparser/util/QueryParserTestBase.java
+++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/util/QueryParserTestBase.java
@@ -161,8 +161,7 @@ public abstract class QueryParserTestBase extends LuceneTestCase {
     return getQuery(query, (Analyzer)null);
   }
 
-  public void assertQueryEquals(String query, Analyzer a, String result)
-    throws Exception {
+  public void assertQueryEquals(String query, Analyzer a, String result) throws Exception {
     Query q = getQuery(query, a);
     String s = q.toString("field");
     if (!s.equals(result)) {
@@ -171,6 +170,20 @@ public abstract class QueryParserTestBase extends LuceneTestCase {
     }
   }
 
+  public void assertMatchNoDocsQuery(String queryString, Analyzer a) throws Exception {
+    assertMatchNoDocsQuery(getQuery(queryString, a));
+  }
+
+  public void assertMatchNoDocsQuery(Query query) throws Exception {
+    if (query instanceof MatchNoDocsQuery) {
+      // good
+    } else if (query instanceof BooleanQuery && ((BooleanQuery) query).clauses().size() == 0) {
+      // good
+    } else {
+      fail("expected MatchNoDocsQuery or an empty BooleanQuery but got: " + query);
+    }
+  }
+
   public void assertQueryEquals(CommonQueryParserConfiguration cqpC, String field, String query, String result) 
     throws Exception {
     Query q = getQuery(query, cqpC);
@@ -418,7 +431,7 @@ public abstract class QueryParserTestBase extends LuceneTestCase {
 
   public void testNumber() throws Exception {
 // The numbers go away because SimpleAnalzyer ignores them
-    assertQueryEquals("3", null, "");
+    assertMatchNoDocsQuery("3", null);
     assertQueryEquals("term 1.0 1 2", null, "term");
     assertQueryEquals("term term1 term2", null, "term term term");
 
@@ -540,14 +553,14 @@ public abstract class QueryParserTestBase extends LuceneTestCase {
 //                      "term phrase1 phrase2 term");
     assertQueryEquals("term AND NOT phrase term", qpAnalyzer,
                       "+term -(phrase1 phrase2) term");
-    assertQueryEquals("stop^3", qpAnalyzer, "");
-    assertQueryEquals("stop", qpAnalyzer, "");
-    assertQueryEquals("(stop)^3", qpAnalyzer, "");
-    assertQueryEquals("((stop))^3", qpAnalyzer, "");
-    assertQueryEquals("(stop^3)", qpAnalyzer, "");
-    assertQueryEquals("((stop)^3)", qpAnalyzer, "");
-    assertQueryEquals("(stop)", qpAnalyzer, "");
-    assertQueryEquals("((stop))", qpAnalyzer, "");
+    assertMatchNoDocsQuery("stop^3", qpAnalyzer);
+    assertMatchNoDocsQuery("stop", qpAnalyzer);
+    assertMatchNoDocsQuery("(stop)^3", qpAnalyzer);
+    assertMatchNoDocsQuery("((stop))^3", qpAnalyzer);
+    assertMatchNoDocsQuery("(stop^3)", qpAnalyzer);
+    assertMatchNoDocsQuery("((stop)^3)", qpAnalyzer);
+    assertMatchNoDocsQuery("(stop)", qpAnalyzer);
+    assertMatchNoDocsQuery("((stop))", qpAnalyzer);
     assertTrue(getQuery("term term term", qpAnalyzer) instanceof BooleanQuery);
     assertTrue(getQuery("term +stop", qpAnalyzer) instanceof TermQuery);
     
@@ -881,7 +894,7 @@ public abstract class QueryParserTestBase extends LuceneTestCase {
     q = getQuery("the^3", qp2);
     // "the" is a stop word so the result is an empty query:
     assertNotNull(q);
-    assertEquals("", q.toString());
+    assertMatchNoDocsQuery(q);
     assertFalse(q instanceof BoostQuery);
   }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cbbc5052/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java
index 9de9436..19f80ab 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java
@@ -191,12 +191,12 @@ public class LatLonPoint extends Field {
     // and should not drag in extra bogus junk! TODO: should encodeCeil just throw ArithmeticException to be less trappy here?
     if (minLatitude == 90.0) {
       // range cannot match as 90.0 can never exist
-      return new MatchNoDocsQuery();
+      return new MatchNoDocsQuery("LatLonPoint.newBoxQuery with minLatitude=90.0");
     }
     if (minLongitude == 180.0) {
       if (maxLongitude == 180.0) {
         // range cannot match as 180.0 can never exist
-        return new MatchNoDocsQuery();
+        return new MatchNoDocsQuery("LatLonPoint.newBoxQuery with minLongitude=maxLongitude=180.0");
       } else if (maxLongitude < minLongitude) {
         // encodeCeil() with dateline wrapping!
         minLongitude = -180.0;