Index: lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java =================================================================== --- lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java (revision 1535810) +++ lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java (working copy) @@ -78,6 +78,16 @@ rewritten.setBoost(this.getBoost()); return rewritten; } + } else { + assert filter != null; + // fix outdated usage pattern from Lucene 2.x/early-3.x, to use QueryWrapperFilter + // (because this Query only accepted filters) + if (filter instanceof QueryWrapperFilter) { + final QueryWrapperFilter qwf = (QueryWrapperFilter) filter; + final ConstantScoreQuery q = new ConstantScoreQuery(qwf.getQuery().rewrite(reader)); + q.setBoost(this.getBoost()); + return q; + } } return this; } @@ -141,7 +151,7 @@ if (disi == null) { return null; } - return new ConstantScorer(disi, this, queryWeight); + return new ConstantScorer(disi, this, queryWeight, query != null); } @Override @@ -173,11 +183,13 @@ protected class ConstantScorer extends Scorer { final DocIdSetIterator docIdSetIterator; final float theScore; + final boolean isQuery; - public ConstantScorer(DocIdSetIterator docIdSetIterator, Weight w, float theScore) { + public ConstantScorer(DocIdSetIterator docIdSetIterator, Weight w, float theScore, boolean isQuery) { super(w); this.theScore = theScore; this.docIdSetIterator = docIdSetIterator; + this.isQuery = isQuery; } @Override @@ -216,7 +228,7 @@ @Override public void setScorer(Scorer scorer) throws IOException { // we must wrap again here, but using the scorer passed in as parameter: - collector.setScorer(new ConstantScorer(scorer, ConstantScorer.this.weight, ConstantScorer.this.theScore)); + collector.setScorer(new ConstantScorer(scorer, ConstantScorer.this.weight, ConstantScorer.this.theScore, isQuery)); } @Override @@ -239,7 +251,7 @@ // this optimization allows out of order scoring as top scorer! @Override public void score(Collector collector) throws IOException { - if (docIdSetIterator instanceof Scorer) { + if (isQuery) { ((Scorer) docIdSetIterator).score(wrapCollector(collector)); } else { super.score(collector); @@ -249,7 +261,7 @@ // 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 (isQuery) { return ((Scorer) docIdSetIterator).score(wrapCollector(collector), max, firstDocID); } else { return super.score(collector, max, firstDocID); @@ -258,7 +270,7 @@ @Override public Collection getChildren() { - if (docIdSetIterator instanceof Scorer) + if (isQuery) return Collections.singletonList(new ChildScorer((Scorer) docIdSetIterator, "constant")); else return Collections.emptyList(); Index: lucene/core/src/test/org/apache/lucene/search/TestConstantScoreQuery.java =================================================================== --- lucene/core/src/test/org/apache/lucene/search/TestConstantScoreQuery.java (revision 1535810) +++ lucene/core/src/test/org/apache/lucene/search/TestConstantScoreQuery.java (working copy) @@ -156,5 +156,31 @@ 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(); + } + } Index: lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java =================================================================== --- lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java (revision 0) +++ lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java (working copy) @@ -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 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); + } + +} Index: lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java =================================================================== --- lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java (revision 0) +++ lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java (working copy) Property changes on: lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property