Source filtering should keep working when the source contains numbers greater than `Long.MAX_VALUE`. #20278
Currently it does not because our parsers do not support big integers/decimals (on purpose) but we do not have to ask our parser for the number type, we can just ask the jackson parser for a number representation of the value with the right type. Note that I did not add similar tests for big decimals because Jackson seems to never return big decimals, even for decimal values that are out of the range of values that can be represented by doubles. Closes #11508
This commit is contained in:
parent
e5bf02b155
commit
5bfab76c96
|
@ -300,16 +300,7 @@ public abstract class AbstractXContentParser implements XContentParser {
|
|||
} else if (token == XContentParser.Token.VALUE_STRING) {
|
||||
return parser.text();
|
||||
} else if (token == XContentParser.Token.VALUE_NUMBER) {
|
||||
XContentParser.NumberType numberType = parser.numberType();
|
||||
if (numberType == XContentParser.NumberType.INT) {
|
||||
return parser.intValue();
|
||||
} else if (numberType == XContentParser.NumberType.LONG) {
|
||||
return parser.longValue();
|
||||
} else if (numberType == XContentParser.NumberType.FLOAT) {
|
||||
return parser.floatValue();
|
||||
} else if (numberType == XContentParser.NumberType.DOUBLE) {
|
||||
return parser.doubleValue();
|
||||
}
|
||||
return parser.numberValue();
|
||||
} else if (token == XContentParser.Token.VALUE_BOOLEAN) {
|
||||
return parser.booleanValue();
|
||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
|
|
|
@ -19,13 +19,19 @@
|
|||
|
||||
package org.elasticsearch.common.xcontent;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
|
||||
import org.elasticsearch.common.bytes.BytesArray;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.xcontent.XContentParser.Token;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class BaseXContentTestCase extends ESTestCase {
|
||||
|
||||
|
@ -156,4 +162,24 @@ public abstract class BaseXContentTestCase extends ESTestCase {
|
|||
assertNull(parser.nextToken());
|
||||
|
||||
}
|
||||
|
||||
protected void doTestBigInteger(JsonGenerator generator, ByteArrayOutputStream os) throws Exception {
|
||||
// Big integers cannot be handled explicitly, but if some values happen to be big ints,
|
||||
// we can still call parser.map() and get the bigint value so that eg. source filtering
|
||||
// keeps working
|
||||
BigInteger bigInteger = BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE);
|
||||
generator.writeStartObject();
|
||||
generator.writeFieldName("foo");
|
||||
generator.writeString("bar");
|
||||
generator.writeFieldName("bigint");
|
||||
generator.writeNumber(bigInteger);
|
||||
generator.writeEndObject();
|
||||
generator.flush();
|
||||
byte[] serialized = os.toByteArray();
|
||||
|
||||
XContentParser parser = xcontentType().xContent().createParser(serialized);
|
||||
Map<String, Object> map = parser.map();
|
||||
assertEquals("bar", map.get("foo"));
|
||||
assertEquals(bigInteger, map.get("bigint"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,9 +19,14 @@
|
|||
|
||||
package org.elasticsearch.common.xcontent.cbor;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
|
||||
|
||||
import org.elasticsearch.common.xcontent.BaseXContentTestCase;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
public class CborXContentTests extends BaseXContentTestCase {
|
||||
|
||||
@Override
|
||||
|
@ -29,4 +34,9 @@ public class CborXContentTests extends BaseXContentTestCase {
|
|||
return XContentType.CBOR;
|
||||
}
|
||||
|
||||
public void testBigInteger() throws Exception {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
JsonGenerator generator = new CBORFactory().createGenerator(os);
|
||||
doTestBigInteger(generator, os);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,9 +19,14 @@
|
|||
|
||||
package org.elasticsearch.common.xcontent.json;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
|
||||
import org.elasticsearch.common.xcontent.BaseXContentTestCase;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
public class JsonXContentTests extends BaseXContentTestCase {
|
||||
|
||||
@Override
|
||||
|
@ -29,4 +34,9 @@ public class JsonXContentTests extends BaseXContentTestCase {
|
|||
return XContentType.JSON;
|
||||
}
|
||||
|
||||
public void testBigInteger() throws Exception {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
JsonGenerator generator = new JsonFactory().createGenerator(os);
|
||||
doTestBigInteger(generator, os);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,9 +19,14 @@
|
|||
|
||||
package org.elasticsearch.common.xcontent.smile;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.dataformat.smile.SmileFactory;
|
||||
|
||||
import org.elasticsearch.common.xcontent.BaseXContentTestCase;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
public class SmileXContentTests extends BaseXContentTestCase {
|
||||
|
||||
@Override
|
||||
|
@ -29,4 +34,9 @@ public class SmileXContentTests extends BaseXContentTestCase {
|
|||
return XContentType.SMILE;
|
||||
}
|
||||
|
||||
public void testBigInteger() throws Exception {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
JsonGenerator generator = new SmileFactory().createGenerator(os);
|
||||
doTestBigInteger(generator, os);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,9 +19,14 @@
|
|||
|
||||
package org.elasticsearch.common.xcontent.yaml;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||
|
||||
import org.elasticsearch.common.xcontent.BaseXContentTestCase;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
public class YamlXContentTests extends BaseXContentTestCase {
|
||||
|
||||
@Override
|
||||
|
@ -29,4 +34,9 @@ public class YamlXContentTests extends BaseXContentTestCase {
|
|||
return XContentType.YAML;
|
||||
}
|
||||
|
||||
public void testBigInteger() throws Exception {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
JsonGenerator generator = new YAMLFactory().createGenerator(os);
|
||||
doTestBigInteger(generator, os);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,22 @@
|
|||
---
|
||||
setup:
|
||||
- do:
|
||||
indices.create:
|
||||
index: test
|
||||
body:
|
||||
mappings:
|
||||
test:
|
||||
properties:
|
||||
bigint:
|
||||
type: keyword
|
||||
|
||||
|
||||
- do:
|
||||
index:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body: { "include": { "field1": "v1", "field2": "v2" }, "count": 1 }
|
||||
body: { "include": { "field1": "v1", "field2": "v2" }, "count": 1, "bigint": 72057594037927936 }
|
||||
- do:
|
||||
indices.refresh: {}
|
||||
|
||||
|
@ -90,6 +101,17 @@ setup:
|
|||
- match: { hits.hits.0._source.include.field1: v1 }
|
||||
- is_false: hits.hits.0._source.include.field2
|
||||
|
||||
---
|
||||
"_source include on bigint":
|
||||
- do:
|
||||
search:
|
||||
body:
|
||||
_source:
|
||||
includes: bigint
|
||||
query: { match_all: {} }
|
||||
- match: { hits.hits.0._source.bigint: 72057594037927936 }
|
||||
- is_false: hits.hits.0._source.include.field2
|
||||
|
||||
---
|
||||
"fields in body":
|
||||
- do:
|
||||
|
|
Loading…
Reference in New Issue