Set spare becore comparing comparator bottom value

The actual documents value was never calculated if setSpare wasn't called
before compareBottom was called on a certain document.

Closes #3309
This commit is contained in:
Simon Willnauer 2013-07-15 15:13:56 +02:00
parent b116097ea5
commit 37edfe060b
2 changed files with 36 additions and 4 deletions

View File

@ -59,11 +59,11 @@ public class StringScriptDataComparator extends FieldComparator<BytesRef> {
private final SearchScript script; private final SearchScript script;
private BytesRef[] values; private BytesRef[] values; // TODO maybe we can preallocate or use a sentinel to prevent the conditionals in compare
private BytesRef bottom; private BytesRef bottom;
private BytesRef spare = new BytesRef(); private final BytesRef spare = new BytesRef();
private int spareDoc = -1; private int spareDoc = -1;
@ -102,10 +102,10 @@ public class StringScriptDataComparator extends FieldComparator<BytesRef> {
@Override @Override
public int compareBottom(int doc) { public int compareBottom(int doc) {
if (bottom == null) { if (bottom == null) {
return -1; return -1;
} }
setSpare(doc);
return bottom.compareTo(spare); return bottom.compareTo(spare);
} }
@ -120,7 +120,6 @@ public class StringScriptDataComparator extends FieldComparator<BytesRef> {
if (spareDoc == doc) { if (spareDoc == doc) {
return; return;
} }
script.setNextDocId(doc); script.setNextDocId(doc);
spare.copyChars(script.run().toString()); spare.copyChars(script.run().toString());
spareDoc = doc; spareDoc = doc;

View File

@ -35,6 +35,8 @@ import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.nullValue;
import org.elasticsearch.search.sort.ScriptSortBuilder;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
@ -335,6 +337,37 @@ public class SimpleSortTests extends AbstractSharedClusterTest {
} }
assertThat(searchResponse.toString(), not(containsString("error"))); assertThat(searchResponse.toString(), not(containsString("error")));
// STRING script
size = 1 + random.nextInt(10);
searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.setSize(size)
.addSort(new ScriptSortBuilder("doc['str_value'].value", "string"))
.execute().actionGet();
assertThat(searchResponse.getHits().getTotalHits(), equalTo(10l));
assertThat(searchResponse.getHits().hits().length, equalTo(size));
for (int i = 0; i < size; i++) {
assertThat(searchResponse.getHits().getAt(i).id(), equalTo(Integer.toString(i)));
assertThat(searchResponse.getHits().getAt(i).sortValues()[0].toString(), equalTo(new String(new char[]{(char) (97 + i), (char) (97 + i)})));
}
size = 1 + random.nextInt(10);
searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.setSize(size)
.addSort("str_value", SortOrder.DESC)
.execute().actionGet();
assertThat(searchResponse.getHits().getTotalHits(), equalTo(10l));
assertThat(searchResponse.getHits().hits().length, equalTo(size));
for (int i = 0; i < size; i++) {
assertThat(searchResponse.getHits().getAt(i).id(), equalTo(Integer.toString(9 - i)));
assertThat(searchResponse.getHits().getAt(i).sortValues()[0].toString(), equalTo(new String(new char[]{(char) (97 + (9 - i)), (char) (97 + (9 - i))})));
}
assertThat(searchResponse.toString(), not(containsString("error")));
// BYTE // BYTE
size = 1 + random.nextInt(10); size = 1 + random.nextInt(10);