Skip to content

Commit dad68c5

Browse files
authored
Avoid precision loss in DocValueFormat.RAW#parseLong (#49063) (#49169)
1 parent aa4d86c commit dad68c5

File tree

2 files changed

+9
-2
lines changed

2 files changed

+9
-2
lines changed

server/src/main/java/org/elasticsearch/search/DocValueFormat.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ public String format(BytesRef value) {
117117

118118
@Override
119119
public long parseLong(String value, boolean roundUp, LongSupplier now) {
120+
try {
121+
// Prefer parsing as a long to avoid losing precision
122+
return Long.parseLong(value);
123+
} catch (NumberFormatException e) {
124+
// retry as a double
125+
}
120126
double d = Double.parseDouble(value);
121127
if (roundUp) {
122128
d = Math.ceil(d);

server/src/test/java/org/elasticsearch/search/DocValueFormatTests.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ public void testGeoTileFormat() {
168168
public void testRawParse() {
169169
assertEquals(-1L, DocValueFormat.RAW.parseLong("-1", randomBoolean(), null));
170170
assertEquals(1L, DocValueFormat.RAW.parseLong("1", randomBoolean(), null));
171+
assertEquals(Long.MAX_VALUE - 2, DocValueFormat.RAW.parseLong(Long.toString(Long.MAX_VALUE - 2), randomBoolean(), null));
171172
// not checking exception messages as they could depend on the JVM
172173
expectThrows(IllegalArgumentException.class, () -> DocValueFormat.RAW.parseLong("", randomBoolean(), null));
173174
expectThrows(IllegalArgumentException.class, () -> DocValueFormat.RAW.parseLong("abc", randomBoolean(), null));
@@ -176,8 +177,8 @@ public void testRawParse() {
176177
assertEquals(1d, DocValueFormat.RAW.parseDouble("1", randomBoolean(), null), 0d);
177178
assertEquals(.5, DocValueFormat.RAW.parseDouble("0.5", randomBoolean(), null), 0d);
178179
// not checking exception messages as they could depend on the JVM
179-
expectThrows(IllegalArgumentException.class, () -> DocValueFormat.RAW.parseLong("", randomBoolean(), null));
180-
expectThrows(IllegalArgumentException.class, () -> DocValueFormat.RAW.parseLong("abc", randomBoolean(), null));
180+
expectThrows(IllegalArgumentException.class, () -> DocValueFormat.RAW.parseDouble("", randomBoolean(), null));
181+
expectThrows(IllegalArgumentException.class, () -> DocValueFormat.RAW.parseDouble("abc", randomBoolean(), null));
181182

182183
assertEquals(new BytesRef("abc"), DocValueFormat.RAW.parseBytesRef("abc"));
183184
}

0 commit comments

Comments
 (0)