SOLR-10874: Fix AIOOBE caused by FloatPayloadValueSource calling PostingsEnum.nextPosition() more than the given term's frequency in overridden FloatDocValues.floatVal().

This commit is contained in:
Steve Rowe 2017-10-26 14:44:22 -04:00
parent 95b75303c7
commit c440361a17
3 changed files with 42 additions and 3 deletions

View File

@ -70,6 +70,10 @@ Bug Fixes
* SOLR-11326: A bootstrap of a target cluster does not need to download the tlog files from the source cluster
(Amrit Sarkar, Varun Thacker)
* SOLR-10874: Fix AIOOBE caused by FloatPayloadValueSource calling PostingsEnum.nextPosition()
more than the given term's frequency in overridden FloatDocValues.floatVal().
(Michael Kosten, Erik Hatcher, Steve Rowe)
Optimizations
----------------------

View File

@ -64,6 +64,7 @@ public class FloatPayloadValueSource extends ValueSource {
PostingsEnum docs ;
int atDoc;
int lastDocRequested = -1;
float docScore = 0.f;
{ reset(); }
@ -141,6 +142,10 @@ public class FloatPayloadValueSource extends ValueSource {
// out-of-order access.... reset
reset();
}
else if (doc == lastDocRequested) {
return docScore;
}
lastDocRequested = doc;
if (atDoc < doc) {
@ -150,7 +155,8 @@ public class FloatPayloadValueSource extends ValueSource {
if (atDoc > doc) {
// term doesn't match this document... either because we hit the
// end, or because the next doc is after this doc.
return defaultValues.floatVal(doc);
docScore = defaultValues.floatVal(doc);
return docScore;
}
// a match!
@ -172,8 +178,8 @@ public class FloatPayloadValueSource extends ValueSource {
}
}
return (numPayloadsSeen > 0) ? payloadFunction.docScore(doc, indexedField, numPayloadsSeen, currentScore) : defaultValues.floatVal(doc);
docScore = (numPayloadsSeen > 0) ? payloadFunction.docScore(doc, indexedField, numPayloadsSeen, currentScore) : defaultValues.floatVal(doc);
return docScore;
} catch (IOException e) {
throw new RuntimeException("caught exception in function "+description()+" : doc="+doc, e);
}

View File

@ -29,6 +29,7 @@ import org.apache.lucene.search.similarities.Similarity;
import org.apache.lucene.search.similarities.TFIDFSimilarity;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.CommonParams;
import org.junit.BeforeClass;
import org.junit.Test;
@ -503,6 +504,34 @@ public class TestFunctionQuery extends SolrTestCaseJ4 {
assertQ(req("fl","*,score","q", "{!func}payload(vals_dpf,x,0.0,max)"), "//float[@name='score']='37.0'");
assertQ(req("fl","*,score","q", "{!func}payload(vals_dpf,x,0.0,average)"), "//float[@name='score']='26.0'");
assertQ(req("fl","*,score","q", "{!func}payload(vals_dpf,x,0.0,first)"), "//float[@name='score']='22.0'");
// Test with debug
assertQ(req("fl","*,score","q", "{!func}payload(vals_dpf,A)", CommonParams.DEBUG, "true"), "//float[@name='score']='1.0'");
}
@Test
public void testRetrievePayloads() throws Exception {
clearIndex();
int numDocs = 100 + random().nextInt(100);
int numLocations = 1000 + random().nextInt(2000);
for (int docNum = 0 ; docNum < numDocs ; ++docNum) {
StringBuilder amountsBuilder = new StringBuilder();
for (int location = 1 ; location <= numLocations ; ++location) {
String amount = "" + location + '.' + random().nextInt(100);
amountsBuilder.append(location).append('|').append(amount).append(' ');
}
assertU(adoc("id","" + docNum,
"default_amount_f", "" + (10000 + random().nextInt(10000)) + ".0",
"amounts_dpf", amountsBuilder.toString()));
}
assertU(commit());
assertJQ(req("q","*:*",
"fl","id,location:$locationId,amount:$amount",
"sort","$amount asc",
"amount","payload(amounts_dpf,$locationId,default_amount_f)",
"locationId",""+(1+random().nextInt(numLocations)),
"wt","json"),
"/response/numFound==" + numDocs);
}
@Test