SQL: fix object extraction from sources (#37502)

Throws an exception if hit extractor tries to retrieve unsupported
object. For example, selecting "a" from `{"a": {"b": "c"}}` now throws
an exception instead of returning null.

Relates to #37364
This commit is contained in:
Igor Motov 2019-01-18 14:03:48 -05:00 committed by GitHub
parent 633bd09be0
commit 54af8a4e7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 2 deletions

View File

@ -166,8 +166,14 @@ public class FieldHitExtractor implements HitExtractor {
sj.add(path[i]); sj.add(path[i]);
Object node = subMap.get(sj.toString()); Object node = subMap.get(sj.toString());
if (node instanceof Map) { if (node instanceof Map) {
if (i < path.length - 1) {
// Add the sub-map to the queue along with the current path index // Add the sub-map to the queue along with the current path index
queue.add(new Tuple<>(i, (Map<String, Object>) node)); queue.add(new Tuple<>(i, (Map<String, Object>) node));
} else {
// We exhausted the path and got a map
// If it is an object - it will be handled in the value extractor
value = node;
}
} else if (node != null) { } else if (node != null) {
if (i < path.length - 1) { if (i < path.length - 1) {
// If we reach a concrete value without exhausting the full path, something is wrong with the mapping // If we reach a concrete value without exhausting the full path, something is wrong with the mapping

View File

@ -336,6 +336,24 @@ public class FieldHitExtractorTests extends AbstractWireSerializingTestCase<Fiel
assertThat(ex.getMessage(), is("Multiple values (returned by [a.b.c.d.e.f.g]) are not supported")); assertThat(ex.getMessage(), is("Multiple values (returned by [a.b.c.d.e.f.g]) are not supported"));
} }
public void testObjectsForSourceValue() throws IOException {
String fieldName = randomAlphaOfLength(5);
FieldHitExtractor fe = new FieldHitExtractor(fieldName, null, false);
SearchHit hit = new SearchHit(1);
XContentBuilder source = JsonXContent.contentBuilder();
source.startObject(); {
source.startObject(fieldName); {
source.field("b", "c");
}
source.endObject();
}
source.endObject();
BytesReference sourceRef = BytesReference.bytes(source);
hit.sourceRef(sourceRef);
SqlException ex = expectThrows(SqlException.class, () -> fe.extract(hit));
assertThat(ex.getMessage(), is("Objects (returned by [" + fieldName + "]) are not supported"));
}
private Object randomValue() { private Object randomValue() {
Supplier<Object> value = randomFrom(Arrays.asList( Supplier<Object> value = randomFrom(Arrays.asList(
() -> randomAlphaOfLength(10), () -> randomAlphaOfLength(10),