SOLR-11073: Fix overflow in interval faceting when querying Long limits

This commit is contained in:
Tomas Fernandez Lobbe 2017-07-14 17:27:11 -07:00
parent e23ac243ef
commit 3bd1115964
3 changed files with 42 additions and 7 deletions

View File

@ -354,6 +354,9 @@ Bug Fixes
* SOLR-11043: Fix facet.range.method=dv and interval facets on single-valued float fields with negative values.
(Tomás Fernández Löbbe, Steve Rowe)
* 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)
Optimizations
----------------------

View File

@ -439,12 +439,12 @@ public class IntervalFacets implements Iterable<FacetInterval> {
INCLUDED,
GREATER_THAN_END,
}
/**
* Helper class to match and count of documents in specified intervals
*/
public static class FacetInterval {
/**
* Key to represent this interval
*/
@ -504,6 +504,11 @@ public class IntervalFacets implements Iterable<FacetInterval> {
* The current count of documents in that match this interval
*/
private int count;
/**
* If this field is set to true, this interval {@code #getCount()} will always return 0.
*/
private boolean includeNoDocs = false;
/**
*
@ -646,7 +651,14 @@ public class IntervalFacets implements Iterable<FacetInterval> {
throw new AssertionError();
}
if (startOpen) {
startLimit++;
if (startLimit == Long.MAX_VALUE) {
/*
* This interval can match no docs
*/
includeNoDocs = true;
} else {
startLimit++;
}
}
}
@ -674,7 +686,14 @@ public class IntervalFacets implements Iterable<FacetInterval> {
throw new AssertionError();
}
if (endOpen) {
endLimit--;
if (endLimit == Long.MIN_VALUE) {
/*
* This interval can match no docs
*/
includeNoDocs = true;
} else {
endLimit--;
}
}
}
}
@ -882,6 +901,9 @@ public class IntervalFacets implements Iterable<FacetInterval> {
* @return The count of document that matched this interval
*/
public int getCount() {
if (includeNoDocs) {
return 0;
}
return this.count;
}
@ -906,7 +928,6 @@ public class IntervalFacets implements Iterable<FacetInterval> {
*/
@Override
public Iterator<FacetInterval> iterator() {
return new ArrayList<FacetInterval>(Arrays.asList(intervals)).iterator();
}

View File

@ -664,11 +664,19 @@ public class TestIntervalFaceting extends SolrTestCaseJ4 {
assertU(adoc("id", "12", "test_l_dv", String.valueOf(Long.MAX_VALUE - 3)));
assertU(adoc("id", "13", "test_l_dv", String.valueOf(Long.MAX_VALUE - 2)));
assertU(adoc("id", "14", "test_l_dv", String.valueOf(Long.MAX_VALUE - 1)));
assertU(adoc("id", "15", "test_l_dv", String.valueOf(Long.MAX_VALUE)));
assertU(adoc("id", "16", "test_l_dv", String.valueOf(Long.MIN_VALUE)));
assertU(commit());
assertIntervalQuery("test_l_dv", "[0," + Integer.MAX_VALUE + "]", "10");
assertIntervalQuery("test_l_dv", "[" + Integer.MAX_VALUE + "," + Long.MAX_VALUE + "]", "3");
assertIntervalQuery("test_l_dv", "[" + Integer.MAX_VALUE + ",*]", "3");
assertIntervalQuery("test_l_dv", "(10," + Long.MAX_VALUE + "]", "4");
assertIntervalQuery("test_l_dv", "[" + Long.MAX_VALUE + "," + Long.MAX_VALUE + "]", "1");
assertIntervalQuery("test_l_dv", "[" + Long.MAX_VALUE + ",*]", "1");
assertIntervalQuery("test_l_dv", "(" + Long.MAX_VALUE + ",*]", "0");
assertIntervalQuery("test_l_dv", "(*, " + Long.MIN_VALUE + "]", "1");
assertIntervalQuery("test_l_dv", "(*, " + Long.MIN_VALUE + ")", "0");
assertIntervalQuery("test_l_dv", "(" + (Long.MAX_VALUE - 1) + ",*]", "1");
assertIntervalQuery("test_l_dv", "[" + (Long.MAX_VALUE - 1) + ",*]", "2");
}
@Test
@ -732,6 +740,9 @@ public class TestIntervalFaceting extends SolrTestCaseJ4 {
assertIntervalQuery(field, "(0, " + Float.MAX_VALUE + "]", "2");
assertIntervalQuery(field, "(0, " + Float.POSITIVE_INFINITY + ")", "2");
assertIntervalQuery(field, "(0, " + Float.POSITIVE_INFINITY + "]", "3");
assertIntervalQuery(field, "[-0.0, 0.0]", "2");
assertIntervalQuery(field, "[-0.0, 0.0)", "1");
assertIntervalQuery(field, "(-0.0, 0.0]", "1");
if (testDouble) {
clearIndex();