Fixed NPE when using `has_parent` or `has_child` filter/query.

The NPE occurred when for an arbitrary segment no parent documents exist for a has_parent filter/query and no child documents exist for a has_child filter/query.

Closes #2297
This commit is contained in:
Martijn van Groningen 2012-09-28 17:06:45 +02:00
parent 2df6b4b0ea
commit 51e69e1a9e
3 changed files with 53 additions and 2 deletions

View File

@ -144,7 +144,11 @@ public abstract class HasChildFilter extends Filter implements ScopePhase.Collec
}
IdReaderTypeCache idReaderTypeCache = searchContext.idCache().reader(reader).type(parentType);
return new ParentDocSet(reader, collectedUids, idReaderTypeCache);
if (idReaderTypeCache != null) {
return new ParentDocSet(reader, collectedUids, idReaderTypeCache);
} else {
return DocIdSet.EMPTY_DOCIDSET;
}
}
public void clear() {

View File

@ -110,7 +110,11 @@ public abstract class HasParentFilter extends Filter implements ScopePhase.Colle
}
IdReaderTypeCache idReaderTypeCache = context.idCache().reader(reader).type(parentType);
return new ChildrenDocSet(reader, parents, idReaderTypeCache);
if (idReaderTypeCache != null) {
return new ChildrenDocSet(reader, parents, idReaderTypeCache);
} else {
return DocIdSet.EMPTY_DOCIDSET;
}
}
public void clear() {

View File

@ -706,6 +706,49 @@ public class SimpleChildQuerySearchTests extends AbstractNodesTests {
assertThat(searchResponse.hits().getAt(0).id(), equalTo("p2"));
}
@Test
public void testHasChildAndHasParentFailWhenSomeSegmentsDontContainAnyParentOrChildDocs() throws Exception {
client.admin().indices().prepareDelete().execute().actionGet();
client.admin().indices().prepareCreate("test").setSettings(
ImmutableSettings.settingsBuilder()
.put("index.number_of_shards", 1)
.put("index.number_of_replicas", 0)
).execute().actionGet();
client.admin().cluster().prepareHealth().setWaitForGreenStatus().execute().actionGet();
client.admin().indices().preparePutMapping("test").setType("child").setSource(
XContentFactory.jsonBuilder()
.startObject()
.startObject("type")
.startObject("_parent")
.field("type", "parent")
.endObject()
. endObject()
.endObject()
).execute().actionGet();
client.prepareIndex("test", "parent", "1").setSource("p_field", 1).execute().actionGet();
client.prepareIndex("test", "child", "1").setParent("1").setSource("c_field", 1).execute().actionGet();
client.admin().indices().prepareFlush("test").execute().actionGet();
client.prepareIndex("test", "type1", "1").setSource("p_field", "p_value1").execute().actionGet();
client.admin().indices().prepareFlush("test").execute().actionGet();
SearchResponse searchResponse = client.prepareSearch("test")
.setQuery(filteredQuery(matchAllQuery(), hasChildFilter("child", matchAllQuery())))
.execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
client.prepareSearch("test")
.setQuery(filteredQuery(matchAllQuery(), hasParentFilter("parent", matchAllQuery())))
.execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
}
@Test
public void testCountApiUsage() throws Exception {
client.admin().indices().prepareDelete().execute().actionGet();