diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 6ce36f8fdec..ac9974ff584 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -91,6 +91,9 @@ Bug Fixes long document in SimilarityBase or BM25Similarity. Add more warnings to sims that will not work well with extreme tf values. (Ahmet Arslan, Robert Muir) +* LUCENE-6984: SpanMultiTermQueryWrapper no longer modifies its wrapped query. + (Alan Woodward, Adrien Grand) + Other * LUCENE-6924: Upgrade randomizedtesting to 2.3.2. (Dawid Weiss) diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java index e5c18599f8d..a9ce80d8b5b 100644 --- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java +++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java @@ -20,6 +20,11 @@ package org.apache.lucene.search.spans; import java.io.IOException; import java.util.Objects; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Term; import org.apache.lucene.index.TermContext; @@ -30,11 +35,6 @@ import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoringRewrite; import org.apache.lucene.search.TopTermsRewrite; -import java.io.IOException; -import java.util.Objects; -import java.util.List; -import java.util.ArrayList; - /** * Wraps any {@link MultiTermQuery} as a {@link SpanQuery}, * so it can be nested within other SpanQuery classes. @@ -52,7 +52,9 @@ import java.util.ArrayList; * */ public class SpanMultiTermQueryWrapper extends SpanQuery { + protected final Q query; + private SpanRewriteMethod rewriteMethod; /** * Create a new SpanMultiTermQueryWrapper. @@ -67,13 +69,16 @@ public class SpanMultiTermQueryWrapper extends SpanQue @SuppressWarnings({"rawtypes","unchecked"}) public SpanMultiTermQueryWrapper(Q query) { this.query = Objects.requireNonNull(query); - + this.rewriteMethod = selectRewriteMethod(query); + } + + private static SpanRewriteMethod selectRewriteMethod(MultiTermQuery query) { MultiTermQuery.RewriteMethod method = query.getRewriteMethod(); if (method instanceof TopTermsRewrite) { final int pqsize = ((TopTermsRewrite) method).getSize(); - setRewriteMethod(new TopTermsSpanBooleanQueryRewrite(pqsize)); + return new TopTermsSpanBooleanQueryRewrite(pqsize); } else { - setRewriteMethod(SCORING_SPAN_QUERY_REWRITE); + return SCORING_SPAN_QUERY_REWRITE; } } @@ -81,10 +86,7 @@ public class SpanMultiTermQueryWrapper extends SpanQue * Expert: returns the rewriteMethod */ public final SpanRewriteMethod getRewriteMethod() { - final MultiTermQuery.RewriteMethod m = query.getRewriteMethod(); - if (!(m instanceof SpanRewriteMethod)) - throw new UnsupportedOperationException("You can only use SpanMultiTermQueryWrapper with a suitable SpanRewriteMethod."); - return (SpanRewriteMethod) m; + return rewriteMethod; } /** @@ -92,7 +94,7 @@ public class SpanMultiTermQueryWrapper extends SpanQue * to be a span rewrite method. */ public final void setRewriteMethod(SpanRewriteMethod rewriteMethod) { - query.setRewriteMethod(rewriteMethod); + this.rewriteMethod = rewriteMethod; } @Override @@ -124,10 +126,7 @@ public class SpanMultiTermQueryWrapper extends SpanQue if (getBoost() != 1f) { return super.rewrite(reader); } - final Query q = query.rewrite(reader); - if (!(q instanceof SpanQuery)) - throw new UnsupportedOperationException("You can only use SpanMultiTermQueryWrapper with a suitable SpanRewriteMethod."); - return q; + return rewriteMethod.rewrite(reader, query); } @Override diff --git a/lucene/core/src/test/org/apache/lucene/search/spans/TestSpanMultiTermQueryWrapper.java b/lucene/core/src/test/org/apache/lucene/search/spans/TestSpanMultiTermQueryWrapper.java index c5023c7f8ff..386f29616f9 100644 --- a/lucene/core/src/test/org/apache/lucene/search/spans/TestSpanMultiTermQueryWrapper.java +++ b/lucene/core/src/test/org/apache/lucene/search/spans/TestSpanMultiTermQueryWrapper.java @@ -17,6 +17,8 @@ package org.apache.lucene.search.spans; * limitations under the License. */ +import java.io.IOException; + import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexReader; @@ -24,11 +26,13 @@ import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.search.FuzzyQuery; import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.MultiTermQuery; 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; +import org.junit.Test; /** * Tests for {@link SpanMultiTermQueryWrapper}, wrapping a few MultiTermQueries. @@ -226,4 +230,19 @@ public class TestSpanMultiTermQueryWrapper extends LuceneTestCase { spanFirst = new SpanFirstQuery(spanPrfxNoSuch, 10); assertEquals(0, searcher.search(spanFirst, 10).totalHits); } + + @Test + public void testWrappedQueryIsNotModified() { + final PrefixQuery pq = new PrefixQuery(new Term("field", "test")); + int pqHash = pq.hashCode(); + SpanMultiTermQueryWrapper wrapper = new SpanMultiTermQueryWrapper<>(pq); + assertEquals(pqHash, pq.hashCode()); + wrapper.setRewriteMethod(new SpanMultiTermQueryWrapper.SpanRewriteMethod() { + @Override + public SpanQuery rewrite(IndexReader reader, MultiTermQuery query) throws IOException { + return null; + } + }); + assertEquals(pqHash, pq.hashCode()); + } }