Fix simple_query_string on invalid input (#28219)
This change converts any exception that occurs during the parsing of a simple_query_string to a match_no_docs query (instead of a null query) when leniency is activated. Closes #28204
This commit is contained in:
parent
06f931fcc4
commit
c38c12e3bf
|
@ -33,6 +33,7 @@ import org.apache.lucene.search.PrefixQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.search.SynonymQuery;
|
import org.apache.lucene.search.SynonymQuery;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
|
import org.elasticsearch.common.lucene.search.Queries;
|
||||||
import org.elasticsearch.common.unit.Fuzziness;
|
import org.elasticsearch.common.unit.Fuzziness;
|
||||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.query.AbstractQueryBuilder;
|
import org.elasticsearch.index.query.AbstractQueryBuilder;
|
||||||
|
@ -86,11 +87,11 @@ public class SimpleQueryStringQueryParser extends SimpleQueryParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rethrow the runtime exception, unless the lenient flag has been set, returns null
|
* Rethrow the runtime exception, unless the lenient flag has been set, returns {@link MatchNoDocsQuery}
|
||||||
*/
|
*/
|
||||||
private Query rethrowUnlessLenient(RuntimeException e) {
|
private Query rethrowUnlessLenient(RuntimeException e) {
|
||||||
if (settings.lenient()) {
|
if (settings.lenient()) {
|
||||||
return null;
|
return Queries.newMatchNoDocsQuery("failed query, caused by " + e.getMessage());
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
@ -115,7 +116,7 @@ public class SimpleQueryStringQueryParser extends SimpleQueryParser {
|
||||||
try {
|
try {
|
||||||
return queryBuilder.parse(MultiMatchQueryBuilder.Type.MOST_FIELDS, weights, text, null);
|
return queryBuilder.parse(MultiMatchQueryBuilder.Type.MOST_FIELDS, weights, text, null);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return rethrowUnlessLenient(new IllegalArgumentException(e.getMessage()));
|
return rethrowUnlessLenient(new IllegalStateException(e.getMessage()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +136,7 @@ public class SimpleQueryStringQueryParser extends SimpleQueryParser {
|
||||||
settings.fuzzyMaxExpansions, settings.fuzzyTranspositions);
|
settings.fuzzyMaxExpansions, settings.fuzzyTranspositions);
|
||||||
disjuncts.add(wrapWithBoost(query, entry.getValue()));
|
disjuncts.add(wrapWithBoost(query, entry.getValue()));
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
rethrowUnlessLenient(e);
|
disjuncts.add(rethrowUnlessLenient(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (disjuncts.size() == 1) {
|
if (disjuncts.size() == 1) {
|
||||||
|
@ -156,7 +157,7 @@ public class SimpleQueryStringQueryParser extends SimpleQueryParser {
|
||||||
}
|
}
|
||||||
return queryBuilder.parse(MultiMatchQueryBuilder.Type.PHRASE, phraseWeights, text, null);
|
return queryBuilder.parse(MultiMatchQueryBuilder.Type.PHRASE, phraseWeights, text, null);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return rethrowUnlessLenient(new IllegalArgumentException(e.getMessage()));
|
return rethrowUnlessLenient(new IllegalStateException(e.getMessage()));
|
||||||
} finally {
|
} finally {
|
||||||
queryBuilder.setPhraseSlop(0);
|
queryBuilder.setPhraseSlop(0);
|
||||||
}
|
}
|
||||||
|
@ -184,7 +185,7 @@ public class SimpleQueryStringQueryParser extends SimpleQueryParser {
|
||||||
disjuncts.add(wrapWithBoost(query, entry.getValue()));
|
disjuncts.add(wrapWithBoost(query, entry.getValue()));
|
||||||
}
|
}
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
return rethrowUnlessLenient(e);
|
disjuncts.add(rethrowUnlessLenient(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (disjuncts.size() == 1) {
|
if (disjuncts.size() == 1) {
|
||||||
|
|
|
@ -46,15 +46,18 @@ import org.elasticsearch.search.internal.SearchContext;
|
||||||
import org.elasticsearch.test.AbstractQueryTestCase;
|
import org.elasticsearch.test.AbstractQueryTestCase;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.anyOf;
|
import static org.hamcrest.Matchers.anyOf;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.either;
|
import static org.hamcrest.Matchers.either;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.instanceOf;
|
import static org.hamcrest.Matchers.instanceOf;
|
||||||
|
@ -607,6 +610,21 @@ public class SimpleQueryStringBuilderTests extends AbstractQueryTestCase<SimpleQ
|
||||||
assertEquals(expected, query);
|
assertEquals(expected, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testLenientToPrefixQuery() throws Exception {
|
||||||
|
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
|
||||||
|
|
||||||
|
Query query = new SimpleQueryStringBuilder("t*")
|
||||||
|
.field(DATE_FIELD_NAME)
|
||||||
|
.field(STRING_FIELD_NAME)
|
||||||
|
.lenient(true)
|
||||||
|
.toQuery(createShardContext());
|
||||||
|
List<Query> expectedQueries = new ArrayList<>();
|
||||||
|
expectedQueries.add(new MatchNoDocsQuery(""));
|
||||||
|
expectedQueries.add(new PrefixQuery(new Term(STRING_FIELD_NAME, "t")));
|
||||||
|
DisjunctionMaxQuery expected = new DisjunctionMaxQuery(expectedQueries, 1.0f);
|
||||||
|
assertEquals(expected, query);
|
||||||
|
}
|
||||||
|
|
||||||
private static IndexMetaData newIndexMeta(String name, Settings oldIndexSettings, Settings indexSettings) {
|
private static IndexMetaData newIndexMeta(String name, Settings oldIndexSettings, Settings indexSettings) {
|
||||||
Settings build = Settings.builder().put(oldIndexSettings)
|
Settings build = Settings.builder().put(oldIndexSettings)
|
||||||
.put(indexSettings)
|
.put(indexSettings)
|
||||||
|
|
Loading…
Reference in New Issue