Extract the first value in an array when looking at the returned values (#40318)

(cherry picked from commit faf02e0f42a101985619abc0d30753851605e01d)
This commit is contained in:
Andrei Stefan 2019-03-21 21:31:47 +02:00 committed by Andrei Stefan
parent 35fe05308e
commit f9ab9afcc1
3 changed files with 75 additions and 4 deletions

View File

@ -113,6 +113,38 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase {
() -> doWithQuery(() -> esJdbc(), "SELECT int, keyword FROM test", (results) -> {
}));
}
public void testMultiValueFields_InsideObjects_WithMultiValueLeniencyEnabled() throws Exception {
createTestDataForMultiValuesInObjectsTests();
doWithQuery(() -> esWithLeniency(true), "SELECT object.intsubfield, object.textsubfield, object.textsubfield.keyword FROM test",
(results) -> {
results.next();
Object number = results.getObject(1);
Object text = results.getObject(2);
Object keyword = results.getObject(3);
assertEquals(-25, number);
assertEquals("xyz", text);
assertEquals("-25", keyword);
assertFalse(results.next());
});
}
public void testMultiValueFields_InsideObjects_WithMultiValueLeniencyDisabled() throws Exception {
createTestDataForMultiValuesInObjectsTests();
SQLException expected = expectThrows(SQLException.class,
() -> doWithQuery(() -> esWithLeniency(false), "SELECT object.intsubfield, object.textsubfield, object.textsubfield.keyword"
+ " FROM test", (results) -> {
}));
assertTrue(expected.getMessage().contains("Arrays (returned by [object.intsubfield]) are not supported"));
// default has multi value disabled
expected = expectThrows(SQLException.class,
() -> doWithQuery(() -> esJdbc(), "SELECT object.intsubfield, object.textsubfield, object.textsubfield.keyword",
(results) -> {
}));
}
// Byte values testing
public void testGettingValidByteWithoutCasting() throws Exception {
@ -1411,7 +1443,7 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase {
body.accept(updateMapping);
}
updateMapping.endObject().endObject();
request.setJsonEntity(Strings.toString(updateMapping));
client().performRequest(request);
}
@ -1437,6 +1469,43 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase {
builder.array("keyword", stringValues);
});
}
private void createTestDataForMultiValuesInObjectsTests() throws Exception {
createIndex("test");
updateMapping("test", builder -> {
builder.startObject("object")
.startObject("properties")
.startObject("intsubfield").field("type", "integer").endObject()
.startObject("textsubfield")
.field("type", "text")
.startObject("fields").startObject("keyword").field("type", "keyword").endObject().endObject()
.endObject()
.endObject()
.endObject();
builder.startObject("keyword").field("type", "keyword").endObject();
});
Integer[] values = randomArray(3, 15, s -> new Integer[s], () -> Integer.valueOf(randomInt(50)));
// add the minimal value in the middle yet the test will pick it up since the results are sorted
values[2] = Integer.valueOf(-25);
String[] stringValues = new String[values.length];
for (int i = 0; i < values.length; i++) {
stringValues[i] = String.valueOf(values[i]);
}
stringValues[0] = "xyz";
index("test", "1", builder -> {
builder.startArray("object");
for (int i = 0; i < values.length; i++) {
builder.startObject()
.field("intsubfield", values[i])
.field("textsubfield", stringValues[i])
.endObject();
}
builder.endArray();
});
}
private void createTestDataForByteValueTests(byte random1, byte random2, byte random3) throws Exception {
createIndex("test");

View File

@ -173,9 +173,10 @@ public class FieldHitExtractor implements HitExtractor {
if (node instanceof List) {
List listOfValues = (List) node;
if (listOfValues.size() == 1) {
if (listOfValues.size() == 1 || arrayLeniency) {
// this is a List with a size of 1 e.g.: {"a" : [{"b" : "value"}]} meaning the JSON is a list with one element
// or a list of values with one element e.g.: {"a": {"b" : ["value"]}}
// in case of being lenient about arrays, just extract the first value in the array
node = listOfValues.get(0);
} else {
// a List of elements with more than one value. Break early and let unwrapMultiValue deal with the list

View File

@ -295,7 +295,8 @@ public class FieldHitExtractorTests extends AbstractWireSerializingTestCase<Fiel
path[i] = randomAlphaOfLength(randomIntBetween(1, 10));
sj.add(path[i]);
}
FieldHitExtractor fe = getFieldHitExtractor(sj.toString(), false);
boolean arrayLeniency = randomBoolean();
FieldHitExtractor fe = new FieldHitExtractor(sj.toString(), null, UTC, false, arrayLeniency);
List<String> paths = new ArrayList<>(path.length);
int start = 0;
@ -336,7 +337,7 @@ public class FieldHitExtractorTests extends AbstractWireSerializingTestCase<Fiel
expected.insert(0, paths.get(i) + ".");
}
if (valuesCount == 1) {
if (valuesCount == 1 || arrayLeniency) {
// if the number of generated values is 1, just check we return the correct value
assertEquals(value instanceof List ? ((List) value).get(0) : value, fe.extractFromSource(map));
} else {