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
|
* 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)
|
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
|
Other Changes
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
|
|
|
@ -678,7 +678,11 @@ public class SolrPluginUtils {
|
||||||
spec = spaceAroundLessThanPattern.matcher(spec).replaceAll("<");
|
spec = spaceAroundLessThanPattern.matcher(spec).replaceAll("<");
|
||||||
for (String s : spacePattern.split(spec)) {
|
for (String s : spacePattern.split(spec)) {
|
||||||
String[] parts = lessThanPattern.split(s,0);
|
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) {
|
if (optionalClauseCount <= upperBound) {
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
|
@ -694,11 +698,12 @@ public class SolrPluginUtils {
|
||||||
if (-1 < spec.indexOf('%')) {
|
if (-1 < spec.indexOf('%')) {
|
||||||
/* percentage - assume the % was the last char. If not, let Integer.parseInt fail. */
|
/* percentage - assume the % was the last char. If not, let Integer.parseInt fail. */
|
||||||
spec = spec.substring(0,spec.length()-1);
|
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);
|
float calc = (result * percent) * (1/100f);
|
||||||
result = calc < 0 ? result + (int)calc : (int)calc;
|
result = calc < 0 ? result + (int)calc : (int)calc;
|
||||||
} else {
|
} else {
|
||||||
int calc = Integer.parseInt(spec);
|
int calc = checkedParseInt(spec, "Input should be a number");
|
||||||
result = calc < 0 ? result + calc : calc;
|
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
|
* 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.Query;
|
||||||
import org.apache.lucene.search.TermQuery;
|
import org.apache.lucene.search.TermQuery;
|
||||||
import org.apache.solr.SolrTestCaseJ4;
|
import org.apache.solr.SolrTestCaseJ4;
|
||||||
|
import org.apache.solr.common.SolrException;
|
||||||
import org.apache.solr.request.SolrQueryRequest;
|
import org.apache.solr.request.SolrQueryRequest;
|
||||||
import org.apache.solr.search.QParser;
|
import org.apache.solr.search.QParser;
|
||||||
import org.apache.solr.util.SolrPluginUtils.DisjunctionMaxQueryParser;
|
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
|
@Test
|
||||||
public void testMinShouldMatchAutoRelax() {
|
public void testMinShouldMatchAutoRelax() {
|
||||||
/* The basics should not be affected by autoRelax */
|
/* The basics should not be affected by autoRelax */
|
||||||
|
|
Loading…
Reference in New Issue