SOLR-11057: Fix overflow in point range queries when querying the type limits

This commit is contained in:
Tomas Fernandez Lobbe 2017-07-18 14:32:11 -07:00
parent 67fbd4f7a1
commit beec66ece7
5 changed files with 66 additions and 0 deletions

View File

@ -360,6 +360,9 @@ Bug Fixes
* SOLR-11073: Fix overflow in interval faceting when querying Long limits (e.g. (Long.MAX_VALUE TO Long.MAX_VALUE])
(Tomás Fernández Löbbe)
* SOLR-11057: Fix overflow in point range queries when querying the type limits
(e.g. q=field_i:{Integer.MAX_VALUE TO Integer.MAX_VALUE]) (Tomás Fernández Löbbe)
Optimizations
----------------------

View File

@ -27,6 +27,7 @@ import org.apache.lucene.index.IndexableField;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.queries.function.valuesource.LongFieldSource;
import org.apache.lucene.queries.function.valuesource.MultiValuedLongFieldSource;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.SortedNumericSelector;
@ -123,6 +124,7 @@ public class DatePointField extends PointField implements DateValueFieldType {
} else {
actualMin = DateMathParser.parseMath(null, min).getTime();
if (!minInclusive) {
if (actualMin == Long.MAX_VALUE) return new MatchNoDocsQuery();
actualMin++;
}
}
@ -131,6 +133,7 @@ public class DatePointField extends PointField implements DateValueFieldType {
} else {
actualMax = DateMathParser.parseMath(null, max).getTime();
if (!maxInclusive) {
if (actualMax == Long.MIN_VALUE) return new MatchNoDocsQuery();
actualMax--;
}
}

View File

@ -25,6 +25,7 @@ import org.apache.lucene.index.IndexableField;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.queries.function.valuesource.IntFieldSource;
import org.apache.lucene.queries.function.valuesource.MultiValuedIntFieldSource;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.SortedNumericSelector;
@ -66,6 +67,7 @@ public class IntPointField extends PointField implements IntValueFieldType {
} else {
actualMin = parseIntFromUser(field.getName(), min);
if (!minInclusive) {
if (actualMin == Integer.MAX_VALUE) return new MatchNoDocsQuery();
actualMin++;
}
}
@ -74,6 +76,7 @@ public class IntPointField extends PointField implements IntValueFieldType {
} else {
actualMax = parseIntFromUser(field.getName(), max);
if (!maxInclusive) {
if (actualMax == Integer.MIN_VALUE) return new MatchNoDocsQuery();
actualMax--;
}
}

View File

@ -25,6 +25,7 @@ import org.apache.lucene.index.IndexableField;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.queries.function.valuesource.LongFieldSource;
import org.apache.lucene.queries.function.valuesource.MultiValuedLongFieldSource;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.SortField;
import org.apache.lucene.util.BytesRef;
@ -65,6 +66,7 @@ public class LongPointField extends PointField implements LongValueFieldType {
} else {
actualMin = parseLongFromUser(field.getName(), min);
if (!minInclusive) {
if (actualMin == Long.MAX_VALUE) return new MatchNoDocsQuery();
actualMin++;
}
}
@ -73,6 +75,7 @@ public class LongPointField extends PointField implements LongValueFieldType {
} else {
actualMax = parseLongFromUser(field.getName(), max);
if (!maxInclusive) {
if (actualMax == Long.MIN_VALUE) return new MatchNoDocsQuery();
actualMax--;
}
}

View File

@ -2381,6 +2381,17 @@ public class TestPointFields extends SolrTestCaseJ4 {
assertQ(req("q", fieldName + ":[" + arr[0] + " TO " + arr[i] + "] AND " + fieldName + ":" + arr[0].replace("-", "\\-"), "fl", "id, " + fieldName),
"//*[@numFound='1']");
}
if (testLong) {
assertQ(req("q", fieldName + ":[" + Long.MIN_VALUE + " TO " + Long.MIN_VALUE + "}", "fl", "id, " + fieldName),
"//*[@numFound='0']");
assertQ(req("q", fieldName + ":{" + Long.MAX_VALUE + " TO " + Long.MAX_VALUE + "]", "fl", "id, " + fieldName),
"//*[@numFound='0']");
} else {
assertQ(req("q", fieldName + ":[" + Integer.MIN_VALUE + " TO " + Integer.MIN_VALUE + "}", "fl", "id, " + fieldName),
"//*[@numFound='0']");
assertQ(req("q", fieldName + ":{" + Integer.MAX_VALUE + " TO " + Integer.MAX_VALUE + "]", "fl", "id, " + fieldName),
"//*[@numFound='0']");
}
}
private void doTestPointFieldFacetField(String nonDocValuesField, String docValuesField, String[] numbers) throws Exception {
@ -3181,6 +3192,43 @@ public class TestPointFields extends SolrTestCaseJ4 {
assertQ(req("q", fieldName + ":{" + arr[0] + " TO " + arr[i] + "}", "fl", "id, " + fieldName),
"//*[@numFound='" + (Math.max(0, i-1)) + "']");
}
clearIndex();
assertU(adoc("id", "1", fieldName, String.valueOf(Float.MAX_VALUE)));
assertU(adoc("id", "2", fieldName, String.valueOf(Float.MIN_VALUE)));
assertU(adoc("id", "3", fieldName, String.valueOf(Float.NEGATIVE_INFINITY)));
assertU(adoc("id", "4", fieldName, String.valueOf(Float.POSITIVE_INFINITY)));
assertU(commit());
assertQ(req("q", fieldName + ":[* TO *]", "fl", "id, " + fieldName),
"//*[@numFound='4']");
// TODO: Awaits fix: SOLR-11070
// assertQ(req("q", fieldName + ":{* TO *}", "fl", "id, " + fieldName),
// "//*[@numFound='4']");
assertQ(req("q", fieldName + ":[" + Float.MIN_VALUE + " TO " + Float.MAX_VALUE + "]", "fl", "id, " + fieldName),
"//*[@numFound='2']");
assertQ(req("q", fieldName + ":{" + Float.MIN_VALUE + " TO " + Float.MAX_VALUE + "]", "fl", "id, " + fieldName),
"//*[@numFound='1']");
assertQ(req("q", fieldName + ":[" + Float.MIN_VALUE + " TO " + Float.MAX_VALUE + "}", "fl", "id, " + fieldName),
"//*[@numFound='1']");
if (testDouble) {
assertQ(req("q", fieldName + ":[" + Double.MIN_VALUE + " TO " + Double.MIN_VALUE + "}", "fl", "id, " + fieldName),
"//*[@numFound='0']");
assertQ(req("q", fieldName + ":{" + Double.MAX_VALUE + " TO " + Double.MAX_VALUE + "]", "fl", "id, " + fieldName),
"//*[@numFound='0']");
assertQ(req("q", fieldName + ":{" + Double.NEGATIVE_INFINITY + " TO " + Double.NEGATIVE_INFINITY + "]", "fl", "id, " + fieldName),
"//*[@numFound='0']");
assertQ(req("q", fieldName + ":[" + Double.POSITIVE_INFINITY + " TO " + Double.POSITIVE_INFINITY + "}", "fl", "id, " + fieldName),
"//*[@numFound='0']");
} else {
assertQ(req("q", fieldName + ":[" + Float.MIN_VALUE + " TO " + Float.MIN_VALUE + "}", "fl", "id, " + fieldName),
"//*[@numFound='0']");
assertQ(req("q", fieldName + ":{" + Float.MAX_VALUE + " TO " + Float.MAX_VALUE + "]", "fl", "id, " + fieldName),
"//*[@numFound='0']");
assertQ(req("q", fieldName + ":{" + Float.NEGATIVE_INFINITY + " TO " + Float.NEGATIVE_INFINITY + "]", "fl", "id, " + fieldName),
"//*[@numFound='0']");
assertQ(req("q", fieldName + ":[" + Float.POSITIVE_INFINITY + " TO " + Float.POSITIVE_INFINITY + "}", "fl", "id, " + fieldName),
"//*[@numFound='0']");
}
}
private void doTestFloatPointFunctionQuery(String field) throws Exception {
@ -3487,7 +3535,13 @@ public class TestPointFields extends SolrTestCaseJ4 {
ascNegXpathChecks);
clearIndex();
assertU(adoc("id", "1", field, "1995-12-31T10:59:59Z"));
assertU(adoc("id", "2", field, "1996-12-31T10:59:59Z"));
assertU(commit());
assertQ(req("q", field + ":[* TO *]", "fl", "id, " + field),
"//*[@numFound='2']");
assertQ(req("q", field + ":{* TO *}", "fl", "id, " + field),
"//*[@numFound='2']");
}
private void doTestDatePointStats(String field, String dvField, String[] dates) {