diff --git a/server/src/main/java/org/elasticsearch/search/DocValueFormat.java b/server/src/main/java/org/elasticsearch/search/DocValueFormat.java index 3c9e3dc3731..02ce9959bb3 100644 --- a/server/src/main/java/org/elasticsearch/search/DocValueFormat.java +++ b/server/src/main/java/org/elasticsearch/search/DocValueFormat.java @@ -117,6 +117,12 @@ public interface DocValueFormat extends NamedWriteable { @Override public long parseLong(String value, boolean roundUp, LongSupplier now) { + try { + // Prefer parsing as a long to avoid losing precision + return Long.parseLong(value); + } catch (NumberFormatException e) { + // retry as a double + } double d = Double.parseDouble(value); if (roundUp) { d = Math.ceil(d); diff --git a/server/src/test/java/org/elasticsearch/search/DocValueFormatTests.java b/server/src/test/java/org/elasticsearch/search/DocValueFormatTests.java index df948a5bff7..321ec43bb1d 100644 --- a/server/src/test/java/org/elasticsearch/search/DocValueFormatTests.java +++ b/server/src/test/java/org/elasticsearch/search/DocValueFormatTests.java @@ -168,6 +168,7 @@ public class DocValueFormatTests extends ESTestCase { public void testRawParse() { assertEquals(-1L, DocValueFormat.RAW.parseLong("-1", randomBoolean(), null)); assertEquals(1L, DocValueFormat.RAW.parseLong("1", randomBoolean(), null)); + assertEquals(Long.MAX_VALUE - 2, DocValueFormat.RAW.parseLong(Long.toString(Long.MAX_VALUE - 2), randomBoolean(), null)); // not checking exception messages as they could depend on the JVM expectThrows(IllegalArgumentException.class, () -> DocValueFormat.RAW.parseLong("", randomBoolean(), null)); expectThrows(IllegalArgumentException.class, () -> DocValueFormat.RAW.parseLong("abc", randomBoolean(), null)); @@ -176,8 +177,8 @@ public class DocValueFormatTests extends ESTestCase { assertEquals(1d, DocValueFormat.RAW.parseDouble("1", randomBoolean(), null), 0d); assertEquals(.5, DocValueFormat.RAW.parseDouble("0.5", randomBoolean(), null), 0d); // not checking exception messages as they could depend on the JVM - expectThrows(IllegalArgumentException.class, () -> DocValueFormat.RAW.parseLong("", randomBoolean(), null)); - expectThrows(IllegalArgumentException.class, () -> DocValueFormat.RAW.parseLong("abc", randomBoolean(), null)); + expectThrows(IllegalArgumentException.class, () -> DocValueFormat.RAW.parseDouble("", randomBoolean(), null)); + expectThrows(IllegalArgumentException.class, () -> DocValueFormat.RAW.parseDouble("abc", randomBoolean(), null)); assertEquals(new BytesRef("abc"), DocValueFormat.RAW.parseBytesRef("abc")); }