From 72d2fd0da079cee9f6e9b7e2dd9fe5733b539d8a Mon Sep 17 00:00:00 2001 From: Shay Banon Date: Wed, 16 Nov 2011 14:15:29 +0200 Subject: [PATCH] Inner queries not resolved correctly in has_child filter when searching directly against the parent type (in the URI for example), closes #1471. --- .../index/query/HasChildFilterParser.java | 3 ++ .../index/query/HasChildQueryParser.java | 3 ++ .../index/query/QueryParseContext.java | 30 ++++++++++++++----- .../search/internal/SearchContext.java | 3 ++ 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/HasChildFilterParser.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/HasChildFilterParser.java index 673c5735b24..6815a8fb1fb 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/HasChildFilterParser.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/HasChildFilterParser.java @@ -59,9 +59,12 @@ public class HasChildFilterParser implements FilterParser { if (token == XContentParser.Token.FIELD_NAME) { currentFieldName = parser.currentName(); } else if (token == XContentParser.Token.START_OBJECT) { + // since we switch types, make sure we change the context + String[] origTypes = QueryParseContext.setTypesWithPrevious(childType == null ? null : new String[]{childType}); if ("query".equals(currentFieldName)) { query = parseContext.parseInnerQuery(); } + QueryParseContext.setTypes(origTypes); } else if (token.isValue()) { if ("type".equals(currentFieldName)) { childType = parser.text(); diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/HasChildQueryParser.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/HasChildQueryParser.java index aed97db14c6..6e537c582bd 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/HasChildQueryParser.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/HasChildQueryParser.java @@ -59,9 +59,12 @@ public class HasChildQueryParser implements QueryParser { if (token == XContentParser.Token.FIELD_NAME) { currentFieldName = parser.currentName(); } else if (token == XContentParser.Token.START_OBJECT) { + // since we switch types, make sure we change the context + String[] origTypes = QueryParseContext.setTypesWithPrevious(childType == null ? null : new String[]{childType}); if ("query".equals(currentFieldName)) { query = parseContext.parseInnerQuery(); } + QueryParseContext.setTypes(origTypes); } else if (token.isValue()) { if ("type".equals(currentFieldName)) { childType = parser.text(); diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/QueryParseContext.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/QueryParseContext.java index 4b4e382b3dc..1965dfeb361 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/QueryParseContext.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/QueryParseContext.java @@ -40,7 +40,6 @@ import org.elasticsearch.index.mapper.FieldMappers; import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.index.similarity.SimilarityService; import org.elasticsearch.script.ScriptService; -import org.elasticsearch.search.internal.SearchContext; import java.io.IOException; import java.util.Map; @@ -50,6 +49,26 @@ import java.util.Map; */ public class QueryParseContext { + private static ThreadLocal typesContext = new ThreadLocal(); + + public static void setTypes(String[] types) { + typesContext.set(types); + } + + public static String[] getTypes() { + return typesContext.get(); + } + + public static String[] setTypesWithPrevious(String[] types) { + String[] old = typesContext.get(); + setTypes(types); + return old; + } + + public static void removeTypes() { + typesContext.remove(); + } + private final Index index; IndexQueryParserService indexQueryParser; @@ -203,8 +222,7 @@ public class QueryParseContext { } public FieldMapper fieldMapper(String name) { - SearchContext searchContext = SearchContext.current(); - FieldMappers fieldMappers = indexQueryParser.mapperService.smartNameFieldMappers(name, searchContext == null ? null : searchContext.types()); + FieldMappers fieldMappers = indexQueryParser.mapperService.smartNameFieldMappers(name, getTypes()); if (fieldMappers == null) { return null; } @@ -220,12 +238,10 @@ public class QueryParseContext { } public MapperService.SmartNameFieldMappers smartFieldMappers(String name) { - SearchContext searchContext = SearchContext.current(); - return indexQueryParser.mapperService.smartName(name, searchContext == null ? null : searchContext.types()); + return indexQueryParser.mapperService.smartName(name, getTypes()); } public MapperService.SmartNameObjectMapper smartObjectMapper(String name) { - SearchContext searchContext = SearchContext.current(); - return indexQueryParser.mapperService.smartNameObjectMapper(name, searchContext == null ? null : searchContext.types()); + return indexQueryParser.mapperService.smartNameObjectMapper(name, getTypes()); } } diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/search/internal/SearchContext.java b/modules/elasticsearch/src/main/java/org/elasticsearch/search/internal/SearchContext.java index c590e7b7b69..c55bab45115 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/search/internal/SearchContext.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/search/internal/SearchContext.java @@ -39,6 +39,7 @@ import org.elasticsearch.index.mapper.FieldMappers; import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.index.query.IndexQueryParserService; import org.elasticsearch.index.query.ParsedQuery; +import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.search.nested.BlockJoinQuery; import org.elasticsearch.index.service.IndexService; import org.elasticsearch.index.shard.service.IndexShard; @@ -68,10 +69,12 @@ public class SearchContext implements Releasable { public static void setCurrent(SearchContext value) { current.set(value); + QueryParseContext.setTypes(value.types()); } public static void removeCurrent() { current.remove(); + QueryParseContext.removeTypes(); } public static SearchContext current() {