Range/Term query/filter on dates fail to handle numbers properly

When providing a number (milliseconds since epoch, UTC), range and term query/filter don't handle it correctly and convert it to a string, that is then first tried to parse as a date
closes #5969
This commit is contained in:
Shay Banon 2014-04-29 08:41:01 +02:00
parent fb53784e3b
commit a4ef418e6e
2 changed files with 44 additions and 12 deletions

View File

@ -301,6 +301,9 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
} }
public long parseToMilliseconds(Object value, @Nullable QueryParseContext context, boolean includeUpper) { public long parseToMilliseconds(Object value, @Nullable QueryParseContext context, boolean includeUpper) {
if (value instanceof Number) {
return ((Number) value).longValue();
}
long now = context == null ? System.currentTimeMillis() : context.nowInMillis(); long now = context == null ? System.currentTimeMillis() : context.nowInMillis();
return includeUpper && roundCeil ? dateMathParser.parseRoundCeil(convertToString(value), now) : dateMathParser.parse(convertToString(value), now); return includeUpper && roundCeil ? dateMathParser.parseRoundCeil(convertToString(value), now) : dateMathParser.parse(convertToString(value), now);
} }
@ -335,15 +338,23 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
Long lowerVal = null; Long lowerVal = null;
Long upperVal = null; Long upperVal = null;
if (lowerTerm != null) { if (lowerTerm != null) {
if (lowerTerm instanceof Number) {
lowerVal = ((Number) lowerTerm).longValue();
} else {
String value = convertToString(lowerTerm); String value = convertToString(lowerTerm);
cache = explicitCaching || !hasNowExpressionWithNoRounding(value); cache = explicitCaching || !hasNowExpressionWithNoRounding(value);
lowerVal = parseToMilliseconds(value, context, false); lowerVal = parseToMilliseconds(value, context, false);
} }
}
if (upperTerm != null) { if (upperTerm != null) {
if (upperTerm instanceof Number) {
upperVal = ((Number) upperTerm).longValue();
} else {
String value = convertToString(upperTerm); String value = convertToString(upperTerm);
cache = explicitCaching || !hasNowExpressionWithNoRounding(value); cache = explicitCaching || !hasNowExpressionWithNoRounding(value);
upperVal = parseToMilliseconds(value, context, includeUpper); upperVal = parseToMilliseconds(value, context, includeUpper);
} }
}
Filter filter = NumericRangeFilter.newLongRange( Filter filter = NumericRangeFilter.newLongRange(
names.indexName(), precisionStep, lowerVal, upperVal, includeLower, includeUpper names.indexName(), precisionStep, lowerVal, upperVal, includeLower, includeUpper
@ -367,15 +378,23 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
Long lowerVal = null; Long lowerVal = null;
Long upperVal = null; Long upperVal = null;
if (lowerTerm != null) { if (lowerTerm != null) {
if (lowerTerm instanceof Number) {
lowerVal = ((Number) lowerTerm).longValue();
} else {
String value = convertToString(lowerTerm); String value = convertToString(lowerTerm);
cache = explicitCaching || !hasNowExpressionWithNoRounding(value); cache = explicitCaching || !hasNowExpressionWithNoRounding(value);
lowerVal = parseToMilliseconds(value, context, false); lowerVal = parseToMilliseconds(value, context, false);
} }
}
if (upperTerm != null) { if (upperTerm != null) {
if (upperTerm instanceof Number) {
upperVal = ((Number) upperTerm).longValue();
} else {
String value = convertToString(upperTerm); String value = convertToString(upperTerm);
cache = explicitCaching || !hasNowExpressionWithNoRounding(value); cache = explicitCaching || !hasNowExpressionWithNoRounding(value);
upperVal = parseToMilliseconds(value, context, includeUpper); upperVal = parseToMilliseconds(value, context, includeUpper);
} }
}
Filter filter = NumericRangeFieldDataFilter.newLongRange( Filter filter = NumericRangeFieldDataFilter.newLongRange(
(IndexNumericFieldData<?>) fieldData.getForField(this), lowerVal,upperVal, includeLower, includeUpper (IndexNumericFieldData<?>) fieldData.getForField(this), lowerVal,upperVal, includeLower, includeUpper

View File

@ -2155,6 +2155,19 @@ public class SimpleQueryTests extends ElasticsearchIntegrationTest {
assertSearchHits(searchResponse, "1"); assertSearchHits(searchResponse, "1");
} }
@Test
public void testDateProvidedAsNumber() {
createIndex("test");
assertAcked(client().admin().indices().preparePutMapping("test").setType("type").setSource("field", "type=date").get());
client().prepareIndex("test", "type", "1").setSource("field", -1000000000001L).get();
client().prepareIndex("test", "type", "2").setSource("field", -1000000000000L).get();
client().prepareIndex("test", "type", "3").setSource("field", -999999999999L).get();
refresh();
assertHitCount(client().prepareCount("test").setQuery(rangeQuery("field").lte(-1000000000000L)).get(), 2);
assertHitCount(client().prepareCount("test").setQuery(rangeQuery("field").lte(-999999999999L)).get(), 3);
}
@Test @Test
public void testRangeFilterNoCacheWithNow() throws Exception { public void testRangeFilterNoCacheWithNow() throws Exception {
assertAcked(prepareCreate("test") assertAcked(prepareCreate("test")