mirror of https://github.com/apache/lucene.git
SOLR-13207: Handle query errors in calculateMinShouldMatch (#978)
Traps error that arises when the < operator is used at the end of a query field. Also handles NumberFormatException when the operand isn't a number.
This commit is contained in:
parent
124d38a597
commit
b17d630e50
|
@ -145,6 +145,9 @@ Bug Fixes
|
|||
* SOLR-13823: Fix ClassCastEx when score is requested with group.query. This also fixes score not being generated
|
||||
for distributed group.query case. (Uwe Jäger, Munendra S N)
|
||||
|
||||
* SOLR-13207: In dismax and edismax "minimum should match" queries, the < operator not followed by a number will now return
|
||||
an HTTP 400 error rather than 500, and the error message will explain that < must be followed by a number. (Chris Hennick)
|
||||
|
||||
Other Changes
|
||||
---------------------
|
||||
|
||||
|
|
|
@ -678,7 +678,11 @@ public class SolrPluginUtils {
|
|||
spec = spaceAroundLessThanPattern.matcher(spec).replaceAll("<");
|
||||
for (String s : spacePattern.split(spec)) {
|
||||
String[] parts = lessThanPattern.split(s,0);
|
||||
int upperBound = Integer.parseInt(parts[0]);
|
||||
if (parts.length == 0) {
|
||||
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
|
||||
"Operator < must be followed by a number");
|
||||
}
|
||||
int upperBound = checkedParseInt(parts[0], "Operator < must be followed by a number");
|
||||
if (optionalClauseCount <= upperBound) {
|
||||
return result;
|
||||
} else {
|
||||
|
@ -694,11 +698,12 @@ public class SolrPluginUtils {
|
|||
if (-1 < spec.indexOf('%')) {
|
||||
/* percentage - assume the % was the last char. If not, let Integer.parseInt fail. */
|
||||
spec = spec.substring(0,spec.length()-1);
|
||||
int percent = Integer.parseInt(spec);
|
||||
int percent = checkedParseInt(spec,
|
||||
"% must be preceded by a number and not combined with other operators");
|
||||
float calc = (result * percent) * (1/100f);
|
||||
result = calc < 0 ? result + (int)calc : (int)calc;
|
||||
} else {
|
||||
int calc = Integer.parseInt(spec);
|
||||
int calc = checkedParseInt(spec, "Input should be a number");
|
||||
result = calc < 0 ? result + calc : calc;
|
||||
}
|
||||
|
||||
|
@ -707,6 +712,25 @@ public class SolrPluginUtils {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper of {@link Integer#parseInt(String)} that wraps any {@link NumberFormatException} in a
|
||||
* {@link SolrException} with HTTP 400 Bad Request status.
|
||||
*
|
||||
* @param input the string to parse
|
||||
* @param errorMessage the error message for any SolrException
|
||||
* @return the integer value of {@code input}
|
||||
* @throws SolrException when parseInt throws NumberFormatException
|
||||
*/
|
||||
private static int checkedParseInt(String input, String errorMessage) {
|
||||
int percent;
|
||||
try {
|
||||
percent = Integer.parseInt(input);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, errorMessage, e);
|
||||
}
|
||||
return percent;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Recursively walks the "from" query pulling out sub-queries and
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.apache.lucene.search.PhraseQuery;
|
|||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.apache.solr.SolrTestCaseJ4;
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.request.SolrQueryRequest;
|
||||
import org.apache.solr.search.QParser;
|
||||
import org.apache.solr.util.SolrPluginUtils.DisjunctionMaxQueryParser;
|
||||
|
@ -338,6 +339,15 @@ public class SolrPluginUtilsTest extends SolrTestCaseJ4 {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMinShouldMatchBadQueries() {
|
||||
expectThrows(SolrException.class, () -> calcMSM(1, "1<"));
|
||||
expectThrows(SolrException.class, () -> calcMSM(1, "1<x"));
|
||||
expectThrows(SolrException.class, () -> calcMSM(1, "x%"));
|
||||
expectThrows(SolrException.class, () -> calcMSM(1, "%%"));
|
||||
expectThrows(SolrException.class, () -> calcMSM(1, "x"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMinShouldMatchAutoRelax() {
|
||||
/* The basics should not be affected by autoRelax */
|
||||
|
|
Loading…
Reference in New Issue