You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by us...@apache.org on 2013/10/26 11:12:32 UTC

svn commit: r1535950 - in /lucene/dev/trunk/lucene: ./ core/src/java/org/apache/lucene/search/ core/src/test/org/apache/lucene/search/ test-framework/src/java/org/apache/lucene/search/

Author: uschindler
Date: Sat Oct 26 09:12:32 2013
New Revision: 1535950

URL: http://svn.apache.org/r1535950
Log:
LUCENE-5307: Fix topScorer inconsistency in handling QueryWrapperFilter inside ConstantScoreQuery, which now rewrites to a query removing the obsolete QueryWrapperFilter

Added:
    lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java   (with props)
Modified:
    lucene/dev/trunk/lucene/CHANGES.txt
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreQuery.java

Modified: lucene/dev/trunk/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/CHANGES.txt?rev=1535950&r1=1535949&r2=1535950&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/CHANGES.txt (original)
+++ lucene/dev/trunk/lucene/CHANGES.txt Sat Oct 26 09:12:32 2013
@@ -161,6 +161,10 @@ Bug Fixes
 * LUCENE-5303: OrdinalsCache did not use coreCacheKey, resulting in
   over caching across multiple threads. (Mike McCandless, Shai Erera)
 
+* LUCENE-5307: Fix topScorer inconsistency in handling QueryWrapperFilter
+  inside ConstantScoreQuery, which now rewrites to a query removing the
+  obsolete QueryWrapperFilter.  (Adrien Grand, Uwe Schindler)
+
 API Changes:
 
 * LUCENE-5222: Add SortField.needsScores(). Previously it was not possible

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java?rev=1535950&r1=1535949&r2=1535950&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java Sat Oct 26 09:12:32 2013
@@ -78,6 +78,17 @@ public class ConstantScoreQuery extends 
         rewritten.setBoost(this.getBoost());
         return rewritten;
       }
+    } else {
+      assert filter != null;
+      // Fix outdated usage pattern from Lucene 2.x/early-3.x:
+      // because ConstantScoreQuery only accepted filters,
+      // QueryWrapperFilter was used to wrap queries.
+      if (filter instanceof QueryWrapperFilter) {
+        final QueryWrapperFilter qwf = (QueryWrapperFilter) filter;
+        final Query rewritten = new ConstantScoreQuery(qwf.getQuery().rewrite(reader));
+        rewritten.setBoost(this.getBoost());
+        return rewritten;
+      }
     }
     return this;
   }
@@ -239,7 +250,7 @@ public class ConstantScoreQuery extends 
     // this optimization allows out of order scoring as top scorer!
     @Override
     public void score(Collector collector) throws IOException {
-      if (docIdSetIterator instanceof Scorer) {
+      if (query != null) {
         ((Scorer) docIdSetIterator).score(wrapCollector(collector));
       } else {
         super.score(collector);
@@ -249,7 +260,7 @@ public class ConstantScoreQuery extends 
     // this optimization allows out of order scoring as top scorer,
     @Override
     public boolean score(Collector collector, int max, int firstDocID) throws IOException {
-      if (docIdSetIterator instanceof Scorer) {
+      if (query != null) {
         return ((Scorer) docIdSetIterator).score(wrapCollector(collector), max, firstDocID);
       } else {
         return super.score(collector, max, firstDocID);
@@ -258,7 +269,7 @@ public class ConstantScoreQuery extends 
 
     @Override
     public Collection<ChildScorer> getChildren() {
-      if (docIdSetIterator instanceof Scorer)
+      if (query != null)
         return Collections.singletonList(new ChildScorer((Scorer) docIdSetIterator, "constant"));
       else
         return Collections.emptyList();

Modified: lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreQuery.java?rev=1535950&r1=1535949&r2=1535950&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreQuery.java (original)
+++ lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreQuery.java Sat Oct 26 09:12:32 2013
@@ -156,5 +156,31 @@ public class TestConstantScoreQuery exte
     r.close();
     d.close();
   }
-  
+
+  // LUCENE-5307
+  // don't reuse the scorer of filters since they have been created with topScorer=false
+  public void testQueryWrapperFilter() throws IOException {
+    Directory d = newDirectory();
+    RandomIndexWriter w = new RandomIndexWriter(random(), d);
+    Document doc = new Document();
+    doc.add(newStringField("field", "a", Field.Store.NO));
+    w.addDocument(doc);
+    IndexReader r = w.getReader();
+    w.close();
+
+    Filter filter = new QueryWrapperFilter(AssertingQuery.wrap(random(), new TermQuery(new Term("field", "a"))));
+    IndexSearcher s = newSearcher(r);
+    assert s instanceof AssertingIndexSearcher;
+    // this used to fail
+    s.search(new ConstantScoreQuery(filter), new TotalHitCountCollector());
+    
+    // check the rewrite
+    Query rewritten = new ConstantScoreQuery(filter).rewrite(r);
+    assertTrue(rewritten instanceof ConstantScoreQuery);
+    assertTrue(((ConstantScoreQuery) rewritten).getQuery() instanceof AssertingQuery);
+    
+    r.close();
+    d.close();
+  }
+
 }

Added: lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java?rev=1535950&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java (added)
+++ lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java Sat Oct 26 09:12:32 2013
@@ -0,0 +1,98 @@
+package org.apache.lucene.search;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.util.Random;
+import java.util.Set;
+
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.Term;
+
+/** Assertion-enabled query. */
+public class AssertingQuery extends Query {
+
+  private final Random random;
+  private final Query in;
+
+  /** Sole constructor. */
+  public AssertingQuery(Random random, Query in) {
+    this.random = random;
+    this.in = in;
+  }
+
+  /** Wrap a query if necessary. */
+  public static Query wrap(Random random, Query query) {
+    return query instanceof AssertingQuery ? query : new AssertingQuery(random, query);
+  }
+
+  @Override
+  public Weight createWeight(IndexSearcher searcher) throws IOException {
+    return AssertingWeight.wrap(new Random(random.nextLong()), in.createWeight(searcher));
+  }
+
+  @Override
+  public void extractTerms(Set<Term> terms) {
+    in.extractTerms(terms);
+  }
+
+  @Override
+  public String toString(String field) {
+    return in.toString(field);
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == null || !(obj instanceof AssertingQuery)) {
+      return false;
+    }
+    final AssertingQuery that = (AssertingQuery) obj;
+    return this.in.equals(that.in);
+  }
+
+  @Override
+  public int hashCode() {
+    return -in.hashCode();
+  }
+
+  @Override
+  public Query clone() {
+    return wrap(new Random(random.nextLong()), in.clone());
+  }
+
+  @Override
+  public Query rewrite(IndexReader reader) throws IOException {
+    final Query rewritten = in.rewrite(reader);
+    if (rewritten == in) {
+      return this;
+    } else {
+      return wrap(new Random(random.nextLong()), rewritten);
+    }
+  }
+
+  @Override
+  public float getBoost() {
+    return in.getBoost();
+  }
+
+  @Override
+  public void setBoost(float b) {
+    in.setBoost(b);
+  }
+
+}