You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rm...@apache.org on 2014/03/17 19:57:25 UTC

svn commit: r1578513 - in /lucene/dev/branches/lucene_solr_4_7: ./ lucene/ lucene/core/ lucene/core/src/java/org/apache/lucene/search/spans/ lucene/core/src/test/org/apache/lucene/search/spans/

Author: rmuir
Date: Mon Mar 17 18:57:24 2014
New Revision: 1578513

URL: http://svn.apache.org/r1578513
Log:
LUCENE-5450: NPE and Illegal Argument Exception in wrapped SpanMultiTerms with no matches

Modified:
    lucene/dev/branches/lucene_solr_4_7/   (props changed)
    lucene/dev/branches/lucene_solr_4_7/lucene/   (props changed)
    lucene/dev/branches/lucene_solr_4_7/lucene/CHANGES.txt   (contents, props changed)
    lucene/dev/branches/lucene_solr_4_7/lucene/core/   (props changed)
    lucene/dev/branches/lucene_solr_4_7/lucene/core/src/java/org/apache/lucene/search/spans/SpanNearQuery.java
    lucene/dev/branches/lucene_solr_4_7/lucene/core/src/java/org/apache/lucene/search/spans/SpanNotQuery.java
    lucene/dev/branches/lucene_solr_4_7/lucene/core/src/java/org/apache/lucene/search/spans/SpanOrQuery.java
    lucene/dev/branches/lucene_solr_4_7/lucene/core/src/java/org/apache/lucene/search/spans/SpanQuery.java
    lucene/dev/branches/lucene_solr_4_7/lucene/core/src/test/org/apache/lucene/search/spans/TestSpanMultiTermQueryWrapper.java

Modified: lucene/dev/branches/lucene_solr_4_7/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_7/lucene/CHANGES.txt?rev=1578513&r1=1578512&r2=1578513&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_7/lucene/CHANGES.txt (original)
+++ lucene/dev/branches/lucene_solr_4_7/lucene/CHANGES.txt Mon Mar 17 18:57:24 2014
@@ -13,6 +13,10 @@ Changes in Runtime Behavior
 
 Bug Fixes
 
+* LUCENE-5450: Fix getField() NPE issues with SpanOr/SpanNear when they have an 
+  empty list of clauses. This can happen for example,  when a wildcard matches 
+  no terms.  (Tim Allison via Robert Muir)
+
 * LUCENE-5532: AutomatonQuery.hashCode was not thread-safe. (Robert Muir)
 
 ======================= Lucene 4.7.0 =======================

Modified: lucene/dev/branches/lucene_solr_4_7/lucene/core/src/java/org/apache/lucene/search/spans/SpanNearQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_7/lucene/core/src/java/org/apache/lucene/search/spans/SpanNearQuery.java?rev=1578513&r1=1578512&r2=1578513&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_7/lucene/core/src/java/org/apache/lucene/search/spans/SpanNearQuery.java (original)
+++ lucene/dev/branches/lucene_solr_4_7/lucene/core/src/java/org/apache/lucene/search/spans/SpanNearQuery.java Mon Mar 17 18:57:24 2014
@@ -64,9 +64,9 @@ public class SpanNearQuery extends SpanQ
     this.clauses = new ArrayList<SpanQuery>(clauses.length);
     for (int i = 0; i < clauses.length; i++) {
       SpanQuery clause = clauses[i];
-      if (i == 0) {                               // check field
+      if (field == null) {                               // check field
         field = clause.getField();
-      } else if (!clause.getField().equals(field)) {
+      } else if (clause.getField() != null && !clause.getField().equals(field)) {
         throw new IllegalArgumentException("Clauses must have same field.");
       }
       this.clauses.add(clause);

Modified: lucene/dev/branches/lucene_solr_4_7/lucene/core/src/java/org/apache/lucene/search/spans/SpanNotQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_7/lucene/core/src/java/org/apache/lucene/search/spans/SpanNotQuery.java?rev=1578513&r1=1578512&r2=1578513&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_7/lucene/core/src/java/org/apache/lucene/search/spans/SpanNotQuery.java (original)
+++ lucene/dev/branches/lucene_solr_4_7/lucene/core/src/java/org/apache/lucene/search/spans/SpanNotQuery.java Mon Mar 17 18:57:24 2014
@@ -62,7 +62,7 @@ public class SpanNotQuery extends SpanQu
     this.pre = (pre >=0) ? pre : 0;
     this.post = (post >= 0) ? post : 0;
 
-    if (!include.getField().equals(exclude.getField()))
+    if (include.getField() != null && exclude.getField() != null && !include.getField().equals(exclude.getField()))
       throw new IllegalArgumentException("Clauses must have same field.");
   }
 

Modified: lucene/dev/branches/lucene_solr_4_7/lucene/core/src/java/org/apache/lucene/search/spans/SpanOrQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_7/lucene/core/src/java/org/apache/lucene/search/spans/SpanOrQuery.java?rev=1578513&r1=1578512&r2=1578513&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_7/lucene/core/src/java/org/apache/lucene/search/spans/SpanOrQuery.java (original)
+++ lucene/dev/branches/lucene_solr_4_7/lucene/core/src/java/org/apache/lucene/search/spans/SpanOrQuery.java Mon Mar 17 18:57:24 2014
@@ -54,7 +54,7 @@ public class SpanOrQuery extends SpanQue
   public final void addClause(SpanQuery clause) {
     if (field == null) {
       field = clause.getField();
-    } else if (!clause.getField().equals(field)) {
+    } else if (clause.getField() != null && !clause.getField().equals(field)) {
       throw new IllegalArgumentException("Clauses must have same field.");
     }
     this.clauses.add(clause);
@@ -132,7 +132,6 @@ public class SpanOrQuery extends SpanQue
     final SpanOrQuery that = (SpanOrQuery) o;
 
     if (!clauses.equals(that.clauses)) return false;
-    if (!clauses.isEmpty() && !field.equals(that.field)) return false;
 
     return getBoost() == that.getBoost();
   }

Modified: lucene/dev/branches/lucene_solr_4_7/lucene/core/src/java/org/apache/lucene/search/spans/SpanQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_7/lucene/core/src/java/org/apache/lucene/search/spans/SpanQuery.java?rev=1578513&r1=1578512&r2=1578513&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_7/lucene/core/src/java/org/apache/lucene/search/spans/SpanQuery.java (original)
+++ lucene/dev/branches/lucene_solr_4_7/lucene/core/src/java/org/apache/lucene/search/spans/SpanQuery.java Mon Mar 17 18:57:24 2014
@@ -34,7 +34,11 @@ public abstract class SpanQuery extends 
    * to search for spans. */
   public abstract Spans getSpans(AtomicReaderContext context, Bits acceptDocs, Map<Term,TermContext> termContexts) throws IOException;
 
-  /** Returns the name of the field matched by this query.*/
+  /** 
+   * Returns the name of the field matched by this query.
+   * <p>
+   * Note that this may return null if the query matches no terms.
+   */
   public abstract String getField();
 
   @Override

Modified: lucene/dev/branches/lucene_solr_4_7/lucene/core/src/test/org/apache/lucene/search/spans/TestSpanMultiTermQueryWrapper.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_7/lucene/core/src/test/org/apache/lucene/search/spans/TestSpanMultiTermQueryWrapper.java?rev=1578513&r1=1578512&r2=1578513&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_7/lucene/core/src/test/org/apache/lucene/search/spans/TestSpanMultiTermQueryWrapper.java (original)
+++ lucene/dev/branches/lucene_solr_4_7/lucene/core/src/test/org/apache/lucene/search/spans/TestSpanMultiTermQueryWrapper.java Mon Mar 17 18:57:24 2014
@@ -24,6 +24,8 @@ import org.apache.lucene.index.RandomInd
 import org.apache.lucene.index.Term;
 import org.apache.lucene.search.FuzzyQuery;
 import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.PrefixQuery;
+import org.apache.lucene.search.RegexpQuery;
 import org.apache.lucene.search.WildcardQuery;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.LuceneTestCase;
@@ -95,4 +97,133 @@ public class TestSpanMultiTermQueryWrapp
     SpanPositionRangeQuery sprq = new SpanPositionRangeQuery(sfq, 0, 100);
     assertEquals(1, searcher.search(sprq, 10).totalHits);
   }
+  public void testNoSuchMultiTermsInNear() throws Exception {
+    //test to make sure non existent multiterms aren't throwing null pointer exceptions  
+    FuzzyQuery fuzzyNoSuch = new FuzzyQuery(new Term("field", "noSuch"), 1, 0, 1, false);
+    SpanQuery spanNoSuch = new SpanMultiTermQueryWrapper<FuzzyQuery>(fuzzyNoSuch);
+    SpanQuery term = new SpanTermQuery(new Term("field", "brown"));
+    SpanQuery near = new SpanNearQuery(new SpanQuery[]{term, spanNoSuch}, 1, true);
+    assertEquals(0, searcher.search(near, 10).totalHits);
+    //flip order
+    near = new SpanNearQuery(new SpanQuery[]{spanNoSuch, term}, 1, true);
+    assertEquals(0, searcher.search(near, 10).totalHits);
+    
+    WildcardQuery wcNoSuch = new WildcardQuery(new Term("field", "noSuch*"));
+    SpanQuery spanWCNoSuch = new SpanMultiTermQueryWrapper<WildcardQuery>(wcNoSuch);
+    near = new SpanNearQuery(new SpanQuery[]{term, spanWCNoSuch}, 1, true);
+    assertEquals(0, searcher.search(near, 10).totalHits);
+  
+    RegexpQuery rgxNoSuch = new RegexpQuery(new Term("field", "noSuch"));
+    SpanQuery spanRgxNoSuch = new SpanMultiTermQueryWrapper<RegexpQuery>(rgxNoSuch);
+    near = new SpanNearQuery(new SpanQuery[]{term, spanRgxNoSuch}, 1, true);
+    assertEquals(0, searcher.search(near, 10).totalHits);
+    
+    PrefixQuery prfxNoSuch = new PrefixQuery(new Term("field", "noSuch"));
+    SpanQuery spanPrfxNoSuch = new SpanMultiTermQueryWrapper<PrefixQuery>(prfxNoSuch);
+    near = new SpanNearQuery(new SpanQuery[]{term, spanPrfxNoSuch}, 1, true);
+    assertEquals(0, searcher.search(near, 10).totalHits);
+
+    //test single noSuch
+    near = new SpanNearQuery(new SpanQuery[]{spanPrfxNoSuch}, 1, true);
+    assertEquals(0, searcher.search(near, 10).totalHits);
+    
+    //test double noSuch
+    near = new SpanNearQuery(new SpanQuery[]{spanPrfxNoSuch, spanPrfxNoSuch}, 1, true);
+    assertEquals(0, searcher.search(near, 10).totalHits);
+
+  }
+  
+  public void testNoSuchMultiTermsInNotNear() throws Exception {
+    //test to make sure non existent multiterms aren't throwing non-matching field exceptions  
+    FuzzyQuery fuzzyNoSuch = new FuzzyQuery(new Term("field", "noSuch"), 1, 0, 1, false);
+    SpanQuery spanNoSuch = new SpanMultiTermQueryWrapper<FuzzyQuery>(fuzzyNoSuch);
+    SpanQuery term = new SpanTermQuery(new Term("field", "brown"));
+    SpanNotQuery notNear = new SpanNotQuery(term, spanNoSuch, 0,0);
+    assertEquals(1, searcher.search(notNear, 10).totalHits);
+
+    //flip
+    notNear = new SpanNotQuery(spanNoSuch, term, 0,0);
+    assertEquals(0, searcher.search(notNear, 10).totalHits);
+    
+    //both noSuch
+    notNear = new SpanNotQuery(spanNoSuch, spanNoSuch, 0,0);
+    assertEquals(0, searcher.search(notNear, 10).totalHits);
+
+    WildcardQuery wcNoSuch = new WildcardQuery(new Term("field", "noSuch*"));
+    SpanQuery spanWCNoSuch = new SpanMultiTermQueryWrapper<WildcardQuery>(wcNoSuch);
+    notNear = new SpanNotQuery(term, spanWCNoSuch, 0,0);
+    assertEquals(1, searcher.search(notNear, 10).totalHits);
+  
+    RegexpQuery rgxNoSuch = new RegexpQuery(new Term("field", "noSuch"));
+    SpanQuery spanRgxNoSuch = new SpanMultiTermQueryWrapper<RegexpQuery>(rgxNoSuch);
+    notNear = new SpanNotQuery(term, spanRgxNoSuch, 1, 1);
+    assertEquals(1, searcher.search(notNear, 10).totalHits);
+    
+    PrefixQuery prfxNoSuch = new PrefixQuery(new Term("field", "noSuch"));
+    SpanQuery spanPrfxNoSuch = new SpanMultiTermQueryWrapper<PrefixQuery>(prfxNoSuch);
+    notNear = new SpanNotQuery(term, spanPrfxNoSuch, 1, 1);
+    assertEquals(1, searcher.search(notNear, 10).totalHits);
+    
+  }
+  
+  public void testNoSuchMultiTermsInOr() throws Exception {
+    //test to make sure non existent multiterms aren't throwing null pointer exceptions  
+    FuzzyQuery fuzzyNoSuch = new FuzzyQuery(new Term("field", "noSuch"), 1, 0, 1, false);
+    SpanQuery spanNoSuch = new SpanMultiTermQueryWrapper<FuzzyQuery>(fuzzyNoSuch);
+    SpanQuery term = new SpanTermQuery(new Term("field", "brown"));
+    SpanOrQuery near = new SpanOrQuery(new SpanQuery[]{term, spanNoSuch});
+    assertEquals(1, searcher.search(near, 10).totalHits);
+    
+    //flip
+    near = new SpanOrQuery(new SpanQuery[]{spanNoSuch, term});
+    assertEquals(1, searcher.search(near, 10).totalHits);
+
+    
+    WildcardQuery wcNoSuch = new WildcardQuery(new Term("field", "noSuch*"));
+    SpanQuery spanWCNoSuch = new SpanMultiTermQueryWrapper<WildcardQuery>(wcNoSuch);
+    near = new SpanOrQuery(new SpanQuery[]{term, spanWCNoSuch});
+    assertEquals(1, searcher.search(near, 10).totalHits);
+  
+    RegexpQuery rgxNoSuch = new RegexpQuery(new Term("field", "noSuch"));
+    SpanQuery spanRgxNoSuch = new SpanMultiTermQueryWrapper<RegexpQuery>(rgxNoSuch);
+    near = new SpanOrQuery(new SpanQuery[]{term, spanRgxNoSuch});
+    assertEquals(1, searcher.search(near, 10).totalHits);
+    
+    PrefixQuery prfxNoSuch = new PrefixQuery(new Term("field", "noSuch"));
+    SpanQuery spanPrfxNoSuch = new SpanMultiTermQueryWrapper<PrefixQuery>(prfxNoSuch);
+    near = new SpanOrQuery(new SpanQuery[]{term, spanPrfxNoSuch});
+    assertEquals(1, searcher.search(near, 10).totalHits);
+    
+    near = new SpanOrQuery(new SpanQuery[]{spanPrfxNoSuch});
+    assertEquals(0, searcher.search(near, 10).totalHits);
+    
+    near = new SpanOrQuery(new SpanQuery[]{spanPrfxNoSuch, spanPrfxNoSuch});
+    assertEquals(0, searcher.search(near, 10).totalHits);
+
+  }
+  
+  
+  public void testNoSuchMultiTermsInSpanFirst() throws Exception {
+    //this hasn't been a problem  
+    FuzzyQuery fuzzyNoSuch = new FuzzyQuery(new Term("field", "noSuch"), 1, 0, 1, false);
+    SpanQuery spanNoSuch = new SpanMultiTermQueryWrapper<FuzzyQuery>(fuzzyNoSuch);
+    SpanQuery spanFirst = new SpanFirstQuery(spanNoSuch, 10);
+ 
+    assertEquals(0, searcher.search(spanFirst, 10).totalHits);
+    
+    WildcardQuery wcNoSuch = new WildcardQuery(new Term("field", "noSuch*"));
+    SpanQuery spanWCNoSuch = new SpanMultiTermQueryWrapper<WildcardQuery>(wcNoSuch);
+    spanFirst = new SpanFirstQuery(spanWCNoSuch, 10);
+    assertEquals(0, searcher.search(spanFirst, 10).totalHits);
+  
+    RegexpQuery rgxNoSuch = new RegexpQuery(new Term("field", "noSuch"));
+    SpanQuery spanRgxNoSuch = new SpanMultiTermQueryWrapper<RegexpQuery>(rgxNoSuch);
+    spanFirst = new SpanFirstQuery(spanRgxNoSuch, 10);
+    assertEquals(0, searcher.search(spanFirst, 10).totalHits);
+    
+    PrefixQuery prfxNoSuch = new PrefixQuery(new Term("field", "noSuch"));
+    SpanQuery spanPrfxNoSuch = new SpanMultiTermQueryWrapper<PrefixQuery>(prfxNoSuch);
+    spanFirst = new SpanFirstQuery(spanPrfxNoSuch, 10);
+    assertEquals(0, searcher.search(spanFirst, 10).totalHits);
+  }
 }