Dates accessed from scripts should use UTC timezone
this was broken in the field data refactoring we did in 0.90, fixes #3091
This commit is contained in:
parent
24fccc91d8
commit
b4d75a50bf
|
@ -24,7 +24,7 @@ import org.apache.lucene.util.BytesRef;
|
|||
/**
|
||||
*/
|
||||
public abstract class AtomicNumericFieldData implements AtomicFieldData<ScriptDocValues> {
|
||||
|
||||
|
||||
private boolean isFloat;
|
||||
|
||||
public AtomicNumericFieldData(boolean isFloat) {
|
||||
|
@ -39,59 +39,59 @@ public abstract class AtomicNumericFieldData implements AtomicFieldData<ScriptDo
|
|||
@Override
|
||||
public ScriptDocValues getScriptValues() {
|
||||
if (isFloat) {
|
||||
return new ScriptDocValues.NumericDouble(getDoubleValues());
|
||||
return new ScriptDocValues.Doubles(getDoubleValues());
|
||||
} else {
|
||||
return new ScriptDocValues.NumericLong(getLongValues());
|
||||
return new ScriptDocValues.Longs(getLongValues());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BytesValues getBytesValues() {
|
||||
if (isFloat) {
|
||||
final DoubleValues values = getDoubleValues();
|
||||
return new BytesValues(values.isMultiValued()) {
|
||||
if (isFloat) {
|
||||
final DoubleValues values = getDoubleValues();
|
||||
return new BytesValues(values.isMultiValued()) {
|
||||
|
||||
@Override
|
||||
public boolean hasValue(int docId) {
|
||||
return values.hasValue(docId);
|
||||
}
|
||||
@Override
|
||||
public boolean hasValue(int docId) {
|
||||
return values.hasValue(docId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BytesRef getValueScratch(int docId, BytesRef ret) {
|
||||
if (values.hasValue(docId)) {
|
||||
ret.copyChars(Double.toString(values.getValue(docId)));
|
||||
} else {
|
||||
ret.length = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@Override
|
||||
public BytesRef getValueScratch(int docId, BytesRef ret) {
|
||||
if (values.hasValue(docId)) {
|
||||
ret.copyChars(Double.toString(values.getValue(docId)));
|
||||
} else {
|
||||
ret.length = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iter getIter(int docId) {
|
||||
final DoubleValues.Iter iter = values.getIter(docId);
|
||||
return new BytesValues.Iter() {
|
||||
private final BytesRef spare = new BytesRef();
|
||||
@Override
|
||||
public Iter getIter(int docId) {
|
||||
final DoubleValues.Iter iter = values.getIter(docId);
|
||||
return new BytesValues.Iter() {
|
||||
private final BytesRef spare = new BytesRef();
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return iter.hasNext();
|
||||
}
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return iter.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BytesRef next() {
|
||||
spare.copyChars(Double.toString(iter.next()));
|
||||
return spare;
|
||||
}
|
||||
@Override
|
||||
public BytesRef next() {
|
||||
spare.copyChars(Double.toString(iter.next()));
|
||||
return spare;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hash() {
|
||||
return spare.hashCode();
|
||||
}
|
||||
@Override
|
||||
public int hash() {
|
||||
return spare.hashCode();
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
};
|
||||
} else {
|
||||
};
|
||||
}
|
||||
};
|
||||
} else {
|
||||
final LongValues values = getLongValues();
|
||||
return new BytesValues(values.isMultiValued()) {
|
||||
|
||||
|
@ -135,7 +135,7 @@ public abstract class AtomicNumericFieldData implements AtomicFieldData<ScriptDo
|
|||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,14 +19,7 @@
|
|||
|
||||
package org.elasticsearch.index.fielddata;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.util.ArrayUtil;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.apache.lucene.util.CharsRef;
|
||||
import org.apache.lucene.util.RamUsageEstimator;
|
||||
import org.apache.lucene.util.UnicodeUtil;
|
||||
import org.apache.lucene.util.*;
|
||||
import org.elasticsearch.common.geo.GeoDistance;
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
import org.elasticsearch.common.unit.DistanceUnit;
|
||||
|
@ -34,8 +27,12 @@ import org.elasticsearch.common.util.SlicedDoubleList;
|
|||
import org.elasticsearch.common.util.SlicedLongList;
|
||||
import org.elasticsearch.common.util.SlicedObjectList;
|
||||
import org.elasticsearch.index.fielddata.BytesValues.Iter;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.joda.time.MutableDateTime;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Script level doc values, the assumption is that any implementation will implement a <code>getValue</code>
|
||||
* and a <code>getValues</code> that return the relevant type that then can be used in scripts.
|
||||
|
@ -53,7 +50,7 @@ public abstract class ScriptDocValues {
|
|||
}
|
||||
|
||||
public abstract boolean isEmpty();
|
||||
|
||||
|
||||
public abstract List<?> getValues();
|
||||
|
||||
public static class Empty extends ScriptDocValues {
|
||||
|
@ -68,7 +65,7 @@ public abstract class ScriptDocValues {
|
|||
|
||||
@Override
|
||||
public List<?> getValues() {
|
||||
return Collections.emptyList();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -109,15 +106,15 @@ public abstract class ScriptDocValues {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public List<String> getValues() {
|
||||
if (!listLoaded) {
|
||||
list.offset = 0;
|
||||
list.length = 0;
|
||||
Iter iter = values.getIter(docId);
|
||||
while(iter.hasNext()) {
|
||||
while (iter.hasNext()) {
|
||||
BytesRef next = iter.next();
|
||||
list.grow(list.length+1);
|
||||
list.grow(list.length + 1);
|
||||
UnicodeUtil.UTF8toUTF16(next, spare);
|
||||
list.values[list.length++] = spare.toString();
|
||||
}
|
||||
|
@ -129,14 +126,13 @@ public abstract class ScriptDocValues {
|
|||
}
|
||||
|
||||
|
||||
|
||||
public static class NumericLong extends ScriptDocValues {
|
||||
public static class Longs extends ScriptDocValues {
|
||||
|
||||
private final LongValues values;
|
||||
private final MutableDateTime date = new MutableDateTime(0);
|
||||
private final MutableDateTime date = new MutableDateTime(0, DateTimeZone.UTC);
|
||||
private final SlicedLongList list;
|
||||
|
||||
public NumericLong(LongValues values) {
|
||||
public Longs(LongValues values) {
|
||||
this.values = values;
|
||||
this.list = new SlicedLongList(values.isMultiValued() ? 10 : 1);
|
||||
}
|
||||
|
@ -149,14 +145,14 @@ public abstract class ScriptDocValues {
|
|||
public long getValue() {
|
||||
return values.getValue(docId);
|
||||
}
|
||||
|
||||
|
||||
public List<Long> getValues() {
|
||||
if (!listLoaded) {
|
||||
final LongValues.Iter iter = values.getIter(docId);
|
||||
list.offset = 0;
|
||||
list.length = 0;
|
||||
while(iter.hasNext()) {
|
||||
list.grow(list.length+1);
|
||||
while (iter.hasNext()) {
|
||||
list.grow(list.length + 1);
|
||||
list.values[list.length++] = iter.next();
|
||||
}
|
||||
listLoaded = true;
|
||||
|
@ -170,12 +166,13 @@ public abstract class ScriptDocValues {
|
|||
}
|
||||
|
||||
}
|
||||
public static class NumericDouble extends ScriptDocValues {
|
||||
|
||||
public static class Doubles extends ScriptDocValues {
|
||||
|
||||
private final DoubleValues values;
|
||||
private final SlicedDoubleList list;
|
||||
|
||||
public NumericDouble(DoubleValues values) {
|
||||
|
||||
public Doubles(DoubleValues values) {
|
||||
this.values = values;
|
||||
this.list = new SlicedDoubleList(values.isMultiValued() ? 10 : 1);
|
||||
|
||||
|
@ -189,14 +186,14 @@ public abstract class ScriptDocValues {
|
|||
public double getValue() {
|
||||
return values.getValue(docId);
|
||||
}
|
||||
|
||||
|
||||
public List<Double> getValues() {
|
||||
if (!listLoaded) {
|
||||
final DoubleValues.Iter iter = values.getIter(docId);
|
||||
list.offset = 0;
|
||||
list.length = 0;
|
||||
while(iter.hasNext()) {
|
||||
list.grow(list.length+1);
|
||||
while (iter.hasNext()) {
|
||||
list.grow(list.length + 1);
|
||||
list.values[list.length++] = iter.next();
|
||||
}
|
||||
listLoaded = true;
|
||||
|
@ -209,7 +206,7 @@ public abstract class ScriptDocValues {
|
|||
|
||||
private final GeoPointValues values;
|
||||
private final SlicedObjectList<GeoPoint> list;
|
||||
|
||||
|
||||
public GeoPoints(GeoPointValues values) {
|
||||
this.values = values;
|
||||
list = new SlicedObjectList<GeoPoint>(values.isMultiValued() ? new GeoPoint[10] : new GeoPoint[1]) {
|
||||
|
@ -250,7 +247,7 @@ public abstract class ScriptDocValues {
|
|||
return lats;
|
||||
}
|
||||
|
||||
public double [] getLons() {
|
||||
public double[] getLons() {
|
||||
List<GeoPoint> points = getValues();
|
||||
double[] lons = new double[points.size()];
|
||||
for (int i = 0; i < points.size(); i++) {
|
||||
|
@ -263,19 +260,19 @@ public abstract class ScriptDocValues {
|
|||
return getValue().lon();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public List<GeoPoint> getValues() {
|
||||
if (!listLoaded) {
|
||||
GeoPointValues.Iter iter = values.getIter(docId);
|
||||
list.offset = 0;
|
||||
list.length = 0;
|
||||
while(iter.hasNext()) {
|
||||
while (iter.hasNext()) {
|
||||
int index = list.length;
|
||||
list.grow(index+1);
|
||||
GeoPoint next = iter.next();
|
||||
list.grow(index + 1);
|
||||
GeoPoint next = iter.next();
|
||||
GeoPoint point = list.values[index];
|
||||
if (point == null) {
|
||||
point = list.values[index] = new GeoPoint();
|
||||
point = list.values[index] = new GeoPoint();
|
||||
}
|
||||
point.reset(next.lat(), next.lon());
|
||||
list.values[list.length++] = point;
|
||||
|
@ -283,7 +280,7 @@ public abstract class ScriptDocValues {
|
|||
listLoaded = true;
|
||||
}
|
||||
return list;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public double factorDistance(double lat, double lon) {
|
||||
|
|
|
@ -27,11 +27,13 @@ import org.elasticsearch.common.settings.ImmutableSettings;
|
|||
import org.elasticsearch.index.fielddata.AtomicNumericFieldData;
|
||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
||||
import org.elasticsearch.index.fielddata.ScriptDocValues;
|
||||
import org.elasticsearch.index.fielddata.plain.ByteArrayAtomicFieldData;
|
||||
import org.elasticsearch.index.fielddata.plain.IntArrayAtomicFieldData;
|
||||
import org.elasticsearch.index.fielddata.plain.LongArrayAtomicFieldData;
|
||||
import org.elasticsearch.index.fielddata.plain.ShortArrayAtomicFieldData;
|
||||
import org.elasticsearch.index.mapper.FieldMapper;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
@ -124,6 +126,19 @@ public class LongFieldDataTests extends NumericFieldDataTests {
|
|||
assertThat(fieldData.getLongValues().getValue(1), equalTo((long) Integer.MIN_VALUE - 1l));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDateScripts() throws Exception {
|
||||
fillSingleValueAllSet();
|
||||
IndexNumericFieldData indexFieldData = getForField("value");
|
||||
AtomicNumericFieldData fieldData = indexFieldData.load(refreshReader());
|
||||
|
||||
ScriptDocValues.Longs scriptValues = (ScriptDocValues.Longs) fieldData.getScriptValues();
|
||||
scriptValues.setNextDocId(0);
|
||||
assertThat(scriptValues.getValue(), equalTo(2l));
|
||||
assertThat(scriptValues.getDate().getMillis(), equalTo(2l));
|
||||
assertThat(scriptValues.getDate().getZone(), equalTo(DateTimeZone.UTC));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillSingleValueAllSet() throws Exception {
|
||||
Document d = new Document();
|
||||
|
|
Loading…
Reference in New Issue