Fix an NPE when requesting inner hits and _source is disabled. (#44836)
This PR makes two changes to FetchSourceSubPhase when _source is disabled and we're in a nested context: * If no source filters are provided, return early to avoid an NPE. * If there are source filters, make sure to throw an exception. The behavior was chosen to match what currently happens in a non-nested context.
This commit is contained in:
parent
6a60fd6d30
commit
acb7f599a3
|
@ -42,17 +42,23 @@ public final class FetchSourceSubPhase implements FetchSubPhase {
|
||||||
SourceLookup source = context.lookup().source();
|
SourceLookup source = context.lookup().source();
|
||||||
FetchSourceContext fetchSourceContext = context.fetchSourceContext();
|
FetchSourceContext fetchSourceContext = context.fetchSourceContext();
|
||||||
assert fetchSourceContext.fetchSource();
|
assert fetchSourceContext.fetchSource();
|
||||||
if (nestedHit == false) {
|
|
||||||
if (fetchSourceContext.includes().length == 0 && fetchSourceContext.excludes().length == 0) {
|
// If source is disabled in the mapping, then attempt to return early.
|
||||||
hitContext.hit().sourceRef(source.internalSourceRef());
|
if (source.source() == null && source.internalSourceRef() == null) {
|
||||||
return;
|
if (containsFilters(fetchSourceContext)) {
|
||||||
}
|
|
||||||
if (source.internalSourceRef() == null) {
|
|
||||||
throw new IllegalArgumentException("unable to fetch fields from _source field: _source is disabled in the mappings " +
|
throw new IllegalArgumentException("unable to fetch fields from _source field: _source is disabled in the mappings " +
|
||||||
"for index [" + context.indexShard().shardId().getIndexName() + "]");
|
"for index [" + context.indexShard().shardId().getIndexName() + "]");
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this is a parent document and there are no source filters, then add the source as-is.
|
||||||
|
if (nestedHit == false && containsFilters(fetchSourceContext) == false) {
|
||||||
|
hitContext.hit().sourceRef(source.internalSourceRef());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, filter the source and add it to the hit.
|
||||||
Object value = source.filter(fetchSourceContext);
|
Object value = source.filter(fetchSourceContext);
|
||||||
if (nestedHit) {
|
if (nestedHit) {
|
||||||
value = getNestedSource((Map<String, Object>) value, hitContext);
|
value = getNestedSource((Map<String, Object>) value, hitContext);
|
||||||
|
@ -79,6 +85,10 @@ public final class FetchSourceSubPhase implements FetchSubPhase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean containsFilters(FetchSourceContext context) {
|
||||||
|
return context.includes().length != 0 || context.excludes().length != 0;
|
||||||
|
}
|
||||||
|
|
||||||
private Map<String, Object> getNestedSource(Map<String, Object> sourceAsMap, HitContext hitContext) {
|
private Map<String, Object> getNestedSource(Map<String, Object> sourceAsMap, HitContext hitContext) {
|
||||||
for (SearchHit.NestedIdentity o = hitContext.hit().getNestedIdentity(); o != null; o = o.getChild()) {
|
for (SearchHit.NestedIdentity o = hitContext.hit().getNestedIdentity(); o != null; o = o.getChild()) {
|
||||||
sourceAsMap = (Map<String, Object>) sourceAsMap.get(o.getField().string());
|
sourceAsMap = (Map<String, Object>) sourceAsMap.get(o.getField().string());
|
||||||
|
|
|
@ -119,6 +119,17 @@ public class FetchSourceSubPhaseTests extends ESTestCase {
|
||||||
"for index [index]", exception.getMessage());
|
"for index [index]", exception.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testNestedSourceWithSourceDisabled() {
|
||||||
|
FetchSubPhase.HitContext hitContext = hitExecute(null, true, null, null,
|
||||||
|
new SearchHit.NestedIdentity("nested1", 0, null));
|
||||||
|
assertNull(hitContext.hit().getSourceAsMap());
|
||||||
|
|
||||||
|
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
|
||||||
|
() -> hitExecute(null, true, "field1", null, new SearchHit.NestedIdentity("nested1", 0, null)));
|
||||||
|
assertEquals("unable to fetch fields from _source field: _source is disabled in the mappings " +
|
||||||
|
"for index [index]", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
private FetchSubPhase.HitContext hitExecute(XContentBuilder source, boolean fetchSource, String include, String exclude) {
|
private FetchSubPhase.HitContext hitExecute(XContentBuilder source, boolean fetchSource, String include, String exclude) {
|
||||||
return hitExecute(source, fetchSource, include, exclude, null);
|
return hitExecute(source, fetchSource, include, exclude, null);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue