Skip to content

Commit

Permalink
Dates accessed from scripts should use UTC timezone
Browse files Browse the repository at this point in the history
this was broken in the field data refactoring we did in 0.90, fixes #3091
  • Loading branch information
kimchy committed May 25, 2013
1 parent d053dca commit 1c9d939
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 83 deletions.
Expand Up @@ -24,7 +24,7 @@
/**
*/
public abstract class AtomicNumericFieldData implements AtomicFieldData<ScriptDocValues> {

private boolean isFloat;

public AtomicNumericFieldData(boolean isFloat) {
Expand All @@ -39,59 +39,59 @@ public AtomicNumericFieldData(boolean isFloat) {
@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()) {

@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 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 BytesRef next() {
spare.copyChars(Double.toString(iter.next()));
return spare;
}

@Override
public int hash() {
return spare.hashCode();
}

};
}
};
} else {
if (isFloat) {
final DoubleValues values = getDoubleValues();
return new BytesValues(values.isMultiValued()) {

@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 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 BytesRef next() {
spare.copyChars(Double.toString(iter.next()));
return spare;
}

@Override
public int hash() {
return spare.hashCode();
}

};
}
};
} else {
final LongValues values = getLongValues();
return new BytesValues(values.isMultiValued()) {

Expand Down Expand Up @@ -135,7 +135,7 @@ public int hash() {
};
}
};
}
}
}

@Override
Expand Down
Expand Up @@ -19,23 +19,20 @@

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;
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.
Expand All @@ -53,7 +50,7 @@ public void setNextDocId(int docId) {
}

public abstract boolean isEmpty();

public abstract List<?> getValues();

public static class Empty extends ScriptDocValues {
Expand All @@ -68,7 +65,7 @@ public boolean isEmpty() {

@Override
public List<?> getValues() {
return Collections.emptyList();
return Collections.emptyList();
}

}
Expand Down Expand Up @@ -109,15 +106,15 @@ public String getValue() {
}
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();
}
Expand All @@ -129,14 +126,13 @@ public List<String> getValues() {
}



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);
}
Expand All @@ -149,14 +145,14 @@ public boolean isEmpty() {
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;
Expand All @@ -170,12 +166,13 @@ public MutableDateTime getDate() {
}

}
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);

Expand All @@ -189,14 +186,14 @@ public boolean isEmpty() {
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;
Expand All @@ -209,7 +206,7 @@ public static class GeoPoints extends 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]) {
Expand Down Expand Up @@ -250,7 +247,7 @@ public double[] getLats() {
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++) {
Expand All @@ -263,27 +260,27 @@ public double getLon() {
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;
}
listLoaded = true;
}
return list;

}

public double factorDistance(double lat, double lon) {
Expand Down
Expand Up @@ -27,11 +27,13 @@
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;
Expand Down Expand Up @@ -124,6 +126,19 @@ public void testOptimizeTypeLong() throws Exception {
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();
Expand Down

0 comments on commit 1c9d939

Please sign in to comment.