SQL: cover the Integer type when extracting values from _source (#42859)

* Take into consideration a wider range of Numbers when extracting the
values from source, more specifically - BigInteger and BigDecimal.

(cherry picked from commit 561b8d73dd7b03c50242e4e3f0128b2142959176)
This commit is contained in:
Andrei Stefan 2019-06-10 09:01:42 +03:00 committed by Andrei Stefan
parent 90485c6028
commit 036f9c4a55
2 changed files with 27 additions and 5 deletions

View File

@ -165,7 +165,11 @@ public class FieldHitExtractor implements HitExtractor {
return DateUtils.asDateTime(Long.parseLong(values.toString()), zoneId); return DateUtils.asDateTime(Long.parseLong(values.toString()), zoneId);
} }
} }
if (values instanceof Long || values instanceof Double || values instanceof String || values instanceof Boolean) { // The Jackson json parser can generate for numerics - Integers, Longs, BigIntegers (if Long is not enough)
// and BigDecimal (if Double is not enough)
if (values instanceof Number
|| values instanceof String
|| values instanceof Boolean) {
return values; return values;
} }
throw new SqlIllegalArgumentException("Type {} (returned by [{}]) is not supported", values.getClass().getSimpleName(), fieldName); throw new SqlIllegalArgumentException("Type {} (returned by [{}]) is not supported", values.getClass().getSimpleName(), fieldName);

View File

@ -19,6 +19,8 @@ import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.sql.util.DateUtils; import org.elasticsearch.xpack.sql.util.DateUtils;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -127,7 +129,7 @@ public class FieldHitExtractorTests extends AbstractWireSerializingTestCase<Fiel
BytesReference sourceRef = BytesReference.bytes(source); BytesReference sourceRef = BytesReference.bytes(source);
hit.sourceRef(sourceRef); hit.sourceRef(sourceRef);
Object extract = extractor.extract(hit); Object extract = extractor.extract(hit);
assertEquals(hasSource ? value : null, extract); assertFieldHitEquals(hasSource ? value : null, extract);
} }
} }
@ -180,7 +182,7 @@ public class FieldHitExtractorTests extends AbstractWireSerializingTestCase<Fiel
source.endObject(); source.endObject();
BytesReference sourceRef = BytesReference.bytes(source); BytesReference sourceRef = BytesReference.bytes(source);
hit.sourceRef(sourceRef); hit.sourceRef(sourceRef);
assertEquals(value, extractor.extract(hit)); assertFieldHitEquals(value, extractor.extract(hit));
} }
} }
@ -226,7 +228,7 @@ public class FieldHitExtractorTests extends AbstractWireSerializingTestCase<Fiel
source.endObject(); source.endObject();
BytesReference sourceRef = BytesReference.bytes(source); BytesReference sourceRef = BytesReference.bytes(source);
hit.sourceRef(sourceRef); hit.sourceRef(sourceRef);
assertEquals(value, fe.extract(hit)); assertFieldHitEquals(value, fe.extract(hit));
} }
public void testExtractSourcePath() { public void testExtractSourcePath() {
@ -580,6 +582,9 @@ public class FieldHitExtractorTests extends AbstractWireSerializingTestCase<Fiel
() -> randomAlphaOfLength(10), () -> randomAlphaOfLength(10),
ESTestCase::randomLong, ESTestCase::randomLong,
ESTestCase::randomDouble, ESTestCase::randomDouble,
ESTestCase::randomInt,
() -> BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE),
() -> new BigDecimal("20012312345621343256123456254.20012312345621343256123456254"),
() -> null)); () -> null));
return value.get(); return value.get();
} }
@ -588,10 +593,23 @@ public class FieldHitExtractorTests extends AbstractWireSerializingTestCase<Fiel
Supplier<Object> value = randomFrom(Arrays.asList( Supplier<Object> value = randomFrom(Arrays.asList(
() -> randomAlphaOfLength(10), () -> randomAlphaOfLength(10),
ESTestCase::randomLong, ESTestCase::randomLong,
ESTestCase::randomDouble)); ESTestCase::randomDouble,
ESTestCase::randomInt,
() -> BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE),
() -> new BigDecimal("20012312345621343256123456254.20012312345621343256123456254")));
return value.get(); return value.get();
} }
private void assertFieldHitEquals(Object expected, Object actual) {
if (expected instanceof BigDecimal) {
// parsing will, by default, build a Double even if the initial value is BigDecimal
// Elasticsearch does this the same when returning the results
assertEquals(((BigDecimal) expected).doubleValue(), actual);
} else {
assertEquals(expected, actual);
}
}
private Object randomPoint(double lat, double lon) { private Object randomPoint(double lat, double lon) {
Supplier<Object> value = randomFrom(Arrays.asList( Supplier<Object> value = randomFrom(Arrays.asList(
() -> lat + "," + lon, () -> lat + "," + lon,