mirror of https://github.com/apache/lucene.git
LUCENE-9050: MultiTermIntervalsSource should call visitLeaf() in visit (#1024)
MultiTermIntervalsSource had an empty visit() implementation, which meant that query visitors would be unaware of its presence in a query tree.
This commit is contained in:
parent
2d1e67c8b4
commit
6aa52b2c4d
|
@ -122,6 +122,9 @@ Bug Fixes
|
|||
* LUCENE-9030: Fix WordnetSynonymParser behaviour so it behaves similar to
|
||||
SolrSynonymParser. (Christoph Buescher via Alan Woodward)
|
||||
|
||||
* LUCENE-9050: MultiTermIntervalsSource.visit() was not calling back to its
|
||||
visitor. (Alan Woodward)
|
||||
|
||||
* LUCENE-9054: Fix reproduceJenkinsFailures.py to not overwrite junit XML files when retrying (hossman)
|
||||
|
||||
Other
|
||||
|
|
|
@ -96,7 +96,7 @@ class MultiTermIntervalsSource extends IntervalsSource {
|
|||
|
||||
@Override
|
||||
public void visit(String field, QueryVisitor visitor) {
|
||||
|
||||
visitor.visitLeaf(new IntervalQuery(field, this));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.util.Collections;
|
|||
import java.util.Objects;
|
||||
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.search.BooleanClause;
|
||||
import org.apache.lucene.search.MatchesIterator;
|
||||
import org.apache.lucene.search.QueryVisitor;
|
||||
|
||||
|
@ -146,7 +147,7 @@ class OffsetIntervalsSource extends IntervalsSource {
|
|||
|
||||
@Override
|
||||
public void visit(String field, QueryVisitor visitor) {
|
||||
in.visit(field, visitor);
|
||||
in.visit(field, visitor.getSubVisitor(BooleanClause.Occur.MUST, new IntervalQuery(field, this)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -18,7 +18,11 @@
|
|||
package org.apache.lucene.queries.intervals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.apache.lucene.analysis.CharArraySet;
|
||||
|
@ -36,9 +40,13 @@ import org.apache.lucene.index.LeafReaderContext;
|
|||
import org.apache.lucene.index.NumericDocValues;
|
||||
import org.apache.lucene.index.RandomIndexWriter;
|
||||
import org.apache.lucene.index.ReaderUtil;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.BooleanClause;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.MatchesIterator;
|
||||
import org.apache.lucene.search.PrefixQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.QueryVisitor;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.apache.lucene.util.IOUtils;
|
||||
|
@ -140,6 +148,38 @@ public class TestIntervals extends LuceneTestCase {
|
|||
assertEquals(expectedMatchCount, matchedDocs);
|
||||
}
|
||||
|
||||
private void checkVisits(IntervalsSource source, int expectedVisitCount, String... expectedTerms) {
|
||||
Set<String> actualTerms = new HashSet<>();
|
||||
int[] visitedSources = new int[1];
|
||||
source.visit("field", new QueryVisitor() {
|
||||
@Override
|
||||
public void consumeTerms(Query query, Term... terms) {
|
||||
visitedSources[0]++;
|
||||
actualTerms.addAll(Arrays.stream(terms).map(Term::text).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLeaf(Query query) {
|
||||
visitedSources[0]++;
|
||||
super.visitLeaf(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryVisitor getSubVisitor(BooleanClause.Occur occur, Query parent) {
|
||||
visitedSources[0]++;
|
||||
return super.getSubVisitor(occur, parent);
|
||||
}
|
||||
});
|
||||
|
||||
Set<String> expectedSet = new HashSet<>(Arrays.asList(expectedTerms));
|
||||
expectedSet.removeAll(actualTerms);
|
||||
actualTerms.removeAll(Arrays.asList(expectedTerms));
|
||||
assertEquals(expectedVisitCount, visitedSources[0]);
|
||||
assertTrue("Unexpected terms collected: " + actualTerms, actualTerms.isEmpty());
|
||||
assertTrue("Missing expected terms: " + expectedSet, expectedSet.isEmpty());
|
||||
|
||||
}
|
||||
|
||||
private MatchesIterator getMatches(IntervalsSource source, int doc, String field) throws IOException {
|
||||
int ord = ReaderUtil.subIndex(doc, searcher.getIndexReader().leaves());
|
||||
LeafReaderContext ctx = searcher.getIndexReader().leaves().get(ord);
|
||||
|
@ -194,6 +234,8 @@ public class TestIntervals extends LuceneTestCase {
|
|||
assertFalse(mi.next());
|
||||
|
||||
assertEquals(1, source.minExtent());
|
||||
|
||||
checkVisits(source, 1, "porridge");
|
||||
}
|
||||
|
||||
public void testOrderedNearIntervals() throws IOException {
|
||||
|
@ -221,6 +263,8 @@ public class TestIntervals extends LuceneTestCase {
|
|||
assertFalse(mi.next());
|
||||
|
||||
assertEquals(2, source.minExtent());
|
||||
|
||||
checkVisits(source, 3, "pease", "hot");
|
||||
}
|
||||
|
||||
public void testPhraseIntervals() throws IOException {
|
||||
|
@ -244,6 +288,8 @@ public class TestIntervals extends LuceneTestCase {
|
|||
assertMatch(mi, 6, 7, 41, 55);
|
||||
|
||||
assertEquals(2, source.minExtent());
|
||||
|
||||
checkVisits(source, 3, "pease", "porridge");
|
||||
}
|
||||
|
||||
public void testUnorderedNearIntervals() throws IOException {
|
||||
|
@ -272,6 +318,8 @@ public class TestIntervals extends LuceneTestCase {
|
|||
});
|
||||
|
||||
assertEquals(2, source.minExtent());
|
||||
|
||||
checkVisits(source, 3, "pease", "hot");
|
||||
}
|
||||
|
||||
public void testIntervalDisjunction() throws IOException {
|
||||
|
@ -293,6 +341,8 @@ public class TestIntervals extends LuceneTestCase {
|
|||
assertFalse(mi.next());
|
||||
|
||||
assertEquals(1, source.minExtent());
|
||||
|
||||
checkVisits(source, 4, "pease", "hot", "notMatching");
|
||||
}
|
||||
|
||||
public void testCombinationDisjunction() throws IOException {
|
||||
|
@ -307,6 +357,8 @@ public class TestIntervals extends LuceneTestCase {
|
|||
});
|
||||
|
||||
assertEquals(2, source.minExtent());
|
||||
|
||||
checkVisits(source, 5, "alph", "sacred", "measureless");
|
||||
}
|
||||
|
||||
public void testNesting() throws IOException {
|
||||
|
@ -371,6 +423,8 @@ public class TestIntervals extends LuceneTestCase {
|
|||
{ 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 18, 18 },
|
||||
{}
|
||||
});
|
||||
|
||||
checkVisits(before, 7, "pease", "porridge", "hot", "cold");
|
||||
}
|
||||
|
||||
public void testNesting2() throws IOException {
|
||||
|
@ -435,9 +489,10 @@ public class TestIntervals extends LuceneTestCase {
|
|||
{ 0, 3 },
|
||||
{}
|
||||
});
|
||||
checkIntervals(Intervals.unorderedNoOverlaps(
|
||||
IntervalsSource source = Intervals.unorderedNoOverlaps(
|
||||
Intervals.term("porridge"),
|
||||
Intervals.unordered(Intervals.term("pease"), Intervals.term("porridge"))), "field1", 3, new int[][]{
|
||||
Intervals.unordered(Intervals.term("pease"), Intervals.term("porridge")));
|
||||
checkIntervals(source, "field1", 3, new int[][]{
|
||||
{},
|
||||
{ 1, 4, 4, 7 },
|
||||
{ 1, 4, 4, 7 },
|
||||
|
@ -445,6 +500,8 @@ public class TestIntervals extends LuceneTestCase {
|
|||
{ 1, 4, 4, 7 },
|
||||
{}
|
||||
});
|
||||
// automatic rewrites mean that we end up with 11 sources to visit
|
||||
checkVisits(source, 11, "porridge", "pease");
|
||||
}
|
||||
|
||||
public void testContainedBy() throws IOException {
|
||||
|
@ -475,6 +532,8 @@ public class TestIntervals extends LuceneTestCase {
|
|||
assertFalse(subs.next());
|
||||
assertFalse(mi.next());
|
||||
assertEquals(1, source.minExtent());
|
||||
|
||||
checkVisits(source, 5, "porridge", "pease", "cold");
|
||||
}
|
||||
|
||||
public void testContaining() throws IOException {
|
||||
|
@ -770,6 +829,8 @@ public class TestIntervals extends LuceneTestCase {
|
|||
});
|
||||
assertEquals("Automaton [p*] expanded to too many terms (limit 1)", e.getMessage());
|
||||
}
|
||||
|
||||
checkVisits(Intervals.prefix(new BytesRef("p")), 1);
|
||||
}
|
||||
|
||||
public void testWildcard() throws IOException {
|
||||
|
@ -795,6 +856,8 @@ public class TestIntervals extends LuceneTestCase {
|
|||
}
|
||||
});
|
||||
assertEquals("Automaton [?ot] expanded to too many terms (limit 1)", e.getMessage());
|
||||
|
||||
checkVisits(Intervals.wildcard(new BytesRef("p??")), 1);
|
||||
}
|
||||
|
||||
public void testWrappedFilters() throws IOException {
|
||||
|
|
Loading…
Reference in New Issue