summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Büscher <christoph@elastic.co>2016-04-20 13:19:12 +0200
committerChristoph Büscher <christoph@elastic.co>2016-06-02 11:25:56 +0200
commit359f45988fa5550ff44a0f805fa050eb9a221405 (patch)
tree6facefbd87f2ed55d9f2142b7896d6f65796bf05
parentb2724c0d08267486efc261a30bdb686cb9977f5d (diff)
Handle empty query bodies at parse time and remove EmptyQueryBuilder
Currently we support empty query clauses like the filter in "constant_score" : { "filter" : { } } How these clauses are handled depends on the surrounding query. They later are either ignored, converted to match all or no documents or passed up further in the query hierarchy. During parsing these claues are currently represented as EmptyQueryBuilders. When not handled anywhere else, these special cases need to be checked for on the shard when building the lucene query. This is trappy, so this PR changes the parsing of compound queries. Instead of returning QueryBuilder, the core query parsing method QueryShardContext#parseInnerQueryBuilder() now return an Optional which can be empty in the case of empty query clauses. This has the advantage of forcing callers to deal with this sooner or later. When encountering empty Optionals, compound query builders now have the choice to ignore them, pass them on or rewrite to a different query, depending on context.
-rw-r--r--core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java8
-rw-r--r--core/src/main/java/org/elasticsearch/index/IndexService.java8
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java30
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/BoostingQueryBuilder.java14
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/CommonTermsQueryBuilder.java7
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/ConstantScoreQueryBuilder.java14
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/DisMaxQueryBuilder.java11
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/ExistsQueryBuilder.java5
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/FieldMaskingSpanQueryBuilder.java11
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/FuzzyQueryBuilder.java7
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java5
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/GeoDistanceQueryBuilder.java5
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/GeoDistanceRangeQueryBuilder.java5
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/GeoPolygonQueryBuilder.java5
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java5
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/GeohashCellQuery.java7
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java15
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java13
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/IdsQueryBuilder.java5
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java12
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/InnerHitBuilder.java5
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/MatchAllQueryBuilder.java5
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/MatchNoneQueryBuilder.java5
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/MatchPhrasePrefixQueryBuilder.java5
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/MatchPhraseQueryBuilder.java6
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/MatchQueryBuilder.java5
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java4
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/MultiMatchQueryBuilder.java7
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java14
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/ParentIdQueryBuilder.java5
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/PrefixQueryBuilder.java7
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/QueryParseContext.java22
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/QueryParser.java10
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/QueryStringQueryBuilder.java5
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/RangeQueryBuilder.java5
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/RegexpQueryBuilder.java7
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/ScriptQueryBuilder.java9
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/SimpleQueryStringBuilder.java5
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/SpanContainingQueryBuilder.java17
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/SpanFirstQueryBuilder.java11
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/SpanMultiTermQueryBuilder.java11
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/SpanNearQueryBuilder.java11
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/SpanNotQueryBuilder.java17
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/SpanOrQueryBuilder.java11
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/SpanTermQueryBuilder.java5
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/SpanWithinQueryBuilder.java17
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java9
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/TermQueryBuilder.java5
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java7
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/TypeQueryBuilder.java7
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/WildcardQueryBuilder.java7
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/WrapperQueryBuilder.java8
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilder.java16
-rw-r--r--core/src/main/java/org/elasticsearch/search/SearchModule.java4
-rw-r--r--core/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterAggregationBuilder.java20
-rw-r--r--core/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersAggregationBuilder.java9
-rw-r--r--core/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersAggregator.java7
-rw-r--r--core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsParser.java7
-rw-r--r--core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java6
-rw-r--r--core/src/main/java/org/elasticsearch/search/highlight/AbstractHighlighterBuilder.java2
-rw-r--r--core/src/main/java/org/elasticsearch/search/rescore/QueryRescorerBuilder.java3
-rw-r--r--core/src/main/java/org/elasticsearch/search/sort/FieldSortBuilder.java7
-rw-r--r--core/src/main/java/org/elasticsearch/search/sort/GeoDistanceSortBuilder.java11
-rw-r--r--core/src/main/java/org/elasticsearch/search/sort/ScriptSortBuilder.java7
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggester.java6
-rw-r--r--core/src/test/java/org/elasticsearch/index/query/BoolQueryBuilderTests.java25
-rw-r--r--core/src/test/java/org/elasticsearch/index/query/BoostingQueryBuilderTests.java39
-rw-r--r--core/src/test/java/org/elasticsearch/index/query/ConstantScoreQueryBuilderTests.java25
-rw-r--r--core/src/test/java/org/elasticsearch/index/query/DisMaxQueryBuilderTests.java18
-rw-r--r--core/src/test/java/org/elasticsearch/index/query/HasChildQueryBuilderTests.java41
-rw-r--r--core/src/test/java/org/elasticsearch/index/query/HasParentQueryBuilderTests.java36
-rw-r--r--core/src/test/java/org/elasticsearch/index/query/NestedQueryBuilderTests.java10
-rw-r--r--core/src/test/java/org/elasticsearch/index/query/RandomQueryBuilder.java4
-rw-r--r--core/src/test/java/org/elasticsearch/index/query/TermsQueryBuilderTests.java8
-rw-r--r--core/src/test/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilderTests.java27
-rw-r--r--core/src/test/java/org/elasticsearch/index/query/plugin/CustomQueryParserIT.java22
-rw-r--r--core/src/test/java/org/elasticsearch/index/query/plugin/DummyQueryBuilder.java (renamed from core/src/main/java/org/elasticsearch/index/query/EmptyQueryBuilder.java)59
-rw-r--r--core/src/test/java/org/elasticsearch/index/query/plugin/DummyQueryParserPlugin.java61
-rw-r--r--core/src/test/java/org/elasticsearch/search/aggregations/bucket/FilterIT.java21
-rw-r--r--core/src/test/java/org/elasticsearch/search/aggregations/bucket/FiltersIT.java26
-rw-r--r--core/src/test/java/org/elasticsearch/search/builder/SearchSourceBuilderTests.java24
-rw-r--r--modules/lang-mustache/src/test/java/org/elasticsearch/messy/tests/TemplateQueryParserTests.java12
-rw-r--r--modules/percolator/src/main/java/org/elasticsearch/percolator/PercolateQueryBuilder.java7
-rw-r--r--modules/percolator/src/main/java/org/elasticsearch/percolator/PercolatorFieldMapper.java3
-rw-r--r--modules/percolator/src/main/java/org/elasticsearch/percolator/TransportPercolateAction.java4
-rw-r--r--modules/percolator/src/test/java/org/elasticsearch/percolator/PercolatorFieldMapperTests.java2
-rw-r--r--test/framework/src/main/java/org/elasticsearch/test/AbstractQueryTestCase.java26
87 files changed, 640 insertions, 431 deletions
diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java b/core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java
index 735916504d..647e30cd85 100644
--- a/core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java
+++ b/core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java
@@ -32,6 +32,7 @@ import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.indices.InvalidAliasNameException;
import java.io.IOException;
+import java.util.Optional;
/**
* Validator for an alias, to be used before adding an alias to the index metadata
@@ -141,7 +142,10 @@ public class AliasValidator extends AbstractComponent {
private static void validateAliasFilter(XContentParser parser, QueryShardContext queryShardContext) throws IOException {
QueryParseContext queryParseContext = queryShardContext.newParseContext(parser);
- QueryBuilder queryBuilder = QueryBuilder.rewriteQuery(queryParseContext.parseInnerQueryBuilder(), queryShardContext);
- queryBuilder.toFilter(queryShardContext);
+ Optional<QueryBuilder> parseInnerQueryBuilder = queryParseContext.parseInnerQueryBuilder();
+ if (parseInnerQueryBuilder.isPresent()) {
+ QueryBuilder queryBuilder = QueryBuilder.rewriteQuery(parseInnerQueryBuilder.get(), queryShardContext);
+ queryBuilder.toFilter(queryShardContext);
+ }
}
}
diff --git a/core/src/main/java/org/elasticsearch/index/IndexService.java b/core/src/main/java/org/elasticsearch/index/IndexService.java
index f5e5ce91d8..e2d2ea4b8f 100644
--- a/core/src/main/java/org/elasticsearch/index/IndexService.java
+++ b/core/src/main/java/org/elasticsearch/index/IndexService.java
@@ -51,6 +51,7 @@ import org.elasticsearch.index.fielddata.IndexFieldDataCache;
import org.elasticsearch.index.fielddata.IndexFieldDataService;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.query.ParsedQuery;
+import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.index.shard.IndexEventListener;
import org.elasticsearch.index.shard.IndexSearcherWrapper;
@@ -80,6 +81,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@@ -601,7 +603,11 @@ public final class IndexService extends AbstractIndexComponent implements IndexC
try {
byte[] filterSource = alias.filter().uncompressed();
try (XContentParser parser = XContentFactory.xContent(filterSource).createParser(filterSource)) {
- ParsedQuery parsedFilter = shardContext.toFilter(shardContext.newParseContext(parser).parseInnerQueryBuilder());
+ Optional<QueryBuilder> innerQueryBuilder = shardContext.newParseContext(parser).parseInnerQueryBuilder();
+ ParsedQuery parsedFilter = null;
+ if (innerQueryBuilder.isPresent()) {
+ parsedFilter = shardContext.toFilter(innerQueryBuilder.get());
+ }
return parsedFilter == null ? null : parsedFilter.query();
}
} catch (IOException ex) {
diff --git a/core/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java
index e5aa774add..863bdb25c7 100644
--- a/core/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java
@@ -37,6 +37,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.function.Consumer;
import static org.elasticsearch.common.lucene.search.Queries.fixNegativeQueryIfNeeded;
@@ -300,7 +301,7 @@ public class BoolQueryBuilder extends AbstractQueryBuilder<BoolQueryBuilder> {
builder.endArray();
}
- public static BoolQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException, ParsingException {
+ public static Optional<BoolQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException, ParsingException {
XContentParser parser = parseContext.parser();
boolean disableCoord = BoolQueryBuilder.DISABLE_COORD_DEFAULT;
@@ -316,7 +317,6 @@ public class BoolQueryBuilder extends AbstractQueryBuilder<BoolQueryBuilder> {
String currentFieldName = null;
XContentParser.Token token;
- QueryBuilder query;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
@@ -325,21 +325,17 @@ public class BoolQueryBuilder extends AbstractQueryBuilder<BoolQueryBuilder> {
} else if (token == XContentParser.Token.START_OBJECT) {
switch (currentFieldName) {
case MUST:
- query = parseContext.parseInnerQueryBuilder();
- mustClauses.add(query);
+ parseContext.parseInnerQueryBuilder().ifPresent(mustClauses::add);
break;
case SHOULD:
- query = parseContext.parseInnerQueryBuilder();
- shouldClauses.add(query);
+ parseContext.parseInnerQueryBuilder().ifPresent(shouldClauses::add);
break;
case FILTER:
- query = parseContext.parseInnerQueryBuilder();
- filterClauses.add(query);
+ parseContext.parseInnerQueryBuilder().ifPresent(filterClauses::add);
break;
case MUST_NOT:
case MUSTNOT:
- query = parseContext.parseInnerQueryBuilder();
- mustNotClauses.add(query);
+ parseContext.parseInnerQueryBuilder().ifPresent(mustNotClauses::add);
break;
default:
throw new ParsingException(parser.getTokenLocation(), "[bool] query does not support [" + currentFieldName + "]");
@@ -348,21 +344,17 @@ public class BoolQueryBuilder extends AbstractQueryBuilder<BoolQueryBuilder> {
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
switch (currentFieldName) {
case MUST:
- query = parseContext.parseInnerQueryBuilder();
- mustClauses.add(query);
+ parseContext.parseInnerQueryBuilder().ifPresent(mustClauses::add);
break;
case SHOULD:
- query = parseContext.parseInnerQueryBuilder();
- shouldClauses.add(query);
+ parseContext.parseInnerQueryBuilder().ifPresent(shouldClauses::add);
break;
case FILTER:
- query = parseContext.parseInnerQueryBuilder();
- filterClauses.add(query);
+ parseContext.parseInnerQueryBuilder().ifPresent(filterClauses::add);
break;
case MUST_NOT:
case MUSTNOT:
- query = parseContext.parseInnerQueryBuilder();
- mustNotClauses.add(query);
+ parseContext.parseInnerQueryBuilder().ifPresent(mustNotClauses::add);
break;
default:
throw new ParsingException(parser.getTokenLocation(), "bool query does not support [" + currentFieldName + "]");
@@ -404,7 +396,7 @@ public class BoolQueryBuilder extends AbstractQueryBuilder<BoolQueryBuilder> {
boolQuery.adjustPureNegative(adjustPureNegative);
boolQuery.minimumNumberShouldMatch(minimumShouldMatch);
boolQuery.queryName(queryName);
- return boolQuery;
+ return Optional.of(boolQuery);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/BoostingQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/BoostingQueryBuilder.java
index 496cb7ec8a..3afa4339b5 100644
--- a/core/src/main/java/org/elasticsearch/index/query/BoostingQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/BoostingQueryBuilder.java
@@ -31,6 +31,7 @@ import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
/**
* The BoostingQuery class can be used to effectively demote results that match a given query.
@@ -138,12 +139,12 @@ public class BoostingQueryBuilder extends AbstractQueryBuilder<BoostingQueryBuil
builder.endObject();
}
- public static BoostingQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<BoostingQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
- QueryBuilder positiveQuery = null;
+ Optional<QueryBuilder> positiveQuery = null;
boolean positiveQueryFound = false;
- QueryBuilder negativeQuery = null;
+ Optional<QueryBuilder> negativeQuery = null;
boolean negativeQueryFound = false;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
float negativeBoost = -1;
@@ -187,12 +188,15 @@ public class BoostingQueryBuilder extends AbstractQueryBuilder<BoostingQueryBuil
throw new ParsingException(parser.getTokenLocation(),
"[boosting] query requires 'negative_boost' to be set to be a positive value'");
}
+ if (positiveQuery.isPresent() == false || negativeQuery.isPresent() == false) {
+ return Optional.empty();
+ }
- BoostingQueryBuilder boostingQuery = new BoostingQueryBuilder(positiveQuery, negativeQuery);
+ BoostingQueryBuilder boostingQuery = new BoostingQueryBuilder(positiveQuery.get(), negativeQuery.get());
boostingQuery.negativeBoost(negativeBoost);
boostingQuery.boost(boost);
boostingQuery.queryName(queryName);
- return boostingQuery;
+ return Optional.of(boostingQuery);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/CommonTermsQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/CommonTermsQueryBuilder.java
index f7b35d8dfa..692c157c1b 100644
--- a/core/src/main/java/org/elasticsearch/index/query/CommonTermsQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/CommonTermsQueryBuilder.java
@@ -40,6 +40,7 @@ import org.elasticsearch.index.mapper.MappedFieldType;
import java.io.IOException;
import java.util.Objects;
+import java.util.Optional;
/**
* CommonTermsQuery query is a query that executes high-frequency terms in a
@@ -263,7 +264,7 @@ public class CommonTermsQueryBuilder extends AbstractQueryBuilder<CommonTermsQue
builder.endObject();
}
- public static CommonTermsQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<CommonTermsQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
XContentParser.Token token = parser.nextToken();
if (token != XContentParser.Token.FIELD_NAME) {
@@ -352,7 +353,7 @@ public class CommonTermsQueryBuilder extends AbstractQueryBuilder<CommonTermsQue
if (text == null) {
throw new ParsingException(parser.getTokenLocation(), "No text specified for text query");
}
- return new CommonTermsQueryBuilder(fieldName, text)
+ return Optional.of(new CommonTermsQueryBuilder(fieldName, text)
.lowFreqMinimumShouldMatch(lowFreqMinimumShouldMatch)
.highFreqMinimumShouldMatch(highFreqMinimumShouldMatch)
.analyzer(analyzer)
@@ -361,7 +362,7 @@ public class CommonTermsQueryBuilder extends AbstractQueryBuilder<CommonTermsQue
.disableCoord(disableCoord)
.cutoffFrequency(cutoffFrequency)
.boost(boost)
- .queryName(queryName);
+ .queryName(queryName));
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/ConstantScoreQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/ConstantScoreQueryBuilder.java
index 306a456857..44b4458b57 100644
--- a/core/src/main/java/org/elasticsearch/index/query/ConstantScoreQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/ConstantScoreQueryBuilder.java
@@ -31,6 +31,7 @@ import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
/**
* A query that wraps a filter and simply returns a constant score equal to the
@@ -87,10 +88,10 @@ public class ConstantScoreQueryBuilder extends AbstractQueryBuilder<ConstantScor
builder.endObject();
}
- public static ConstantScoreQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<ConstantScoreQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
- QueryBuilder query = null;
+ Optional<QueryBuilder> query = Optional.empty();
boolean queryFound = false;
String queryName = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
@@ -131,10 +132,15 @@ public class ConstantScoreQueryBuilder extends AbstractQueryBuilder<ConstantScor
throw new ParsingException(parser.getTokenLocation(), "[constant_score] requires a 'filter' element");
}
- ConstantScoreQueryBuilder constantScoreBuilder = new ConstantScoreQueryBuilder(query);
+ if (query.isPresent() == false) {
+ // if inner query is empty, bubble this up to caller so they can decide how to deal with it
+ return Optional.empty();
+ }
+
+ ConstantScoreQueryBuilder constantScoreBuilder = new ConstantScoreQueryBuilder(query.get());
constantScoreBuilder.boost(boost);
constantScoreBuilder.queryName(queryName);
- return constantScoreBuilder;
+ return Optional.of(constantScoreBuilder);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/DisMaxQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/DisMaxQueryBuilder.java
index f38b2c09b1..e480417e8f 100644
--- a/core/src/main/java/org/elasticsearch/index/query/DisMaxQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/DisMaxQueryBuilder.java
@@ -33,6 +33,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
/**
* A query that generates the union of documents produced by its sub-queries, and that scores each document
@@ -122,7 +123,7 @@ public class DisMaxQueryBuilder extends AbstractQueryBuilder<DisMaxQueryBuilder>
builder.endObject();
}
- public static DisMaxQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<DisMaxQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
@@ -140,8 +141,7 @@ public class DisMaxQueryBuilder extends AbstractQueryBuilder<DisMaxQueryBuilder>
} else if (token == XContentParser.Token.START_OBJECT) {
if (parseContext.getParseFieldMatcher().match(currentFieldName, QUERIES_FIELD)) {
queriesFound = true;
- QueryBuilder query = parseContext.parseInnerQueryBuilder();
- queries.add(query);
+ parseContext.parseInnerQueryBuilder().ifPresent(queries::add);
} else {
throw new ParsingException(parser.getTokenLocation(), "[dis_max] query does not support [" + currentFieldName + "]");
}
@@ -149,8 +149,7 @@ public class DisMaxQueryBuilder extends AbstractQueryBuilder<DisMaxQueryBuilder>
if (parseContext.getParseFieldMatcher().match(currentFieldName, QUERIES_FIELD)) {
queriesFound = true;
while (token != XContentParser.Token.END_ARRAY) {
- QueryBuilder query = parseContext.parseInnerQueryBuilder();
- queries.add(query);
+ parseContext.parseInnerQueryBuilder().ifPresent(queries::add);
token = parser.nextToken();
}
} else {
@@ -180,7 +179,7 @@ public class DisMaxQueryBuilder extends AbstractQueryBuilder<DisMaxQueryBuilder>
for (QueryBuilder query : queries) {
disMaxQuery.add(query);
}
- return disMaxQuery;
+ return Optional.of(disMaxQuery);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/ExistsQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/ExistsQueryBuilder.java
index afcff164be..c933bae68c 100644
--- a/core/src/main/java/org/elasticsearch/index/query/ExistsQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/ExistsQueryBuilder.java
@@ -37,6 +37,7 @@ import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Objects;
+import java.util.Optional;
/**
* Constructs a query that only match on documents that the field has a value in them.
@@ -85,7 +86,7 @@ public class ExistsQueryBuilder extends AbstractQueryBuilder<ExistsQueryBuilder>
builder.endObject();
}
- public static ExistsQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<ExistsQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String fieldPattern = null;
@@ -121,7 +122,7 @@ public class ExistsQueryBuilder extends AbstractQueryBuilder<ExistsQueryBuilder>
ExistsQueryBuilder builder = new ExistsQueryBuilder(fieldPattern);
builder.queryName(queryName);
builder.boost(boost);
- return builder;
+ return Optional.of(builder);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/FieldMaskingSpanQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/FieldMaskingSpanQueryBuilder.java
index 0382f353cb..801b0ae5a8 100644
--- a/core/src/main/java/org/elasticsearch/index/query/FieldMaskingSpanQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/FieldMaskingSpanQueryBuilder.java
@@ -33,6 +33,7 @@ import org.elasticsearch.index.mapper.MappedFieldType;
import java.io.IOException;
import java.util.Objects;
+import java.util.Optional;
public class FieldMaskingSpanQueryBuilder extends AbstractQueryBuilder<FieldMaskingSpanQueryBuilder>
implements SpanQueryBuilder {
@@ -103,7 +104,7 @@ public class FieldMaskingSpanQueryBuilder extends AbstractQueryBuilder<FieldMask
builder.endObject();
}
- public static FieldMaskingSpanQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<FieldMaskingSpanQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
@@ -119,11 +120,11 @@ public class FieldMaskingSpanQueryBuilder extends AbstractQueryBuilder<FieldMask
currentFieldName = parser.currentName();
} else if (token == XContentParser.Token.START_OBJECT) {
if (parseContext.getParseFieldMatcher().match(currentFieldName, QUERY_FIELD)) {
- QueryBuilder query = parseContext.parseInnerQueryBuilder();
- if (!(query instanceof SpanQueryBuilder)) {
+ Optional<QueryBuilder> query = parseContext.parseInnerQueryBuilder();
+ if (query.isPresent() == false || query.get() instanceof SpanQueryBuilder == false) {
throw new ParsingException(parser.getTokenLocation(), "[field_masking_span] query must be of type span query");
}
- inner = (SpanQueryBuilder) query;
+ inner = (SpanQueryBuilder) query.get();
} else {
throw new ParsingException(parser.getTokenLocation(), "[field_masking_span] query does not support ["
+ currentFieldName + "]");
@@ -151,7 +152,7 @@ public class FieldMaskingSpanQueryBuilder extends AbstractQueryBuilder<FieldMask
FieldMaskingSpanQueryBuilder queryBuilder = new FieldMaskingSpanQueryBuilder(inner, field);
queryBuilder.boost(boost);
queryBuilder.queryName(queryName);
- return queryBuilder;
+ return Optional.of(queryBuilder);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/FuzzyQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/FuzzyQueryBuilder.java
index 70b4f5eb7f..6e60c19d2f 100644
--- a/core/src/main/java/org/elasticsearch/index/query/FuzzyQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/FuzzyQueryBuilder.java
@@ -37,6 +37,7 @@ import org.elasticsearch.index.query.support.QueryParsers;
import java.io.IOException;
import java.util.Objects;
+import java.util.Optional;
/**
* A Query that does fuzzy matching for a specific value.
@@ -257,7 +258,7 @@ public class FuzzyQueryBuilder extends AbstractQueryBuilder<FuzzyQueryBuilder> i
builder.endObject();
}
- public static FuzzyQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<FuzzyQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
XContentParser.Token token = parser.nextToken();
@@ -317,14 +318,14 @@ public class FuzzyQueryBuilder extends AbstractQueryBuilder<FuzzyQueryBuilder> i
if (value == null) {
throw new ParsingException(parser.getTokenLocation(), "no value specified for fuzzy query");
}
- return new FuzzyQueryBuilder(fieldName, value)
+ return Optional.of(new FuzzyQueryBuilder(fieldName, value)
.fuzziness(fuzziness)
.prefixLength(prefixLength)
.maxExpansions(maxExpansions)
.transpositions(transpositions)
.rewrite(rewrite)
.boost(boost)
- .queryName(queryName);
+ .queryName(queryName));
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java
index 7f5d5e2ec8..c1925fe3f3 100644
--- a/core/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java
@@ -43,6 +43,7 @@ import org.elasticsearch.index.search.geo.IndexedGeoBoundingBoxQuery;
import java.io.IOException;
import java.util.Objects;
+import java.util.Optional;
/**
* Creates a Lucene query that will filter for all documents that lie within the specified
@@ -385,7 +386,7 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding
builder.endObject();
}
- public static GeoBoundingBoxQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<GeoBoundingBoxQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String fieldName = null;
@@ -496,7 +497,7 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding
} else {
builder.setValidationMethod(GeoValidationMethod.infer(coerce, ignoreMalformed));
}
- return builder;
+ return Optional.of(builder);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/GeoDistanceQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/GeoDistanceQueryBuilder.java
index 0f2b4694e2..710cb529c0 100644
--- a/core/src/main/java/org/elasticsearch/index/query/GeoDistanceQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/GeoDistanceQueryBuilder.java
@@ -45,6 +45,7 @@ import org.elasticsearch.index.search.geo.GeoDistanceRangeQuery;
import java.io.IOException;
import java.util.Locale;
import java.util.Objects;
+import java.util.Optional;
/**
* Filter results of a query to include only those within a specific distance to some
@@ -330,7 +331,7 @@ public class GeoDistanceQueryBuilder extends AbstractQueryBuilder<GeoDistanceQue
builder.endObject();
}
- public static GeoDistanceQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<GeoDistanceQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
XContentParser.Token token;
@@ -445,7 +446,7 @@ public class GeoDistanceQueryBuilder extends AbstractQueryBuilder<GeoDistanceQue
qb.boost(boost);
qb.queryName(queryName);
qb.ignoreUnmapped(ignoreUnmapped);
- return qb;
+ return Optional.of(qb);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/GeoDistanceRangeQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/GeoDistanceRangeQueryBuilder.java
index ea22461243..06f30a3477 100644
--- a/core/src/main/java/org/elasticsearch/index/query/GeoDistanceRangeQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/GeoDistanceRangeQueryBuilder.java
@@ -46,6 +46,7 @@ import org.elasticsearch.index.search.geo.GeoDistanceRangeQuery;
import java.io.IOException;
import java.util.Locale;
import java.util.Objects;
+import java.util.Optional;
import static org.apache.lucene.spatial.util.GeoEncodingUtils.TOLERANCE;
@@ -391,7 +392,7 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
builder.endObject();
}
- public static GeoDistanceRangeQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<GeoDistanceRangeQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
XContentParser.Token token;
@@ -603,7 +604,7 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
queryBuilder.setValidationMethod(GeoValidationMethod.infer(coerce, ignoreMalformed));
}
queryBuilder.ignoreUnmapped(ignoreUnmapped);
- return queryBuilder;
+ return Optional.of(queryBuilder);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/GeoPolygonQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/GeoPolygonQueryBuilder.java
index 35ab98e25d..97c9990a9f 100644
--- a/core/src/main/java/org/elasticsearch/index/query/GeoPolygonQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/GeoPolygonQueryBuilder.java
@@ -43,6 +43,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
public class GeoPolygonQueryBuilder extends AbstractQueryBuilder<GeoPolygonQueryBuilder> {
@@ -241,7 +242,7 @@ public class GeoPolygonQueryBuilder extends AbstractQueryBuilder<GeoPolygonQuery
builder.endObject();
}
- public static GeoPolygonQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<GeoPolygonQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String fieldName = null;
@@ -322,7 +323,7 @@ public class GeoPolygonQueryBuilder extends AbstractQueryBuilder<GeoPolygonQuery
builder.boost(boost);
}
builder.ignoreUnmapped(ignoreUnmapped);
- return builder;
+ return Optional.of(builder);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java
index 8b3c8a6248..0b04629e2c 100644
--- a/core/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java
@@ -47,6 +47,7 @@ import org.elasticsearch.index.mapper.geo.GeoShapeFieldMapper;
import java.io.IOException;
import java.util.Objects;
+import java.util.Optional;
/**
* {@link QueryBuilder} that builds a GeoShape Query
@@ -453,7 +454,7 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
builder.endObject();
}
- public static GeoShapeQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<GeoShapeQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String fieldName = null;
@@ -559,7 +560,7 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
}
builder.boost(boost);
builder.ignoreUnmapped(ignoreUnmapped);
- return builder;
+ return Optional.of(builder);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/GeohashCellQuery.java b/core/src/main/java/org/elasticsearch/index/query/GeohashCellQuery.java
index 4f34d6db31..f9f21bac7b 100644
--- a/core/src/main/java/org/elasticsearch/index/query/GeohashCellQuery.java
+++ b/core/src/main/java/org/elasticsearch/index/query/GeohashCellQuery.java
@@ -21,12 +21,12 @@ package org.elasticsearch.index.query;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
-import org.elasticsearch.common.geo.GeoHashUtils;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.geo.GeoHashUtils;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.GeoUtils;
import org.elasticsearch.common.io.stream.StreamInput;
@@ -42,6 +42,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
/**
* A geohash cell filter that filters {@link GeoPoint}s by their geohashes. Basically the a
@@ -280,7 +281,7 @@ public class GeohashCellQuery {
builder.endObject();
}
- public static Builder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<Builder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String fieldName = null;
@@ -362,7 +363,7 @@ public class GeohashCellQuery {
builder.boost(boost);
}
builder.ignoreUnmapped(ignoreUnmapped);
- return builder;
+ return Optional.of(builder);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java
index 990b5a35fd..410fda41ae 100644
--- a/core/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java
@@ -43,6 +43,7 @@ import java.io.IOException;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
/**
* A query builder for <tt>has_child</tt> query.
@@ -226,7 +227,7 @@ public class HasChildQueryBuilder extends AbstractQueryBuilder<HasChildQueryBuil
builder.endObject();
}
- public static HasChildQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<HasChildQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
String childType = null;
@@ -238,7 +239,7 @@ public class HasChildQueryBuilder extends AbstractQueryBuilder<HasChildQueryBuil
InnerHitBuilder innerHitBuilder = null;
String currentFieldName = null;
XContentParser.Token token;
- QueryBuilder iqb = null;
+ Optional<QueryBuilder> iqb = Optional.empty();
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
@@ -272,7 +273,13 @@ public class HasChildQueryBuilder extends AbstractQueryBuilder<HasChildQueryBuil
}
}
}
- HasChildQueryBuilder hasChildQueryBuilder = new HasChildQueryBuilder(childType, iqb, scoreMode);
+
+ if (iqb.isPresent() == false) {
+ // if inner query is empty, bubble this up to caller so they can decide how to deal with it
+ return Optional.empty();
+ }
+
+ HasChildQueryBuilder hasChildQueryBuilder = new HasChildQueryBuilder(childType, iqb.get(), scoreMode);
if (innerHitBuilder != null) {
hasChildQueryBuilder.innerHit(innerHitBuilder);
}
@@ -280,7 +287,7 @@ public class HasChildQueryBuilder extends AbstractQueryBuilder<HasChildQueryBuil
hasChildQueryBuilder.queryName(queryName);
hasChildQueryBuilder.boost(boost);
hasChildQueryBuilder.ignoreUnmapped(ignoreUnmapped);
- return hasChildQueryBuilder;
+ return Optional.of(hasChildQueryBuilder);
}
public static ScoreMode parseScoreMode(String scoreModeString) {
diff --git a/core/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java
index 96356c276e..7e788a16e8 100644
--- a/core/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java
@@ -38,6 +38,7 @@ import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.Set;
/**
@@ -227,7 +228,7 @@ public class HasParentQueryBuilder extends AbstractQueryBuilder<HasParentQueryBu
builder.endObject();
}
- public static HasParentQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<HasParentQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
String parentType = null;
@@ -238,7 +239,7 @@ public class HasParentQueryBuilder extends AbstractQueryBuilder<HasParentQueryBu
String currentFieldName = null;
XContentParser.Token token;
- QueryBuilder iqb = null;
+ Optional<QueryBuilder> iqb = Optional.empty();
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
@@ -276,14 +277,18 @@ public class HasParentQueryBuilder extends AbstractQueryBuilder<HasParentQueryBu
}
}
}
- HasParentQueryBuilder queryBuilder = new HasParentQueryBuilder(parentType, iqb, score)
+ if (iqb.isPresent() == false) {
+ // if inner query is empty, bubble this up to caller so they can decide how to deal with it
+ return Optional.empty();
+ }
+ HasParentQueryBuilder queryBuilder = new HasParentQueryBuilder(parentType, iqb.get(), score)
.ignoreUnmapped(ignoreUnmapped)
.queryName(queryName)
.boost(boost);
if (innerHits != null) {
queryBuilder.innerHit(innerHits);
}
- return queryBuilder;
+ return Optional.of(queryBuilder);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/IdsQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/IdsQueryBuilder.java
index 7845e2732e..d2c847c55c 100644
--- a/core/src/main/java/org/elasticsearch/index/query/IdsQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/IdsQueryBuilder.java
@@ -40,6 +40,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
import java.util.Set;
/**
@@ -127,7 +128,7 @@ public class IdsQueryBuilder extends AbstractQueryBuilder<IdsQueryBuilder> {
builder.endObject();
}
- public static IdsQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<IdsQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
List<String> ids = new ArrayList<>();
List<String> types = new ArrayList<>();
@@ -191,7 +192,7 @@ public class IdsQueryBuilder extends AbstractQueryBuilder<IdsQueryBuilder> {
IdsQueryBuilder query = new IdsQueryBuilder(types.toArray(new String[types.size()]));
query.addIds(ids.toArray(new String[ids.size()]));
query.boost(boost).queryName(queryName);
- return query;
+ return Optional.of(query);
}
diff --git a/core/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java
index 7cfdf1baa1..9758ad3f54 100644
--- a/core/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java
@@ -34,6 +34,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Objects;
+import java.util.Optional;
/**
* A query that will execute the wrapped query only for the specified indices,
@@ -141,7 +142,7 @@ public class IndicesQueryBuilder extends AbstractQueryBuilder<IndicesQueryBuilde
builder.endObject();
}
- public static IndicesQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException, ParsingException {
+ public static Optional<IndicesQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException, ParsingException {
XContentParser parser = parseContext.parser();
QueryBuilder innerQuery = null;
@@ -158,9 +159,10 @@ public class IndicesQueryBuilder extends AbstractQueryBuilder<IndicesQueryBuilde
currentFieldName = parser.currentName();
} else if (token == XContentParser.Token.START_OBJECT) {
if (parseContext.getParseFieldMatcher().match(currentFieldName, QUERY_FIELD)) {
- innerQuery = parseContext.parseInnerQueryBuilder();
+ // the 2.0 behaviour when encountering "query" : {} is to return no docs for matching indices
+ innerQuery = parseContext.parseInnerQueryBuilder().orElse(new MatchNoneQueryBuilder());
} else if (parseContext.getParseFieldMatcher().match(currentFieldName, NO_MATCH_QUERY)) {
- noMatchQuery = parseContext.parseInnerQueryBuilder();
+ noMatchQuery = parseContext.parseInnerQueryBuilder().orElse(defaultNoMatchQuery());
} else {
throw new ParsingException(parser.getTokenLocation(), "[indices] query does not support [" + currentFieldName + "]");
}
@@ -203,10 +205,10 @@ public class IndicesQueryBuilder extends AbstractQueryBuilder<IndicesQueryBuilde
if (indices.isEmpty()) {
throw new ParsingException(parser.getTokenLocation(), "[indices] requires 'indices' or 'index' element");
}
- return new IndicesQueryBuilder(innerQuery, indices.toArray(new String[indices.size()]))
+ return Optional.of(new IndicesQueryBuilder(innerQuery, indices.toArray(new String[indices.size()]))
.noMatchQuery(noMatchQuery)
.boost(boost)
- .queryName(queryName);
+ .queryName(queryName));
}
static QueryBuilder parseNoMatchQuery(String type) {
diff --git a/core/src/main/java/org/elasticsearch/index/query/InnerHitBuilder.java b/core/src/main/java/org/elasticsearch/index/query/InnerHitBuilder.java
index b62b5a18a1..a017159b45 100644
--- a/core/src/main/java/org/elasticsearch/index/query/InnerHitBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/InnerHitBuilder.java
@@ -60,6 +60,7 @@ public final class InnerHitBuilder extends ToXContentToBytes implements Writeabl
public static final ParseField NAME_FIELD = new ParseField("name");
public static final ParseField INNER_HITS_FIELD = new ParseField("inner_hits");
+ public static final QueryBuilder DEFAULT_INNER_HIT_QUERY = new MatchAllQueryBuilder();
private final static ObjectParser<InnerHitBuilder, QueryParseContext> PARSER = new ObjectParser<>("inner_hits", InnerHitBuilder::new);
@@ -131,7 +132,7 @@ public final class InnerHitBuilder extends ToXContentToBytes implements Writeabl
private boolean trackScores;
private List<String> fieldNames;
- private QueryBuilder query = new MatchAllQueryBuilder();
+ private QueryBuilder query = DEFAULT_INNER_HIT_QUERY;
private List<SortBuilder<?>> sorts;
private List<String> fieldDataFields;
private Set<ScriptField> scriptFields;
@@ -394,7 +395,7 @@ public final class InnerHitBuilder extends ToXContentToBytes implements Writeabl
return this;
}
- public InnerHitBuilder addSort(SortBuilder sort) {
+ public InnerHitBuilder addSort(SortBuilder<?> sort) {
if (sorts == null) {
sorts = new ArrayList<>();
}
diff --git a/core/src/main/java/org/elasticsearch/index/query/MatchAllQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/MatchAllQueryBuilder.java
index 2d415c2b2a..21742eb877 100644
--- a/core/src/main/java/org/elasticsearch/index/query/MatchAllQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/MatchAllQueryBuilder.java
@@ -29,6 +29,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
+import java.util.Optional;
/**
* A query that matches on all documents.
@@ -60,7 +61,7 @@ public class MatchAllQueryBuilder extends AbstractQueryBuilder<MatchAllQueryBuil
builder.endObject();
}
- public static MatchAllQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<MatchAllQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String currentFieldName = null;
@@ -87,7 +88,7 @@ public class MatchAllQueryBuilder extends AbstractQueryBuilder<MatchAllQueryBuil
MatchAllQueryBuilder queryBuilder = new MatchAllQueryBuilder();
queryBuilder.boost(boost);
queryBuilder.queryName(queryName);
- return queryBuilder;
+ return Optional.of(queryBuilder);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/MatchNoneQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/MatchNoneQueryBuilder.java
index 068b0e86d8..f96c6160ee 100644
--- a/core/src/main/java/org/elasticsearch/index/query/MatchNoneQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/MatchNoneQueryBuilder.java
@@ -29,6 +29,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
+import java.util.Optional;
/**
* A query that matches no document.
@@ -60,7 +61,7 @@ public class MatchNoneQueryBuilder extends AbstractQueryBuilder<MatchNoneQueryBu
builder.endObject();
}
- public static MatchNoneQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<MatchNoneQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String currentFieldName = null;
@@ -88,7 +89,7 @@ public class MatchNoneQueryBuilder extends AbstractQueryBuilder<MatchNoneQueryBu
MatchNoneQueryBuilder matchNoneQueryBuilder = new MatchNoneQueryBuilder();
matchNoneQueryBuilder.boost(boost);
matchNoneQueryBuilder.queryName(queryName);
- return matchNoneQueryBuilder;
+ return Optional.of(matchNoneQueryBuilder);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/MatchPhrasePrefixQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/MatchPhrasePrefixQueryBuilder.java
index cb20d448f8..002b5e2343 100644
--- a/core/src/main/java/org/elasticsearch/index/query/MatchPhrasePrefixQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/MatchPhrasePrefixQueryBuilder.java
@@ -31,6 +31,7 @@ import org.elasticsearch.index.search.MatchQuery;
import java.io.IOException;
import java.util.Objects;
+import java.util.Optional;
/**
* Match query is a query that analyzes the text and constructs a phrase prefix
@@ -191,7 +192,7 @@ public class MatchPhrasePrefixQueryBuilder extends AbstractQueryBuilder<MatchPhr
return Objects.hash(fieldName, value, analyzer, slop, maxExpansions);
}
- public static MatchPhrasePrefixQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<MatchPhrasePrefixQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
XContentParser.Token token = parser.nextToken();
@@ -257,6 +258,6 @@ public class MatchPhrasePrefixQueryBuilder extends AbstractQueryBuilder<MatchPhr
matchQuery.maxExpansions(maxExpansion);
matchQuery.queryName(queryName);
matchQuery.boost(boost);
- return matchQuery;
+ return Optional.of(matchQuery);
}
}
diff --git a/core/src/main/java/org/elasticsearch/index/query/MatchPhraseQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/MatchPhraseQueryBuilder.java
index 7fef776bbc..2621c2dc50 100644
--- a/core/src/main/java/org/elasticsearch/index/query/MatchPhraseQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/MatchPhraseQueryBuilder.java
@@ -27,8 +27,10 @@ import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.search.MatchQuery;
+
import java.io.IOException;
import java.util.Objects;
+import java.util.Optional;
/**
* Match query is a query that analyzes the text and constructs a phrase query
@@ -161,7 +163,7 @@ public class MatchPhraseQueryBuilder extends AbstractQueryBuilder<MatchPhraseQue
return Objects.hash(fieldName, value, analyzer, slop);
}
- public static MatchPhraseQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<MatchPhraseQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
XContentParser.Token token = parser.nextToken();
@@ -223,6 +225,6 @@ public class MatchPhraseQueryBuilder extends AbstractQueryBuilder<MatchPhraseQue
matchQuery.slop(slop);
matchQuery.queryName(queryName);
matchQuery.boost(boost);
- return matchQuery;
+ return Optional.of(matchQuery);
}
}
diff --git a/core/src/main/java/org/elasticsearch/index/query/MatchQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/MatchQueryBuilder.java
index 6c86759065..04fa9120a7 100644
--- a/core/src/main/java/org/elasticsearch/index/query/MatchQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/MatchQueryBuilder.java
@@ -38,6 +38,7 @@ import org.elasticsearch.index.search.MatchQuery.ZeroTermsQuery;
import java.io.IOException;
import java.util.Locale;
import java.util.Objects;
+import java.util.Optional;
/**
* Match query is a query that analyzes the text and constructs a query as the
@@ -507,7 +508,7 @@ public class MatchQueryBuilder extends AbstractQueryBuilder<MatchQueryBuilder> {
return NAME;
}
- public static MatchQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<MatchQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
XContentParser.Token token = parser.nextToken();
@@ -633,7 +634,7 @@ public class MatchQueryBuilder extends AbstractQueryBuilder<MatchQueryBuilder> {
matchQuery.zeroTermsQuery(zeroTermsQuery);
matchQuery.queryName(queryName);
matchQuery.boost(boost);
- return matchQuery;
+ return Optional.of(matchQuery);
}
}
diff --git a/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java
index 66f623cbbb..5fa36ec977 100644
--- a/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java
@@ -805,7 +805,7 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
builder.endObject();
}
- public static MoreLikeThisQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<MoreLikeThisQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
// document inputs
@@ -955,7 +955,7 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
if (stopWords != null) {
moreLikeThisQueryBuilder.stopWords(stopWords);
}
- return moreLikeThisQueryBuilder;
+ return Optional.of(moreLikeThisQueryBuilder);
}
private static void parseLikeField(QueryParseContext parseContext, List<String> texts, List<Item> items) throws IOException {
diff --git a/core/src/main/java/org/elasticsearch/index/query/MultiMatchQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/MultiMatchQueryBuilder.java
index 032feac919..0d93b1331b 100644
--- a/core/src/main/java/org/elasticsearch/index/query/MultiMatchQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/MultiMatchQueryBuilder.java
@@ -43,6 +43,7 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.TreeMap;
/**
@@ -556,7 +557,7 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQuery
builder.endObject();
}
- public static MultiMatchQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<MultiMatchQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
Object value = null;
@@ -660,7 +661,7 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQuery
"Fuziness not allowed for type [" + type.parseField.getPreferredName() + "]");
}
- return new MultiMatchQueryBuilder(value)
+ return Optional.of(new MultiMatchQueryBuilder(value)
.fields(fieldsBoosts)
.type(type)
.analyzer(analyzer)
@@ -677,7 +678,7 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQuery
.tieBreaker(tieBreaker)
.zeroTermsQuery(zeroTermsQuery)
.boost(boost)
- .queryName(queryName);
+ .queryName(queryName));
}
private static void parseFieldAndBoost(XContentParser parser, Map<String, Float> fieldsBoosts) throws IOException {
diff --git a/core/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java
index 5d74b54011..1d0e6d11f5 100644
--- a/core/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java
@@ -36,6 +36,7 @@ import org.elasticsearch.index.mapper.object.ObjectMapper;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
public class NestedQueryBuilder extends AbstractQueryBuilder<NestedQueryBuilder> {
@@ -156,12 +157,12 @@ public class NestedQueryBuilder extends AbstractQueryBuilder<NestedQueryBuilder>
builder.endObject();
}
- public static NestedQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<NestedQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
ScoreMode scoreMode = ScoreMode.Avg;
String queryName = null;
- QueryBuilder query = null;
+ Optional<QueryBuilder> query = Optional.empty();
String path = null;
String currentFieldName = null;
InnerHitBuilder innerHitBuilder = null;
@@ -194,14 +195,19 @@ public class NestedQueryBuilder extends AbstractQueryBuilder<NestedQueryBuilder>
}
}
}
- NestedQueryBuilder queryBuilder = new NestedQueryBuilder(path, query, scoreMode)
+
+ if (query.isPresent() == false) {
+ // if inner query is empty, bubble this up to caller so they can decide how to deal with it
+ return Optional.empty();
+ }
+ NestedQueryBuilder queryBuilder = new NestedQueryBuilder(path, query.get(), scoreMode)
.ignoreUnmapped(ignoreUnmapped)
.queryName(queryName)
.boost(boost);
if (innerHitBuilder != null) {
queryBuilder.innerHit(innerHitBuilder);
}
- return queryBuilder;
+ return Optional.of(queryBuilder);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/ParentIdQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/ParentIdQueryBuilder.java
index 419149ce99..ede449cbd3 100644
--- a/core/src/main/java/org/elasticsearch/index/query/ParentIdQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/ParentIdQueryBuilder.java
@@ -38,6 +38,7 @@ import org.elasticsearch.index.mapper.internal.TypeFieldMapper;
import java.io.IOException;
import java.util.Objects;
+import java.util.Optional;
public final class ParentIdQueryBuilder extends AbstractQueryBuilder<ParentIdQueryBuilder> {
@@ -117,7 +118,7 @@ public final class ParentIdQueryBuilder extends AbstractQueryBuilder<ParentIdQue
builder.endObject();
}
- public static ParentIdQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<ParentIdQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
String type = null;
@@ -151,7 +152,7 @@ public final class ParentIdQueryBuilder extends AbstractQueryBuilder<ParentIdQue
queryBuilder.queryName(queryName);
queryBuilder.boost(boost);
queryBuilder.ignoreUnmapped(ignoreUnmapped);
- return queryBuilder;
+ return Optional.of(queryBuilder);
}
diff --git a/core/src/main/java/org/elasticsearch/index/query/PrefixQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/PrefixQueryBuilder.java
index 44677d1840..f92e1d521d 100644
--- a/core/src/main/java/org/elasticsearch/index/query/PrefixQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/PrefixQueryBuilder.java
@@ -36,6 +36,7 @@ import org.elasticsearch.index.query.support.QueryParsers;
import java.io.IOException;
import java.util.Objects;
+import java.util.Optional;
/**
* A Query that matches documents containing terms with a specified prefix.
@@ -118,7 +119,7 @@ public class PrefixQueryBuilder extends AbstractQueryBuilder<PrefixQueryBuilder>
builder.endObject();
}
- public static PrefixQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<PrefixQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String fieldName = parser.currentName();
@@ -163,10 +164,10 @@ public class PrefixQueryBuilder extends AbstractQueryBuilder<PrefixQueryBuilder>
if (value == null) {
throw new ParsingException(parser.getTokenLocation(), "No value specified for prefix query");
}
- return new PrefixQueryBuilder(fieldName, value)
+ return Optional.of(new PrefixQueryBuilder(fieldName, value)
.rewrite(rewrite)
.boost(boost)
- .queryName(queryName);
+ .queryName(queryName));
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/QueryParseContext.java b/core/src/main/java/org/elasticsearch/index/query/QueryParseContext.java
index 62662914fd..93bd07c7bf 100644
--- a/core/src/main/java/org/elasticsearch/index/query/QueryParseContext.java
+++ b/core/src/main/java/org/elasticsearch/index/query/QueryParseContext.java
@@ -23,14 +23,19 @@ import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.ParseFieldMatcherSupplier;
import org.elasticsearch.common.ParsingException;
+import org.elasticsearch.common.logging.DeprecationLogger;
+import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
import java.io.IOException;
import java.util.Objects;
+import java.util.Optional;
public class QueryParseContext implements ParseFieldMatcherSupplier {
+ private static final DeprecationLogger DEPRECATION_LOGGER = new DeprecationLogger(Loggers.getLogger(QueryParseContext.class));
+
private static final ParseField CACHE = new ParseField("_cache").withAllDeprecated("Elasticsearch makes its own caching decisions");
private static final ParseField CACHE_KEY = new ParseField("_cache_key").withAllDeprecated("Filters are always used as cache keys");
@@ -62,7 +67,7 @@ public class QueryParseContext implements ParseFieldMatcherSupplier {
if (token == XContentParser.Token.FIELD_NAME) {
String fieldName = parser.currentName();
if ("query".equals(fieldName)) {
- queryBuilder = parseInnerQueryBuilder();
+ queryBuilder = parseInnerQueryBuilder().orElse(null);
} else {
throw new ParsingException(parser.getTokenLocation(), "request does not support [" + parser.currentName() + "]");
}
@@ -82,7 +87,7 @@ public class QueryParseContext implements ParseFieldMatcherSupplier {
/**
* Parses a query excluding the query element that wraps it
*/
- public QueryBuilder parseInnerQueryBuilder() throws IOException {
+ public Optional<QueryBuilder> parseInnerQueryBuilder() throws IOException {
// move to START object
XContentParser.Token token;
if (parser.currentToken() != XContentParser.Token.START_OBJECT) {
@@ -93,8 +98,13 @@ public class QueryParseContext implements ParseFieldMatcherSupplier {
}
token = parser.nextToken();
if (token == XContentParser.Token.END_OBJECT) {
- // empty query
- return new EmptyQueryBuilder();
+ // we encountered '{}' for a query clause
+ String msg = "query malformed, empty clause found at [" + parser.getTokenLocation() +"]";
+ DEPRECATION_LOGGER.deprecated(msg);
+ if (parseFieldMatcher.isStrict()) {
+ throw new IllegalArgumentException(msg);
+ }
+ return Optional.empty();
}
if (token != XContentParser.Token.FIELD_NAME) {
throw new ParsingException(parser.getTokenLocation(), "[_na] query malformed, no field after start_object");
@@ -105,7 +115,9 @@ public class QueryParseContext implements ParseFieldMatcherSupplier {
if (token != XContentParser.Token.START_OBJECT && token != XContentParser.Token.START_ARRAY) {
throw new ParsingException(parser.getTokenLocation(), "[_na] query malformed, no field after start_object");
}
- QueryBuilder result = indicesQueriesRegistry.lookup(queryName, parseFieldMatcher, parser.getTokenLocation()).fromXContent(this);
+ @SuppressWarnings("unchecked")
+ Optional<QueryBuilder> result = (Optional<QueryBuilder>) indicesQueriesRegistry.lookup(queryName, parseFieldMatcher,
+ parser.getTokenLocation()).fromXContent(this);
if (parser.currentToken() == XContentParser.Token.END_OBJECT || parser.currentToken() == XContentParser.Token.END_ARRAY) {
// if we are at END_OBJECT, move to the next one...
parser.nextToken();
diff --git a/core/src/main/java/org/elasticsearch/index/query/QueryParser.java b/core/src/main/java/org/elasticsearch/index/query/QueryParser.java
index 069dc86cf8..222d3bd496 100644
--- a/core/src/main/java/org/elasticsearch/index/query/QueryParser.java
+++ b/core/src/main/java/org/elasticsearch/index/query/QueryParser.java
@@ -20,6 +20,7 @@
package org.elasticsearch.index.query;
import java.io.IOException;
+import java.util.Optional;
/**
* Defines a query parser that is able to parse {@link QueryBuilder}s from {@link org.elasticsearch.common.xcontent.XContent}.
@@ -36,5 +37,12 @@ public interface QueryParser<QB extends QueryBuilder> {
* call
* @return the new QueryBuilder
*/
- QB fromXContent(QueryParseContext parseContext) throws IOException;
+ Optional<QB> fromXContent(QueryParseContext parseContext) throws IOException;
+
+ /**
+ * @return an empty {@link QueryBuilder} instance for this parser that can be used for deserialization
+ */
+ default QB getBuilderPrototype() { // TODO remove this when nothing implements it
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/core/src/main/java/org/elasticsearch/index/query/QueryStringQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/QueryStringQueryBuilder.java
index 6806ae944c..c390507a78 100644
--- a/core/src/main/java/org/elasticsearch/index/query/QueryStringQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/QueryStringQueryBuilder.java
@@ -46,6 +46,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.TreeMap;
/**
@@ -631,7 +632,7 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
builder.endObject();
}
- public static QueryStringQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<QueryStringQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String currentFieldName = null;
XContentParser.Token token;
@@ -792,7 +793,7 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
queryStringQuery.locale(locale);
queryStringQuery.boost(boost);
queryStringQuery.queryName(queryName);
- return queryStringQuery;
+ return Optional.of(queryStringQuery);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/RangeQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/RangeQueryBuilder.java
index 241c38475a..1c51b6a2dd 100644
--- a/core/src/main/java/org/elasticsearch/index/query/RangeQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/RangeQueryBuilder.java
@@ -42,6 +42,7 @@ import org.joda.time.DateTimeZone;
import java.io.IOException;
import java.util.Objects;
+import java.util.Optional;
/**
* A Query that matches documents within an range of terms.
@@ -297,7 +298,7 @@ public class RangeQueryBuilder extends AbstractQueryBuilder<RangeQueryBuilder> i
builder.endObject();
}
- public static RangeQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<RangeQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String fieldName = null;
@@ -381,7 +382,7 @@ public class RangeQueryBuilder extends AbstractQueryBuilder<RangeQueryBuilder> i
if (format != null) {
rangeQuery.format(format);
}
- return rangeQuery;
+ return Optional.of(rangeQuery);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/RegexpQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/RegexpQueryBuilder.java
index 703b2463b1..27462cfb26 100644
--- a/core/src/main/java/org/elasticsearch/index/query/RegexpQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/RegexpQueryBuilder.java
@@ -37,6 +37,7 @@ import org.elasticsearch.index.query.support.QueryParsers;
import java.io.IOException;
import java.util.Objects;
+import java.util.Optional;
/**
* A Query that does fuzzy matching for a specific value.
@@ -179,7 +180,7 @@ public class RegexpQueryBuilder extends AbstractQueryBuilder<RegexpQueryBuilder>
builder.endObject();
}
- public static RegexpQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<RegexpQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String fieldName = parser.currentName();
@@ -237,12 +238,12 @@ public class RegexpQueryBuilder extends AbstractQueryBuilder<RegexpQueryBuilder>
if (value == null) {
throw new ParsingException(parser.getTokenLocation(), "No value specified for regexp query");
}
- return new RegexpQueryBuilder(fieldName, value)
+ return Optional.of(new RegexpQueryBuilder(fieldName, value)
.flags(flagsValue)
.maxDeterminizedStates(maxDeterminizedStates)
.rewrite(rewrite)
.boost(boost)
- .queryName(queryName);
+ .queryName(queryName));
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/ScriptQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/ScriptQueryBuilder.java
index 12aba8ae87..6d563f22a0 100644
--- a/core/src/main/java/org/elasticsearch/index/query/ScriptQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/ScriptQueryBuilder.java
@@ -35,9 +35,9 @@ import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.script.LeafSearchScript;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.Script.ScriptField;
-import org.elasticsearch.script.ScriptParameterParser.ScriptParameterValue;
import org.elasticsearch.script.ScriptContext;
import org.elasticsearch.script.ScriptParameterParser;
+import org.elasticsearch.script.ScriptParameterParser.ScriptParameterValue;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.SearchScript;
import org.elasticsearch.search.lookup.SearchLookup;
@@ -47,6 +47,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
public class ScriptQueryBuilder extends AbstractQueryBuilder<ScriptQueryBuilder> {
@@ -94,7 +95,7 @@ public class ScriptQueryBuilder extends AbstractQueryBuilder<ScriptQueryBuilder>
builder.endObject();
}
- public static ScriptQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<ScriptQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
ScriptParameterParser scriptParameterParser = new ScriptParameterParser();
@@ -149,9 +150,9 @@ public class ScriptQueryBuilder extends AbstractQueryBuilder<ScriptQueryBuilder>
throw new ParsingException(parser.getTokenLocation(), "script must be provided with a [script] filter");
}
- return new ScriptQueryBuilder(script)
+ return Optional.of(new ScriptQueryBuilder(script)
.boost(boost)
- .queryName(queryName);
+ .queryName(queryName));
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/SimpleQueryStringBuilder.java b/core/src/main/java/org/elasticsearch/index/query/SimpleQueryStringBuilder.java
index 5e2c88af92..0bedf67820 100644
--- a/core/src/main/java/org/elasticsearch/index/query/SimpleQueryStringBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/SimpleQueryStringBuilder.java
@@ -39,6 +39,7 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.TreeMap;
/**
@@ -417,7 +418,7 @@ public class SimpleQueryStringBuilder extends AbstractQueryBuilder<SimpleQuerySt
builder.endObject();
}
- public static SimpleQueryStringBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<SimpleQueryStringBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String currentFieldName = null;
@@ -514,7 +515,7 @@ public class SimpleQueryStringBuilder extends AbstractQueryBuilder<SimpleQuerySt
qb.boost(boost).fields(fieldsAndWeights).analyzer(analyzerName).queryName(queryName).minimumShouldMatch(minimumShouldMatch);
qb.flags(flags).defaultOperator(defaultOperator).locale(locale).lowercaseExpandedTerms(lowercaseExpandedTerms);
qb.lenient(lenient).analyzeWildcard(analyzeWildcard).boost(boost);
- return qb;
+ return Optional.of(qb);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/SpanContainingQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/SpanContainingQueryBuilder.java
index ae4297e431..5d22df1557 100644
--- a/core/src/main/java/org/elasticsearch/index/query/SpanContainingQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/SpanContainingQueryBuilder.java
@@ -31,6 +31,7 @@ import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.Objects;
+import java.util.Optional;
/**
* Builder for {@link org.apache.lucene.search.spans.SpanContainingQuery}.
@@ -102,7 +103,7 @@ public class SpanContainingQueryBuilder extends AbstractQueryBuilder<SpanContain
builder.endObject();
}
- public static SpanContainingQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<SpanContainingQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
String queryName = null;
@@ -116,17 +117,17 @@ public class SpanContainingQueryBuilder extends AbstractQueryBuilder<SpanContain
currentFieldName = parser.currentName();
} else if (token == XContentParser.Token.START_OBJECT) {
if (parseContext.getParseFieldMatcher().match(currentFieldName, BIG_FIELD)) {
- QueryBuilder query = parseContext.parseInnerQueryBuilder();
- if (!(query instanceof SpanQueryBuilder)) {
+ Optional<QueryBuilder> query = parseContext.parseInnerQueryBuilder();
+ if (query.isPresent() == false || query.get() instanceof SpanQueryBuilder == false) {
throw new ParsingException(parser.getTokenLocation(), "span_containing [big] must be of type span query");
}
- big = (SpanQueryBuilder) query;
+ big = (SpanQueryBuilder) query.get();
} else if (parseContext.getParseFieldMatcher().match(currentFieldName, LITTLE_FIELD)) {
- QueryBuilder query = parseContext.parseInnerQueryBuilder();
- if (!(query instanceof SpanQueryBuilder)) {
+ Optional<QueryBuilder> query = parseContext.parseInnerQueryBuilder();
+ if (query.isPresent() == false || query.get() instanceof SpanQueryBuilder == false) {
throw new ParsingException(parser.getTokenLocation(), "span_containing [little] must be of type span query");
}
- little = (SpanQueryBuilder) query;
+ little = (SpanQueryBuilder) query.get();
} else {
throw new ParsingException(parser.getTokenLocation(),
"[span_containing] query does not support [" + currentFieldName + "]");
@@ -143,7 +144,7 @@ public class SpanContainingQueryBuilder extends AbstractQueryBuilder<SpanContain
SpanContainingQueryBuilder query = new SpanContainingQueryBuilder(big, little);
query.boost(boost).queryName(queryName);
- return query;
+ return Optional.of(query);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/SpanFirstQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/SpanFirstQueryBuilder.java
index 009f8a3965..b0b096b19e 100644
--- a/core/src/main/java/org/elasticsearch/index/query/SpanFirstQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/SpanFirstQueryBuilder.java
@@ -31,6 +31,7 @@ import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.Objects;
+import java.util.Optional;
public class SpanFirstQueryBuilder extends AbstractQueryBuilder<SpanFirstQueryBuilder> implements SpanQueryBuilder {
@@ -101,7 +102,7 @@ public class SpanFirstQueryBuilder extends AbstractQueryBuilder<SpanFirstQueryBu
builder.endObject();
}
- public static SpanFirstQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<SpanFirstQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
@@ -117,11 +118,11 @@ public class SpanFirstQueryBuilder extends AbstractQueryBuilder<SpanFirstQueryBu
currentFieldName = parser.currentName();
} else if (token == XContentParser.Token.START_OBJECT) {
if (parseContext.getParseFieldMatcher().match(currentFieldName, MATCH_FIELD)) {
- QueryBuilder query = parseContext.parseInnerQueryBuilder();
- if (!(query instanceof SpanQueryBuilder)) {
+ Optional<QueryBuilder> query = parseContext.parseInnerQueryBuilder();
+ if (query.isPresent() == false || query.get() instanceof SpanQueryBuilder == false) {
throw new ParsingException(parser.getTokenLocation(), "spanFirst [match] must be of type span query");
}
- match = (SpanQueryBuilder) query;
+ match = (SpanQueryBuilder) query.get();
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_first] query does not support [" + currentFieldName + "]");
}
@@ -145,7 +146,7 @@ public class SpanFirstQueryBuilder extends AbstractQueryBuilder<SpanFirstQueryBu
}
SpanFirstQueryBuilder queryBuilder = new SpanFirstQueryBuilder(match, end);
queryBuilder.boost(boost).queryName(queryName);
- return queryBuilder;
+ return Optional.of(queryBuilder);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/SpanMultiTermQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/SpanMultiTermQueryBuilder.java
index 86418903f7..0849d1c6a6 100644
--- a/core/src/main/java/org/elasticsearch/index/query/SpanMultiTermQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/SpanMultiTermQueryBuilder.java
@@ -33,6 +33,7 @@ import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.Objects;
+import java.util.Optional;
/**
* Query that allows wraping a {@link MultiTermQueryBuilder} (one of wildcard, fuzzy, prefix, term, range or regexp query)
@@ -82,7 +83,7 @@ public class SpanMultiTermQueryBuilder extends AbstractQueryBuilder<SpanMultiTer
builder.endObject();
}
- public static SpanMultiTermQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<SpanMultiTermQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String currentFieldName = null;
MultiTermQueryBuilder subQuery = null;
@@ -94,12 +95,12 @@ public class SpanMultiTermQueryBuilder extends AbstractQueryBuilder<SpanMultiTer
currentFieldName = parser.currentName();
} else if (token == XContentParser.Token.START_OBJECT) {
if (parseContext.getParseFieldMatcher().match(currentFieldName, MATCH_FIELD)) {
- QueryBuilder innerQuery = parseContext.parseInnerQueryBuilder();
- if (innerQuery instanceof MultiTermQueryBuilder == false) {
+ Optional<QueryBuilder> query = parseContext.parseInnerQueryBuilder();
+ if (query.isPresent() == false || query.get() instanceof MultiTermQueryBuilder == false) {
throw new ParsingException(parser.getTokenLocation(),
"[span_multi] [" + MATCH_FIELD.getPreferredName() + "] must be of type multi term query");
}
- subQuery = (MultiTermQueryBuilder) innerQuery;
+ subQuery = (MultiTermQueryBuilder) query.get();
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_multi] query does not support [" + currentFieldName + "]");
}
@@ -119,7 +120,7 @@ public class SpanMultiTermQueryBuilder extends AbstractQueryBuilder<SpanMultiTer
"[span_multi] must have [" + MATCH_FIELD.getPreferredName() + "] multi term query clause");
}
- return new SpanMultiTermQueryBuilder(subQuery).queryName(queryName).boost(boost);
+ return Optional.of(new SpanMultiTermQueryBuilder(subQuery).queryName(queryName).boost(boost));
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/SpanNearQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/SpanNearQueryBuilder.java
index cebc72c077..c11164ae7a 100644
--- a/core/src/main/java/org/elasticsearch/index/query/SpanNearQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/SpanNearQueryBuilder.java
@@ -34,6 +34,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
/**
* Matches spans which are near one another. One can specify slop, the maximum number
@@ -146,7 +147,7 @@ public class SpanNearQueryBuilder extends AbstractQueryBuilder<SpanNearQueryBuil
builder.endObject();
}
- public static SpanNearQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<SpanNearQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
@@ -164,11 +165,11 @@ public class SpanNearQueryBuilder extends AbstractQueryBuilder<SpanNearQueryBuil
} else if (token == XContentParser.Token.START_ARRAY) {
if (parseContext.getParseFieldMatcher().match(currentFieldName, CLAUSES_FIELD)) {
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
- QueryBuilder query = parseContext.parseInnerQueryBuilder();
- if (!(query instanceof SpanQueryBuilder)) {
+ Optional<QueryBuilder> query = parseContext.parseInnerQueryBuilder();
+ if (query.isPresent() == false || query.get() instanceof SpanQueryBuilder == false) {
throw new ParsingException(parser.getTokenLocation(), "spanNear [clauses] must be of type span query");
}
- clauses.add((SpanQueryBuilder) query);
+ clauses.add((SpanQueryBuilder) query.get());
}
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_near] query does not support [" + currentFieldName + "]");
@@ -207,7 +208,7 @@ public class SpanNearQueryBuilder extends AbstractQueryBuilder<SpanNearQueryBuil
queryBuilder.inOrder(inOrder);
queryBuilder.boost(boost);
queryBuilder.queryName(queryName);
- return queryBuilder;
+ return Optional.of(queryBuilder);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/SpanNotQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/SpanNotQueryBuilder.java
index 02ce431de1..6bb635b200 100644
--- a/core/src/main/java/org/elasticsearch/index/query/SpanNotQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/SpanNotQueryBuilder.java
@@ -31,6 +31,7 @@ import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.Objects;
+import java.util.Optional;
public class SpanNotQueryBuilder extends AbstractQueryBuilder<SpanNotQueryBuilder> implements SpanQueryBuilder {
@@ -162,7 +163,7 @@ public class SpanNotQueryBuilder extends AbstractQueryBuilder<SpanNotQueryBuilde
builder.endObject();
}
- public static SpanNotQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<SpanNotQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
@@ -183,17 +184,17 @@ public class SpanNotQueryBuilder extends AbstractQueryBuilder<SpanNotQueryBuilde
currentFieldName = parser.currentName();
} else if (token == XContentParser.Token.START_OBJECT) {
if (parseContext.getParseFieldMatcher().match(currentFieldName, INCLUDE_FIELD)) {
- QueryBuilder query = parseContext.parseInnerQueryBuilder();
- if (!(query instanceof SpanQueryBuilder)) {
+ Optional<QueryBuilder> query = parseContext.parseInnerQueryBuilder();
+ if (query.isPresent() == false || query.get() instanceof SpanQueryBuilder == false) {
throw new ParsingException(parser.getTokenLocation(), "spanNot [include] must be of type span query");
}
- include = (SpanQueryBuilder) query;
+ include = (SpanQueryBuilder) query.get();
} else if (parseContext.getParseFieldMatcher().match(currentFieldName, EXCLUDE_FIELD)) {
- QueryBuilder query = parseContext.parseInnerQueryBuilder();
- if (!(query instanceof SpanQueryBuilder)) {
+ Optional<QueryBuilder> query = parseContext.parseInnerQueryBuilder();
+ if (query.isPresent() == false || query.get() instanceof SpanQueryBuilder == false) {
throw new ParsingException(parser.getTokenLocation(), "spanNot [exclude] must be of type span query");
}
- exclude = (SpanQueryBuilder) query;
+ exclude = (SpanQueryBuilder) query.get();
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_not] query does not support [" + currentFieldName + "]");
}
@@ -235,7 +236,7 @@ public class SpanNotQueryBuilder extends AbstractQueryBuilder<SpanNotQueryBuilde
}
spanNotQuery.boost(boost);
spanNotQuery.queryName(queryName);
- return spanNotQuery;
+ return Optional.of(spanNotQuery);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/SpanOrQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/SpanOrQueryBuilder.java
index 98698307d0..5169e0d933 100644
--- a/core/src/main/java/org/elasticsearch/index/query/SpanOrQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/SpanOrQueryBuilder.java
@@ -34,6 +34,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
/**
* Span query that matches the union of its clauses. Maps to {@link SpanOrQuery}.
@@ -99,7 +100,7 @@ public class SpanOrQueryBuilder extends AbstractQueryBuilder<SpanOrQueryBuilder>
builder.endObject();
}
- public static SpanOrQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<SpanOrQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
@@ -115,11 +116,11 @@ public class SpanOrQueryBuilder extends AbstractQueryBuilder<SpanOrQueryBuilder>
} else if (token == XContentParser.Token.START_ARRAY) {
if (parseContext.getParseFieldMatcher().match(currentFieldName, CLAUSES_FIELD)) {
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
- QueryBuilder query = parseContext.parseInnerQueryBuilder();
- if (!(query instanceof SpanQueryBuilder)) {
+ Optional<QueryBuilder> query = parseContext.parseInnerQueryBuilder();
+ if (query.isPresent() == false || query.get() instanceof SpanQueryBuilder == false) {
throw new ParsingException(parser.getTokenLocation(), "spanOr [clauses] must be of type span query");
}
- clauses.add((SpanQueryBuilder) query);
+ clauses.add((SpanQueryBuilder) query.get());
}
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_or] query does not support [" + currentFieldName + "]");
@@ -145,7 +146,7 @@ public class SpanOrQueryBuilder extends AbstractQueryBuilder<SpanOrQueryBuilder>
}
queryBuilder.boost(boost);
queryBuilder.queryName(queryName);
- return queryBuilder;
+ return Optional.of(queryBuilder);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/SpanTermQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/SpanTermQueryBuilder.java
index 3bb374ff27..56581c3991 100644
--- a/core/src/main/java/org/elasticsearch/index/query/SpanTermQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/SpanTermQueryBuilder.java
@@ -31,6 +31,7 @@ import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.MappedFieldType;
import java.io.IOException;
+import java.util.Optional;
/**
* A Span Query that matches documents containing a term.
@@ -93,7 +94,7 @@ public class SpanTermQueryBuilder extends BaseTermQueryBuilder<SpanTermQueryBuil
return new SpanTermQuery(term);
}
- public static SpanTermQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException, ParsingException {
+ public static Optional<SpanTermQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException, ParsingException {
XContentParser parser = parseContext.parser();
XContentParser.Token token = parser.currentToken();
@@ -142,7 +143,7 @@ public class SpanTermQueryBuilder extends BaseTermQueryBuilder<SpanTermQueryBuil
SpanTermQueryBuilder result = new SpanTermQueryBuilder(fieldName, value);
result.boost(boost).queryName(queryName);
- return result;
+ return Optional.of(result);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/SpanWithinQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/SpanWithinQueryBuilder.java
index eaedc80bab..2975063f78 100644
--- a/core/src/main/java/org/elasticsearch/index/query/SpanWithinQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/SpanWithinQueryBuilder.java
@@ -31,6 +31,7 @@ import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.Objects;
+import java.util.Optional;
/**
* Builder for {@link org.apache.lucene.search.spans.SpanWithinQuery}.
@@ -107,7 +108,7 @@ public class SpanWithinQueryBuilder extends AbstractQueryBuilder<SpanWithinQuery
builder.endObject();
}
- public static SpanWithinQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<SpanWithinQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
@@ -122,17 +123,17 @@ public class SpanWithinQueryBuilder extends AbstractQueryBuilder<SpanWithinQuery
currentFieldName = parser.currentName();
} else if (token == XContentParser.Token.START_OBJECT) {
if (parseContext.getParseFieldMatcher().match(currentFieldName, BIG_FIELD)) {
- QueryBuilder query = parseContext.parseInnerQueryBuilder();
- if (query instanceof SpanQueryBuilder == false) {
+ Optional<QueryBuilder> query = parseContext.parseInnerQueryBuilder();
+ if (query.isPresent() == false || query.get() instanceof SpanQueryBuilder == false) {
throw new ParsingException(parser.getTokenLocation(), "span_within [big] must be of type span query");
}
- big = (SpanQueryBuilder) query;
+ big = (SpanQueryBuilder) query.get();
} else if (parseContext.getParseFieldMatcher().match(currentFieldName, LITTLE_FIELD)) {
- QueryBuilder query = parseContext.parseInnerQueryBuilder();
- if (query instanceof SpanQueryBuilder == false) {
+ Optional<QueryBuilder> query = parseContext.parseInnerQueryBuilder();
+ if (query.isPresent() == false || query.get() instanceof SpanQueryBuilder == false) {
throw new ParsingException(parser.getTokenLocation(), "span_within [little] must be of type span query");
}
- little = (SpanQueryBuilder) query;
+ little = (SpanQueryBuilder) query.get();
} else {
throw new ParsingException(parser.getTokenLocation(),
"[span_within] query does not support [" + currentFieldName + "]");
@@ -155,7 +156,7 @@ public class SpanWithinQueryBuilder extends AbstractQueryBuilder<SpanWithinQuery
SpanWithinQueryBuilder query = new SpanWithinQueryBuilder(big, little);
query.boost(boost).queryName(queryName);
- return query;
+ return Optional.of(query);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java
index 1a4d05374b..3b41abbbe8 100644
--- a/core/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java
@@ -21,6 +21,7 @@ package org.elasticsearch.index.query;
import org.apache.lucene.search.Query;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParseFieldMatcher;
+import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
@@ -37,6 +38,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
/**
* Facilitates creating template query requests.
@@ -120,10 +122,10 @@ public class TemplateQueryBuilder extends AbstractQueryBuilder<TemplateQueryBuil
* In the simplest case, parse template string and variables from the request,
* compile the template and execute the template against the given variables.
*/
- public static TemplateQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<TemplateQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
Template template = parse(parser, parseContext.getParseFieldMatcher());
- return new TemplateQueryBuilder(template);
+ return Optional.of(new TemplateQueryBuilder(template));
}
public static Template parse(XContentParser parser, ParseFieldMatcher parseFieldMatcher, String... parameters) throws IOException {
@@ -179,7 +181,8 @@ public class TemplateQueryBuilder extends AbstractQueryBuilder<TemplateQueryBuil
BytesReference querySource = (BytesReference) executable.run();
try (XContentParser qSourceParser = XContentFactory.xContent(querySource).createParser(querySource)) {
final QueryParseContext queryParseContext = queryRewriteContext.newParseContext(qSourceParser);
- final QueryBuilder queryBuilder = queryParseContext.parseInnerQueryBuilder();
+ final QueryBuilder queryBuilder = queryParseContext.parseInnerQueryBuilder().orElseThrow(
+ () -> new ParsingException(qSourceParser.getTokenLocation(), "inner query in [" + NAME + "] cannot be empty"));;
if (boost() != DEFAULT_BOOST || queryName() != null) {
final BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
boolQueryBuilder.must(queryBuilder);
diff --git a/core/src/main/java/org/elasticsearch/index/query/TermQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/TermQueryBuilder.java
index ffdf6a3337..bfb55c9956 100644
--- a/core/src/main/java/org/elasticsearch/index/query/TermQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/TermQueryBuilder.java
@@ -30,6 +30,7 @@ import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.MappedFieldType;
import java.io.IOException;
+import java.util.Optional;
/**
* A Query that matches documents containing a term.
@@ -84,7 +85,7 @@ public class TermQueryBuilder extends BaseTermQueryBuilder<TermQueryBuilder> {
super(in);
}
- public static TermQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<TermQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String queryName = null;
@@ -140,7 +141,7 @@ public class TermQueryBuilder extends BaseTermQueryBuilder<TermQueryBuilder> {
if (queryName != null) {
termQuery.queryName(queryName);
}
- return termQuery;
+ return Optional.of(termQuery);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java
index 5b0650eb7e..7d27a911f8 100644
--- a/core/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java
@@ -47,6 +47,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@@ -238,7 +239,7 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
builder.endObject();
}
- public static TermsQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<TermsQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String fieldName = null;
@@ -289,9 +290,9 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
throw new ParsingException(parser.getTokenLocation(), "[" + TermsQueryBuilder.NAME + "] query requires a field name, " +
"followed by array of terms or a document lookup specification");
}
- return new TermsQueryBuilder(fieldName, values, termsLookup)
+ return Optional.of(new TermsQueryBuilder(fieldName, values, termsLookup)
.boost(boost)
- .queryName(queryName);
+ .queryName(queryName));
}
private static List<Object> parseValues(XContentParser parser) throws IOException {
diff --git a/core/src/main/java/org/elasticsearch/index/query/TypeQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/TypeQueryBuilder.java
index 129b027552..00cd108c00 100644
--- a/core/src/main/java/org/elasticsearch/index/query/TypeQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/TypeQueryBuilder.java
@@ -33,6 +33,7 @@ import org.elasticsearch.index.mapper.DocumentMapper;
import java.io.IOException;
import java.util.Objects;
+import java.util.Optional;
public class TypeQueryBuilder extends AbstractQueryBuilder<TypeQueryBuilder> {
public static final String NAME = "type";
@@ -81,7 +82,7 @@ public class TypeQueryBuilder extends AbstractQueryBuilder<TypeQueryBuilder> {
builder.endObject();
}
- public static TypeQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<TypeQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
BytesRef type = null;
@@ -114,9 +115,9 @@ public class TypeQueryBuilder extends AbstractQueryBuilder<TypeQueryBuilder> {
throw new ParsingException(parser.getTokenLocation(),
"[" + TypeQueryBuilder.NAME + "] filter needs to be provided with a value for the type");
}
- return new TypeQueryBuilder(type)
+ return Optional.of(new TypeQueryBuilder(type)
.boost(boost)
- .queryName(queryName);
+ .queryName(queryName));
}
diff --git a/core/src/main/java/org/elasticsearch/index/query/WildcardQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/WildcardQueryBuilder.java
index ef49472b8c..007dff9234 100644
--- a/core/src/main/java/org/elasticsearch/index/query/WildcardQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/WildcardQueryBuilder.java
@@ -36,6 +36,7 @@ import org.elasticsearch.index.query.support.QueryParsers;
import java.io.IOException;
import java.util.Objects;
+import java.util.Optional;
/**
* Implements the wildcard search query. Supported wildcards are <tt>*</tt>, which
@@ -135,7 +136,7 @@ public class WildcardQueryBuilder extends AbstractQueryBuilder<WildcardQueryBuil
builder.endObject();
}
- public static WildcardQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<WildcardQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
XContentParser.Token token = parser.nextToken();
@@ -180,10 +181,10 @@ public class WildcardQueryBuilder extends AbstractQueryBuilder<WildcardQueryBuil
if (value == null) {
throw new ParsingException(parser.getTokenLocation(), "No value specified for wildcard query");
}
- return new WildcardQueryBuilder(fieldName, value)
+ return Optional.of(new WildcardQueryBuilder(fieldName, value)
.rewrite(rewrite)
.boost(boost)
- .queryName(queryName);
+ .queryName(queryName));
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/WrapperQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/WrapperQueryBuilder.java
index 4037666393..4e1eb83272 100644
--- a/core/src/main/java/org/elasticsearch/index/query/WrapperQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/WrapperQueryBuilder.java
@@ -33,6 +33,7 @@ import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
+import java.util.Optional;
/**
* A Query builder which allows building a query given JSON string or binary data provided as input. This is useful when you want
@@ -116,7 +117,7 @@ public class WrapperQueryBuilder extends AbstractQueryBuilder<WrapperQueryBuilde
builder.endObject();
}
- public static WrapperQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<WrapperQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
XContentParser.Token token = parser.nextToken();
@@ -136,7 +137,7 @@ public class WrapperQueryBuilder extends AbstractQueryBuilder<WrapperQueryBuilde
if (source == null) {
throw new ParsingException(parser.getTokenLocation(), "wrapper query has no [query] specified");
}
- return new WrapperQueryBuilder(source);
+ return Optional.of(new WrapperQueryBuilder(source));
}
@Override
@@ -164,7 +165,8 @@ public class WrapperQueryBuilder extends AbstractQueryBuilder<WrapperQueryBuilde
try (XContentParser qSourceParser = XContentFactory.xContent(source).createParser(source)) {
QueryParseContext parseContext = context.newParseContext(qSourceParser);
- final QueryBuilder queryBuilder = parseContext.parseInnerQueryBuilder();
+ final QueryBuilder queryBuilder = parseContext.parseInnerQueryBuilder().orElseThrow(
+ () -> new ParsingException(qSourceParser.getTokenLocation(), "inner query cannot be empty"));
if (boost() != DEFAULT_BOOST || queryName() != null) {
final BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
boolQueryBuilder.must(queryBuilder);
diff --git a/core/src/main/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilder.java
index 98f878d1c2..3e52322d22 100644
--- a/core/src/main/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilder.java
@@ -37,12 +37,13 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentLocation;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.AbstractQueryBuilder;
+import org.elasticsearch.index.query.InnerHitBuilder;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
+import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.query.QueryRewriteContext;
import org.elasticsearch.index.query.QueryShardContext;
-import org.elasticsearch.index.query.InnerHitBuilder;
import java.io.IOException;
import java.util.ArrayList;
@@ -51,6 +52,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
/**
* A query that uses a filters with a script associated with them to compute the
@@ -431,15 +433,13 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder<FunctionScor
return this;
}
-
-
@Override
protected void extractInnerHitBuilders(Map<String, InnerHitBuilder> innerHits) {
InnerHitBuilder.extractInnerHits(query(), innerHits);
}
- public static FunctionScoreQueryBuilder fromXContent(ParseFieldRegistry<ScoreFunctionParser<?>> scoreFunctionsRegistry,
- QueryParseContext parseContext) throws IOException {
+ public static Optional<FunctionScoreQueryBuilder> fromXContent(ParseFieldRegistry<ScoreFunctionParser<?>> scoreFunctionsRegistry,
+ QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
QueryBuilder query = null;
@@ -468,7 +468,7 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder<FunctionScor
throw new ParsingException(parser.getTokenLocation(), "failed to parse [{}] query. [query] is already defined.",
NAME);
}
- query = parseContext.parseInnerQueryBuilder();
+ query = parseContext.parseInnerQueryBuilder().orElse(QueryBuilders.matchAllQuery());
} else {
if (singleFunctionFound) {
throw new ParsingException(parser.getTokenLocation(),
@@ -556,7 +556,7 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder<FunctionScor
}
functionScoreQueryBuilder.boost(boost);
functionScoreQueryBuilder.queryName(queryName);
- return functionScoreQueryBuilder;
+ return Optional.of(functionScoreQueryBuilder);
}
private static void handleMisplacedFunctionsDeclaration(XContentLocation contentLocation, String errorString) {
@@ -584,7 +584,7 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder<FunctionScor
currentFieldName = parser.currentName();
} else if (token == XContentParser.Token.START_OBJECT) {
if (parseContext.getParseFieldMatcher().match(currentFieldName, FILTER_FIELD)) {
- filter = parseContext.parseInnerQueryBuilder();
+ filter = parseContext.parseInnerQueryBuilder().orElse(QueryBuilders.matchAllQuery());
} else {
if (scoreFunction != null) {
throw new ParsingException(parser.getTokenLocation(),
diff --git a/core/src/main/java/org/elasticsearch/search/SearchModule.java b/core/src/main/java/org/elasticsearch/search/SearchModule.java
index a8893c4c27..8afda85c58 100644
--- a/core/src/main/java/org/elasticsearch/search/SearchModule.java
+++ b/core/src/main/java/org/elasticsearch/search/SearchModule.java
@@ -37,7 +37,6 @@ import org.elasticsearch.index.query.BoostingQueryBuilder;
import org.elasticsearch.index.query.CommonTermsQueryBuilder;
import org.elasticsearch.index.query.ConstantScoreQueryBuilder;
import org.elasticsearch.index.query.DisMaxQueryBuilder;
-import org.elasticsearch.index.query.EmptyQueryBuilder;
import org.elasticsearch.index.query.ExistsQueryBuilder;
import org.elasticsearch.index.query.FieldMaskingSpanQueryBuilder;
import org.elasticsearch.index.query.FuzzyQueryBuilder;
@@ -698,9 +697,6 @@ public class SearchModule extends AbstractModule {
if (ShapesAvailability.JTS_AVAILABLE && ShapesAvailability.SPATIAL4J_AVAILABLE) {
registerQuery(GeoShapeQueryBuilder::new, GeoShapeQueryBuilder::fromXContent, GeoShapeQueryBuilder.QUERY_NAME_FIELD);
}
- // EmptyQueryBuilder is not registered as query parser but used internally.
- // We need to register it with the NamedWriteableRegistry in order to serialize it
- namedWriteableRegistry.register(QueryBuilder.class, EmptyQueryBuilder.NAME, EmptyQueryBuilder::new);
}
static {
diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterAggregationBuilder.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterAggregationBuilder.java
index a971035b5f..a973d69da4 100644
--- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterAggregationBuilder.java
+++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterAggregationBuilder.java
@@ -24,8 +24,6 @@ import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
-import org.elasticsearch.index.query.EmptyQueryBuilder;
-import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
@@ -55,11 +53,7 @@ public class FilterAggregationBuilder extends AbstractAggregationBuilder<FilterA
if (filter == null) {
throw new IllegalArgumentException("[filter] must not be null: [" + name + "]");
}
- if (filter instanceof EmptyQueryBuilder) {
- this.filter = new MatchAllQueryBuilder();
- } else {
- this.filter = filter;
- }
+ this.filter = filter;
}
/**
@@ -89,18 +83,12 @@ public class FilterAggregationBuilder extends AbstractAggregationBuilder<FilterA
return builder;
}
- public static FilterAggregationBuilder parse(String aggregationName, QueryParseContext context)
- throws IOException {
- QueryBuilder filter = context.parseInnerQueryBuilder();
-
- if (filter == null) {
- throw new ParsingException(null, "filter cannot be null in filter aggregation [{}]", aggregationName);
- }
-
+ public static FilterAggregationBuilder parse(String aggregationName, QueryParseContext context) throws IOException {
+ QueryBuilder filter = context.parseInnerQueryBuilder().orElseThrow(() -> new ParsingException(context.parser().getTokenLocation(),
+ "filter cannot be null in filter aggregation [{}]", aggregationName));
return new FilterAggregationBuilder(aggregationName, filter);
}
-
@Override
protected int doHashCode() {
return Objects.hash(filter);
diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersAggregationBuilder.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersAggregationBuilder.java
index 5056e3a67b..9b2b9cee7f 100644
--- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersAggregationBuilder.java
+++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersAggregationBuilder.java
@@ -26,7 +26,6 @@ import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.QueryBuilder;
-import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
@@ -235,8 +234,8 @@ public class FiltersAggregationBuilder extends AbstractAggregationBuilder<Filter
if (token == XContentParser.Token.FIELD_NAME) {
key = parser.currentName();
} else {
- QueryBuilder filter = context.parseInnerQueryBuilder();
- keyedFilters.add(new FiltersAggregator.KeyedFilter(key, filter == null ? matchAllQuery() : filter));
+ QueryBuilder filter = context.parseInnerQueryBuilder().orElse(matchAllQuery());
+ keyedFilters.add(new FiltersAggregator.KeyedFilter(key, filter));
}
}
} else {
@@ -247,8 +246,8 @@ public class FiltersAggregationBuilder extends AbstractAggregationBuilder<Filter
if (context.getParseFieldMatcher().match(currentFieldName, FILTERS_FIELD)) {
nonKeyedFilters = new ArrayList<>();
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
- QueryBuilder filter = context.parseInnerQueryBuilder();
- nonKeyedFilters.add(filter == null ? QueryBuilders.matchAllQuery() : filter);
+ QueryBuilder filter = context.parseInnerQueryBuilder().orElse(matchAllQuery());
+ nonKeyedFilters.add(filter);
}
} else {
throw new ParsingException(parser.getTokenLocation(),
diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersAggregator.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersAggregator.java
index a5ce89c466..08bbdaf3e3 100644
--- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersAggregator.java
+++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersAggregator.java
@@ -29,7 +29,6 @@ import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.common.lucene.Lucene;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
-import org.elasticsearch.index.query.EmptyQueryBuilder;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.aggregations.Aggregator;
@@ -69,11 +68,7 @@ public class FiltersAggregator extends BucketsAggregator {
throw new IllegalArgumentException("[filter] must not be null");
}
this.key = key;
- if (filter instanceof EmptyQueryBuilder) {
- this.filter = new MatchAllQueryBuilder();
- } else {
- this.filter = filter;
- }
+ this.filter = filter;
}
/**
diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsParser.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsParser.java
index 33db8f9733..ba87f0917a 100644
--- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsParser.java
+++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsParser.java
@@ -38,6 +38,7 @@ import org.elasticsearch.search.aggregations.support.ValuesSourceType;
import java.io.IOException;
import java.util.Map;
+import java.util.Optional;
/**
*
@@ -91,8 +92,10 @@ public class SignificantTermsParser extends AbstractTermsParser {
return true;
} else if (parseFieldMatcher.match(currentFieldName, SignificantTermsAggregationBuilder.BACKGROUND_FILTER)) {
QueryParseContext queryParseContext = new QueryParseContext(queriesRegistry, parser, parseFieldMatcher);
- QueryBuilder filter = queryParseContext.parseInnerQueryBuilder();
- otherOptions.put(SignificantTermsAggregationBuilder.BACKGROUND_FILTER, filter);
+ Optional<QueryBuilder> filter = queryParseContext.parseInnerQueryBuilder();
+ if (filter.isPresent()) {
+ otherOptions.put(SignificantTermsAggregationBuilder.BACKGROUND_FILTER, filter.get());
+ }
return true;
}
}
diff --git a/core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java b/core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java
index a2c2f3a0fa..4c47304330 100644
--- a/core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java
+++ b/core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java
@@ -611,7 +611,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
/**
* Add an aggregation to perform as part of the search.
*/
- public SearchSourceBuilder aggregation(PipelineAggregatorBuilder aggregation) {
+ public SearchSourceBuilder aggregation(PipelineAggregatorBuilder<?> aggregation) {
if (aggregations == null) {
aggregations = AggregatorFactories.builder();
}
@@ -1003,9 +1003,9 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
}
} else if (token == XContentParser.Token.START_OBJECT) {
if (context.getParseFieldMatcher().match(currentFieldName, QUERY_FIELD)) {
- queryBuilder = context.parseInnerQueryBuilder();
+ queryBuilder = context.parseInnerQueryBuilder().orElse(null);
} else if (context.getParseFieldMatcher().match(currentFieldName, POST_FILTER_FIELD)) {
- postQueryBuilder = context.parseInnerQueryBuilder();
+ postQueryBuilder = context.parseInnerQueryBuilder().orElse(null);
} else if (context.getParseFieldMatcher().match(currentFieldName, _SOURCE_FIELD)) {
fetchSourceContext = FetchSourceContext.parse(context);
} else if (context.getParseFieldMatcher().match(currentFieldName, SCRIPT_FIELDS_FIELD)) {
diff --git a/core/src/main/java/org/elasticsearch/search/highlight/AbstractHighlighterBuilder.java b/core/src/main/java/org/elasticsearch/search/highlight/AbstractHighlighterBuilder.java
index 557567fe35..816be79a9e 100644
--- a/core/src/main/java/org/elasticsearch/search/highlight/AbstractHighlighterBuilder.java
+++ b/core/src/main/java/org/elasticsearch/search/highlight/AbstractHighlighterBuilder.java
@@ -539,7 +539,7 @@ public abstract class AbstractHighlighterBuilder<HB extends AbstractHighlighterB
}, OPTIONS_FIELD);
parser.declareObject(HB::highlightQuery, (XContentParser p, QueryParseContext c) -> {
try {
- return c.parseInnerQueryBuilder();
+ return c.parseInnerQueryBuilder().orElse(null);
} catch (IOException e) {
throw new RuntimeException("Error parsing query", e);
}
diff --git a/core/src/main/java/org/elasticsearch/search/rescore/QueryRescorerBuilder.java b/core/src/main/java/org/elasticsearch/search/rescore/QueryRescorerBuilder.java
index e91468c805..6f59b446dc 100644
--- a/core/src/main/java/org/elasticsearch/search/rescore/QueryRescorerBuilder.java
+++ b/core/src/main/java/org/elasticsearch/search/rescore/QueryRescorerBuilder.java
@@ -26,6 +26,7 @@ import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.query.QueryBuilder;
+import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.search.rescore.QueryRescorer.QueryRescoreContext;
@@ -56,7 +57,7 @@ public class QueryRescorerBuilder extends RescoreBuilder<QueryRescorerBuilder> {
static {
QUERY_RESCORE_PARSER.declareObject(InnerBuilder::setQueryBuilder, (p, c) -> {
try {
- return c.parseInnerQueryBuilder();
+ return c.parseInnerQueryBuilder().orElse(QueryBuilders.matchAllQuery());
} catch (IOException e) {
throw new ParsingException(p.getTokenLocation(), "Could not parse inner query", e);
}
diff --git a/core/src/main/java/org/elasticsearch/search/sort/FieldSortBuilder.java b/core/src/main/java/org/elasticsearch/search/sort/FieldSortBuilder.java
index 892673f890..d519f74087 100644
--- a/core/src/main/java/org/elasticsearch/search/sort/FieldSortBuilder.java
+++ b/core/src/main/java/org/elasticsearch/search/sort/FieldSortBuilder.java
@@ -39,6 +39,7 @@ import org.elasticsearch.search.MultiValueMode;
import java.io.IOException;
import java.util.Objects;
+import java.util.Optional;
/**
* A sort builder to sort based on a document field.
@@ -328,7 +329,7 @@ public class FieldSortBuilder extends SortBuilder<FieldSortBuilder> {
public static FieldSortBuilder fromXContent(QueryParseContext context, String fieldName) throws IOException {
XContentParser parser = context.parser();
- QueryBuilder nestedFilter = null;
+ Optional<QueryBuilder> nestedFilter = Optional.empty();
String nestedPath = null;
Object missing = null;
SortOrder order = null;
@@ -371,9 +372,7 @@ public class FieldSortBuilder extends SortBuilder<FieldSortBuilder> {
}
FieldSortBuilder builder = new FieldSortBuilder(fieldName);
- if (nestedFilter != null) {
- builder.setNestedFilter(nestedFilter);
- }
+ nestedFilter.ifPresent(builder::setNestedFilter);
if (nestedPath != null) {
builder.setNestedPath(nestedPath);
}
diff --git a/core/src/main/java/org/elasticsearch/search/sort/GeoDistanceSortBuilder.java b/core/src/main/java/org/elasticsearch/search/sort/GeoDistanceSortBuilder.java
index dce9a7ec3f..f33dd0e2b1 100644
--- a/core/src/main/java/org/elasticsearch/search/sort/GeoDistanceSortBuilder.java
+++ b/core/src/main/java/org/elasticsearch/search/sort/GeoDistanceSortBuilder.java
@@ -60,6 +60,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
+import java.util.Optional;
/**
* A geo distance based sorting on a geo point like field.
@@ -257,7 +258,7 @@ public class GeoDistanceSortBuilder extends SortBuilder<GeoDistanceSortBuilder>
}
/**
- * Sets validation method for this sort builder.
+ * Sets validation method for this sort builder.
*/
public GeoDistanceSortBuilder validation(GeoValidationMethod method) {
this.validation = method;
@@ -265,7 +266,7 @@ public class GeoDistanceSortBuilder extends SortBuilder<GeoDistanceSortBuilder>
}
/**
- * Returns the validation method to use for this sort builder.
+ * Returns the validation method to use for this sort builder.
*/
public GeoValidationMethod validation() {
return validation;
@@ -407,7 +408,7 @@ public class GeoDistanceSortBuilder extends SortBuilder<GeoDistanceSortBuilder>
GeoDistance geoDistance = GeoDistance.DEFAULT;
SortOrder order = SortOrder.ASC;
SortMode sortMode = null;
- QueryBuilder nestedFilter = null;
+ Optional<QueryBuilder> nestedFilter = Optional.empty();
String nestedPath = null;
boolean coerce = GeoValidationMethod.DEFAULT_LENIENT_PARSING;
@@ -492,7 +493,7 @@ public class GeoDistanceSortBuilder extends SortBuilder<GeoDistanceSortBuilder>
if (sortMode != null) {
result.sortMode(sortMode);
}
- result.setNestedFilter(nestedFilter);
+ nestedFilter.ifPresent(result::setNestedFilter);
result.setNestedPath(nestedPath);
if (validation == null) {
// looks like either validation was left unset or we are parsing old validation json
@@ -517,7 +518,7 @@ public class GeoDistanceSortBuilder extends SortBuilder<GeoDistanceSortBuilder>
for (GeoPoint point : localPoints) {
if (GeoUtils.isValidLatitude(point.lat()) == false) {
throw new ElasticsearchParseException(
- "illegal latitude value [{}] for [GeoDistanceSort] for field [{}].",
+ "illegal latitude value [{}] for [GeoDistanceSort] for field [{}].",
point.lat(),
fieldName);
}
diff --git a/core/src/main/java/org/elasticsearch/search/sort/ScriptSortBuilder.java b/core/src/main/java/org/elasticsearch/search/sort/ScriptSortBuilder.java
index eeb418c0a9..f7baee509d 100644
--- a/core/src/main/java/org/elasticsearch/search/sort/ScriptSortBuilder.java
+++ b/core/src/main/java/org/elasticsearch/search/sort/ScriptSortBuilder.java
@@ -61,6 +61,7 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
/**
* Script sort builder allows to sort based on a custom script expression.
@@ -237,7 +238,7 @@ public class ScriptSortBuilder extends SortBuilder<ScriptSortBuilder> {
ScriptSortType type = null;
SortMode sortMode = null;
SortOrder order = null;
- QueryBuilder nestedFilter = null;
+ Optional<QueryBuilder> nestedFilter = Optional.empty();
String nestedPath = null;
Map<String, Object> params = new HashMap<>();
@@ -292,9 +293,7 @@ public class ScriptSortBuilder extends SortBuilder<ScriptSortBuilder> {
if (sortMode != null) {
result.sortMode(sortMode);
}
- if (nestedFilter != null) {
- result.setNestedFilter(nestedFilter);
- }
+ nestedFilter.ifPresent(result::setNestedFilter);
if (nestedPath != null) {
result.setNestedPath(nestedPath);
}
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggester.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggester.java
index 9aed90f55e..25f589794f 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggester.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggester.java
@@ -34,7 +34,9 @@ import org.elasticsearch.common.lucene.Lucene;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
+import org.elasticsearch.index.query.MatchNoneQueryBuilder;
import org.elasticsearch.index.query.ParsedQuery;
+import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.script.CompiledScript;
@@ -53,6 +55,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
public final class PhraseSuggester extends Suggester<PhraseSuggestionContext> {
private final BytesRef SEPARATOR = new BytesRef(" ");
@@ -123,7 +126,8 @@ public final class PhraseSuggester extends Suggester<PhraseSuggestionContext> {
final ExecutableScript executable = scriptService.executable(collateScript, vars);
final BytesReference querySource = (BytesReference) executable.run();
try (XContentParser parser = XContentFactory.xContent(querySource).createParser(querySource)) {
- final ParsedQuery parsedQuery = shardContext.toQuery(shardContext.newParseContext(parser).parseInnerQueryBuilder());
+ Optional<QueryBuilder> innerQueryBuilder = shardContext.newParseContext(parser).parseInnerQueryBuilder();
+ final ParsedQuery parsedQuery = shardContext.toQuery(innerQueryBuilder.orElse(new MatchNoneQueryBuilder()));
collateMatch = Lucene.exists(searcher, parsedQuery.query());
}
}
diff --git a/core/src/test/java/org/elasticsearch/index/query/BoolQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/BoolQueryBuilderTests.java
index 15180b9d98..89da227df8 100644
--- a/core/src/test/java/org/elasticsearch/index/query/BoolQueryBuilderTests.java
+++ b/core/src/test/java/org/elasticsearch/index/query/BoolQueryBuilderTests.java
@@ -24,6 +24,7 @@ import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.ConstantScoreQuery;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.Query;
+import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
@@ -43,6 +44,7 @@ import static org.elasticsearch.index.query.QueryBuilders.constantScoreQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.startsWith;
public class BoolQueryBuilderTests extends AbstractQueryTestCase<BoolQueryBuilder> {
@Override
@@ -345,6 +347,29 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase<BoolQueryBuilde
assertEquals(query, "kimchy", ((TermQueryBuilder)queryBuilder.must().get(0)).value());
}
+ /**
+ * we ignore empty query bodies if we are not in strict mode
+ */
+ public void testFromJsonEmptyQueryBody() throws IOException {
+ String query =
+ "{" +
+ "\"bool\" : {" +
+ " \"must\" : [ { } ]," +
+ " \"filter\" : { }," +
+ " \"must_not\" : [ { \"constant_score\" : {\"filter\" : { } } } ]" +
+ "}" +
+ "}";
+
+ BoolQueryBuilder queryBuilder = (BoolQueryBuilder) parseQuery(query, ParseFieldMatcher.EMPTY);
+ assertEquals(query, 0, queryBuilder.must().size());
+ assertEquals(query, 0, queryBuilder.filter().size());
+ assertEquals(query, 0, queryBuilder.mustNot().size());
+ assertEquals(query, 0, queryBuilder.should().size());
+
+ IllegalArgumentException ex = expectThrows(IllegalArgumentException.class, () -> parseQuery(query, ParseFieldMatcher.STRICT));
+ assertThat(ex.getMessage(), startsWith("query malformed, empty clause found at"));
+ }
+
public void testRewrite() throws IOException {
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
boolean mustRewrite = false;
diff --git a/core/src/test/java/org/elasticsearch/index/query/BoostingQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/BoostingQueryBuilderTests.java
index 34c15d6357..343c627074 100644
--- a/core/src/test/java/org/elasticsearch/index/query/BoostingQueryBuilderTests.java
+++ b/core/src/test/java/org/elasticsearch/index/query/BoostingQueryBuilderTests.java
@@ -21,12 +21,17 @@ package org.elasticsearch.index.query;
import org.apache.lucene.queries.BoostingQuery;
import org.apache.lucene.search.Query;
+import org.elasticsearch.common.ParseFieldMatcher;
+import org.elasticsearch.common.xcontent.XContentFactory;
+import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.test.AbstractQueryTestCase;
import java.io.IOException;
+import java.util.Optional;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.CoreMatchers.startsWith;;
public class BoostingQueryBuilderTests extends AbstractQueryTestCase<BoostingQueryBuilder> {
@@ -105,6 +110,40 @@ public class BoostingQueryBuilderTests extends AbstractQueryTestCase<BoostingQue
assertEquals(query, 5, queryBuilder.positiveQuery().boost(), 0.00001);
}
+ /**
+ * we bubble up empty inner clauses as an empty optional
+ */
+ public void testFromJsonEmptyQueryBody() throws IOException {
+ String query =
+ "{ \"boosting\" : {" +
+ " \"positive\" : { }, " +
+ " \"negative\" : { \"match_all\" : {} }, " +
+ " \"negative_boost\" : 23.0" +
+ " }" +
+ "}";
+ XContentParser parser = XContentFactory.xContent(query).createParser(query);
+ QueryParseContext context = createParseContext(parser, ParseFieldMatcher.EMPTY);
+ Optional<QueryBuilder> innerQueryBuilder = context.parseInnerQueryBuilder();
+ assertTrue(innerQueryBuilder.isPresent() == false);
+
+ query =
+ "{ \"boosting\" : {" +
+ " \"positive\" : { \"match_all\" : {} }, " +
+ " \"negative\" : { }, " +
+ " \"negative_boost\" : 23.0" +
+ " }" +
+ "}";
+ parser = XContentFactory.xContent(query).createParser(query);
+ context = createParseContext(parser, ParseFieldMatcher.EMPTY);
+ innerQueryBuilder = context.parseInnerQueryBuilder();
+ assertTrue(innerQueryBuilder.isPresent() == false);
+
+ parser = XContentFactory.xContent(query).createParser(query);
+ QueryParseContext otherContext = createParseContext(parser, ParseFieldMatcher.STRICT);
+ IllegalArgumentException ex = expectThrows(IllegalArgumentException.class, () -> otherContext.parseInnerQueryBuilder());
+ assertThat(ex.getMessage(), startsWith("query malformed, empty clause found at"));
+ }
+
public void testRewrite() throws IOException {
QueryBuilder positive = randomBoolean() ? new MatchAllQueryBuilder() : new WrapperQueryBuilder(new TermQueryBuilder("pos", "bar").toString());
QueryBuilder negative = randomBoolean() ? new MatchAllQueryBuilder() : new WrapperQueryBuilder(new TermQueryBuilder("neg", "bar").toString());
diff --git a/core/src/test/java/org/elasticsearch/index/query/ConstantScoreQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/ConstantScoreQueryBuilderTests.java
index c24dd25b98..86381c135a 100644
--- a/core/src/test/java/org/elasticsearch/index/query/ConstantScoreQueryBuilderTests.java
+++ b/core/src/test/java/org/elasticsearch/index/query/ConstantScoreQueryBuilderTests.java
@@ -21,13 +21,18 @@ package org.elasticsearch.index.query;
import org.apache.lucene.search.ConstantScoreQuery;
import org.apache.lucene.search.Query;
+import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.ParsingException;
+import org.elasticsearch.common.xcontent.XContentFactory;
+import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.test.AbstractQueryTestCase;
import java.io.IOException;
+import java.util.Optional;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.CoreMatchers.startsWith;
import static org.hamcrest.Matchers.containsString;
public class ConstantScoreQueryBuilderTests extends AbstractQueryTestCase<ConstantScoreQueryBuilder> {
@@ -126,4 +131,24 @@ public class ConstantScoreQueryBuilderTests extends AbstractQueryTestCase<Consta
assertEquals(json, 42.0, parsed.innerQuery().boost(), 0.0001);
}
+ /**
+ * we bubble up empty query bodies as an empty optional
+ */
+ public void testFromJsonEmptyQueryBody() throws IOException {
+ String query =
+ "{ \"constant_score\" : {" +
+ " \"filter\" : { }" +
+ " }" +
+ "}";
+ XContentParser parser = XContentFactory.xContent(query).createParser(query);
+ QueryParseContext context = createParseContext(parser, ParseFieldMatcher.EMPTY);
+ Optional<QueryBuilder> innerQueryBuilder = context.parseInnerQueryBuilder();
+ assertTrue(innerQueryBuilder.isPresent() == false);
+
+ parser = XContentFactory.xContent(query).createParser(query);
+ QueryParseContext otherContext = createParseContext(parser, ParseFieldMatcher.STRICT);
+ IllegalArgumentException ex = expectThrows(IllegalArgumentException.class, () -> otherContext.parseInnerQueryBuilder());
+ assertThat(ex.getMessage(), startsWith("query malformed, empty clause found at"));
+ }
+
}
diff --git a/core/src/test/java/org/elasticsearch/index/query/DisMaxQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/DisMaxQueryBuilderTests.java
index 6d2348660c..61c786d1b0 100644
--- a/core/src/test/java/org/elasticsearch/index/query/DisMaxQueryBuilderTests.java
+++ b/core/src/test/java/org/elasticsearch/index/query/DisMaxQueryBuilderTests.java
@@ -24,6 +24,7 @@ import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.DisjunctionMaxQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
+import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.test.AbstractQueryTestCase;
import java.io.IOException;
@@ -96,15 +97,16 @@ public class DisMaxQueryBuilderTests extends AbstractQueryTestCase<DisMaxQueryBu
}
/**
- * Test inner query parsing to null. Current DSL allows inner filter element to parse to <tt>null</tt>.
- * Those should be ignored upstream. To test this, we use inner {@link ConstantScoreQueryBuilder}
- * with empty inner filter.
+ * Test with empty inner query body, this should be ignored upstream.
+ * To test this, we use inner {@link ConstantScoreQueryBuilder} with empty inner filter.
*/
- public void testInnerQueryReturnsNull() throws IOException {
- String queryString = "{ \"" + ConstantScoreQueryBuilder.NAME + "\" : { \"filter\" : { } } }";
- QueryBuilder innerQueryBuilder = parseQuery(queryString);
- DisMaxQueryBuilder disMaxBuilder = new DisMaxQueryBuilder().add(innerQueryBuilder);
- assertNull(disMaxBuilder.toQuery(createShardContext()));
+ public void testInnerQueryEmptyIgnored() throws IOException {
+ String queryString = "{ \"" + DisMaxQueryBuilder.NAME + "\" :"
+ + " { \"queries\" : [ {\"" + ConstantScoreQueryBuilder.NAME + "\" : { \"filter\" : { } } } ] "
+ + " }"
+ + " }";
+ DisMaxQueryBuilder builder = (DisMaxQueryBuilder) parseQuery(queryString, ParseFieldMatcher.EMPTY);
+ assertTrue("the inner query has an empty body, so it should be ignored", builder.innerQueries().isEmpty());
}
public void testIllegalArguments() {
diff --git a/core/src/test/java/org/elasticsearch/index/query/HasChildQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/HasChildQueryBuilderTests.java
index 1c6a99ca09..d0a924be0a 100644
--- a/core/src/test/java/org/elasticsearch/index/query/HasChildQueryBuilderTests.java
+++ b/core/src/test/java/org/elasticsearch/index/query/HasChildQueryBuilderTests.java
@@ -35,9 +35,12 @@ import org.apache.lucene.search.similarities.Similarity;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
+import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.common.xcontent.XContentFactory;
+import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.Uid;
import org.elasticsearch.index.mapper.internal.TypeFieldMapper;
@@ -56,11 +59,13 @@ import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import java.util.Optional;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.CoreMatchers.startsWith;
import static org.hamcrest.Matchers.is;
public class HasChildQueryBuilderTests extends AbstractQueryTestCase<HasChildQueryBuilder> {
@@ -116,16 +121,11 @@ public class HasChildQueryBuilderTests extends AbstractQueryTestCase<HasChildQue
@Override
protected void doAssertLuceneQuery(HasChildQueryBuilder queryBuilder, Query query, QueryShardContext context) throws IOException {
- QueryBuilder innerQueryBuilder = queryBuilder.query();
- if (innerQueryBuilder instanceof EmptyQueryBuilder) {
- assertNull(query);
- } else {
- assertThat(query, instanceOf(HasChildQueryBuilder.LateParsingQuery.class));
- HasChildQueryBuilder.LateParsingQuery lpq = (HasChildQueryBuilder.LateParsingQuery) query;
- assertEquals(queryBuilder.minChildren(), lpq.getMinChildren());
- assertEquals(queryBuilder.maxChildren(), lpq.getMaxChildren());
- assertEquals(queryBuilder.scoreMode(), lpq.getScoreMode()); // WTF is this why do we have two?
- }
+ assertThat(query, instanceOf(HasChildQueryBuilder.LateParsingQuery.class));
+ HasChildQueryBuilder.LateParsingQuery lpq = (HasChildQueryBuilder.LateParsingQuery) query;
+ assertEquals(queryBuilder.minChildren(), lpq.getMinChildren());
+ assertEquals(queryBuilder.maxChildren(), lpq.getMaxChildren());
+ assertEquals(queryBuilder.scoreMode(), lpq.getScoreMode()); // WTF is this why do we have two?
if (queryBuilder.innerHit() != null) {
SearchContext searchContext = SearchContext.current();
assertNotNull(searchContext);
@@ -224,8 +224,29 @@ public class HasChildQueryBuilderTests extends AbstractQueryTestCase<HasChildQue
.setSize(100)
.addSort(new FieldSortBuilder("mapped_string").order(SortOrder.ASC));
assertEquals(query, queryBuilder.innerHit(), expected);
+ }
+ /**
+ * we resolve empty inner clauses by representing this whole query as empty optional upstream
+ */
+ public void testFromJsonEmptyQueryBody() throws IOException {
+ String query = "{\n" +
+ " \"has_child\" : {\n" +
+ " \"query\" : { },\n" +
+ " \"type\" : \"child\"" +
+ " }" +
+ "}";
+ XContentParser parser = XContentFactory.xContent(query).createParser(query);
+ QueryParseContext context = createParseContext(parser, ParseFieldMatcher.EMPTY);
+ Optional<QueryBuilder> innerQueryBuilder = context.parseInnerQueryBuilder();
+ assertTrue(innerQueryBuilder.isPresent() == false);
+
+ parser = XContentFactory.xContent(query).createParser(query);
+ QueryParseContext otherContext = createParseContext(parser, ParseFieldMatcher.STRICT);
+ IllegalArgumentException ex = expectThrows(IllegalArgumentException.class, () -> otherContext.parseInnerQueryBuilder());
+ assertThat(ex.getMessage(), startsWith("query malformed, empty clause found at"));
}
+
public void testToQueryInnerQueryType() throws IOException {
String[] searchTypes = new String[]{PARENT_TYPE};
QueryShardContext shardContext = createShardContext();
diff --git a/core/src/test/java/org/elasticsearch/index/query/HasParentQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/HasParentQueryBuilderTests.java
index 7b700cbfc7..c4ba395db5 100644
--- a/core/src/test/java/org/elasticsearch/index/query/HasParentQueryBuilderTests.java
+++ b/core/src/test/java/org/elasticsearch/index/query/HasParentQueryBuilderTests.java
@@ -32,6 +32,7 @@ import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
+import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.script.Script.ScriptParseException;
import org.elasticsearch.search.fetch.innerhits.InnerHitsContext;
@@ -45,11 +46,13 @@ import org.junit.BeforeClass;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
+import java.util.Optional;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.CoreMatchers.startsWith;
public class HasParentQueryBuilderTests extends AbstractQueryTestCase<HasParentQueryBuilder> {
protected static final String PARENT_TYPE = "parent";
@@ -99,14 +102,10 @@ public class HasParentQueryBuilderTests extends AbstractQueryTestCase<HasParentQ
@Override
protected void doAssertLuceneQuery(HasParentQueryBuilder queryBuilder, Query query, QueryShardContext context) throws IOException {
- QueryBuilder innerQueryBuilder = queryBuilder.query();
- if (innerQueryBuilder instanceof EmptyQueryBuilder) {
- assertNull(query);
- } else {
- assertThat(query, instanceOf(HasChildQueryBuilder.LateParsingQuery.class));
- HasChildQueryBuilder.LateParsingQuery lpq = (HasChildQueryBuilder.LateParsingQuery) query;
- assertEquals(queryBuilder.score() ? ScoreMode.Max : ScoreMode.None, lpq.getScoreMode());
- }
+ assertThat(query, instanceOf(HasChildQueryBuilder.LateParsingQuery.class));
+ HasChildQueryBuilder.LateParsingQuery lpq = (HasChildQueryBuilder.LateParsingQuery) query;
+ assertEquals(queryBuilder.score() ? ScoreMode.Max : ScoreMode.None, lpq.getScoreMode());
+
if (queryBuilder.innerHit() != null) {
SearchContext searchContext = SearchContext.current();
assertNotNull(searchContext);
@@ -231,6 +230,27 @@ public class HasParentQueryBuilderTests extends AbstractQueryTestCase<HasParentQ
assertEquals(json, "something", ((TermQueryBuilder) parsed.query()).value());
}
+ /**
+ * we resolve empty inner clauses by representing this whole query as empty optional upstream
+ */
+ public void testFromJsonEmptyQueryBody() throws IOException {
+ String query = "{\n" +
+ " \"has_parent\" : {\n" +
+ " \"query\" : { },\n" +
+ " \"parent_type\" : \"blog\"" +
+ " }" +
+ "}";
+ XContentParser parser = XContentFactory.xContent(query).createParser(query);
+ QueryParseContext context = createParseContext(parser, ParseFieldMatcher.EMPTY);
+ Optional<QueryBuilder> innerQueryBuilder = context.parseInnerQueryBuilder();
+ assertTrue(innerQueryBuilder.isPresent() == false);
+
+ parser = XContentFactory.xContent(query).createParser(query);
+ QueryParseContext otherContext = createParseContext(parser, ParseFieldMatcher.STRICT);
+ IllegalArgumentException ex = expectThrows(IllegalArgumentException.class, () -> otherContext.parseInnerQueryBuilder());
+ assertThat(ex.getMessage(), startsWith("query malformed, empty clause found at"));
+ }
+
public void testIgnoreUnmapped() throws IOException {
final HasParentQueryBuilder queryBuilder = new HasParentQueryBuilder("unmapped", new MatchAllQueryBuilder(), false);
queryBuilder.ignoreUnmapped(true);
diff --git a/core/src/test/java/org/elasticsearch/index/query/NestedQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/NestedQueryBuilderTests.java
index 04bbadb02c..d93bcce6dc 100644
--- a/core/src/test/java/org/elasticsearch/index/query/NestedQueryBuilderTests.java
+++ b/core/src/test/java/org/elasticsearch/index/query/NestedQueryBuilderTests.java
@@ -83,13 +83,9 @@ public class NestedQueryBuilderTests extends AbstractQueryTestCase<NestedQueryBu
@Override
protected void doAssertLuceneQuery(NestedQueryBuilder queryBuilder, Query query, QueryShardContext context) throws IOException {
QueryBuilder innerQueryBuilder = queryBuilder.query();
- if (innerQueryBuilder instanceof EmptyQueryBuilder) {
- assertNull(query);
- } else {
- assertThat(query, instanceOf(ToParentBlockJoinQuery.class));
- ToParentBlockJoinQuery parentBlockJoinQuery = (ToParentBlockJoinQuery) query;
- //TODO how to assert this?
- }
+ assertThat(query, instanceOf(ToParentBlockJoinQuery.class));
+ ToParentBlockJoinQuery parentBlockJoinQuery = (ToParentBlockJoinQuery) query;
+ // TODO how to assert this?
if (queryBuilder.innerHit() != null) {
SearchContext searchContext = SearchContext.current();
assertNotNull(searchContext);
diff --git a/core/src/test/java/org/elasticsearch/index/query/RandomQueryBuilder.java b/core/src/test/java/org/elasticsearch/index/query/RandomQueryBuilder.java
index cf4921b7a4..c244273d13 100644
--- a/core/src/test/java/org/elasticsearch/index/query/RandomQueryBuilder.java
+++ b/core/src/test/java/org/elasticsearch/index/query/RandomQueryBuilder.java
@@ -38,7 +38,7 @@ public class RandomQueryBuilder {
* @return a random {@link QueryBuilder}
*/
public static QueryBuilder createQuery(Random r) {
- switch (RandomInts.randomIntBetween(r, 0, 4)) {
+ switch (RandomInts.randomIntBetween(r, 0, 3)) {
case 0:
return new MatchAllQueryBuilderTests().createTestQueryBuilder();
case 1:
@@ -47,8 +47,6 @@ public class RandomQueryBuilder {
return new IdsQueryBuilderTests().createTestQueryBuilder();
case 3:
return createMultiTermQuery(r);
- case 4:
- return new EmptyQueryBuilder();
default:
throw new UnsupportedOperationException();
}
diff --git a/core/src/test/java/org/elasticsearch/index/query/TermsQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/TermsQueryBuilderTests.java
index a8bdeb6936..985669394d 100644
--- a/core/src/test/java/org/elasticsearch/index/query/TermsQueryBuilderTests.java
+++ b/core/src/test/java/org/elasticsearch/index/query/TermsQueryBuilderTests.java
@@ -239,25 +239,25 @@ public class TermsQueryBuilderTests extends AbstractQueryTestCase<TermsQueryBuil
public void testNumeric() throws IOException {
{
TermsQueryBuilder builder = new TermsQueryBuilder("foo", new int[]{1, 3, 4});
- TermsQueryBuilder copy = assertSerialization(builder);
+ TermsQueryBuilder copy = (TermsQueryBuilder) assertSerialization(builder);
List<Object> values = copy.values();
assertEquals(Arrays.asList(1, 3, 4), values);
}
{
TermsQueryBuilder builder = new TermsQueryBuilder("foo", new double[]{1, 3, 4});
- TermsQueryBuilder copy = assertSerialization(builder);
+ TermsQueryBuilder copy = (TermsQueryBuilder) assertSerialization(builder);
List<Object> values = copy.values();
assertEquals(Arrays.asList(1d, 3d, 4d), values);
}
{
TermsQueryBuilder builder = new TermsQueryBuilder("foo", new float[]{1, 3, 4});
- TermsQueryBuilder copy = assertSerialization(builder);
+ TermsQueryBuilder copy = (TermsQueryBuilder) assertSerialization(builder);
List<Object> values = copy.values();
assertEquals(Arrays.asList(1f, 3f, 4f), values);
}
{
TermsQueryBuilder builder = new TermsQueryBuilder("foo", new long[]{1, 3, 4});
- TermsQueryBuilder copy = assertSerialization(builder);
+ TermsQueryBuilder copy = (TermsQueryBuilder) assertSerialization(builder);
List<Object> values = copy.values();
assertEquals(Arrays.asList(1L, 3L, 4L), values);
}
diff --git a/core/src/test/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilderTests.java
index 52632edcf4..2597675095 100644
--- a/core/src/test/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilderTests.java
+++ b/core/src/test/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilderTests.java
@@ -26,6 +26,7 @@ import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.elasticsearch.common.ParseField;
+import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.io.stream.StreamInput;
@@ -599,8 +600,30 @@ public class FunctionScoreQueryBuilderTests extends AbstractQueryTestCase<Functi
" }\n" +
"}";
- FunctionScoreQueryBuilder parsed = (FunctionScoreQueryBuilder) parseQuery(json);
- checkGeneratedJson(json, parsed);
+ FunctionScoreQueryBuilder parsed = (FunctionScoreQueryBuilder) parseQuery(json, ParseFieldMatcher.EMPTY);
+ // this should be equivalent to the same with a match_all query
+ String expected =
+ "{\n" +
+ " \"function_score\" : {\n" +
+ " \"query\" : { \"match_all\" : {} },\n" +
+ " \"functions\" : [ {\n" +
+ " \"filter\" : { },\n" +
+ " \"weight\" : 23.0,\n" +
+ " \"random_score\" : { }\n" +
+ " }, {\n" +
+ " \"filter\" : { },\n" +
+ " \"weight\" : 5.0\n" +
+ " } ],\n" +
+ " \"score_mode\" : \"multiply\",\n" +
+ " \"boost_mode\" : \"multiply\",\n" +
+ " \"max_boost\" : 100.0,\n" +
+ " \"min_score\" : 1.0,\n" +
+ " \"boost\" : 42.0\n" +
+ " }\n" +
+ "}";
+
+ FunctionScoreQueryBuilder expectedParsed = (FunctionScoreQueryBuilder) parseQuery(json, ParseFieldMatcher.EMPTY);
+ assertEquals(expectedParsed, parsed);
assertEquals(json, 2, parsed.filterFunctionBuilders().length);
assertEquals(json, 42, parsed.boost(), 0.0001);
diff --git a/core/src/test/java/org/elasticsearch/index/query/plugin/CustomQueryParserIT.java b/core/src/test/java/org/elasticsearch/index/query/plugin/CustomQueryParserIT.java
index ec405bd840..ba87b29370 100644
--- a/core/src/test/java/org/elasticsearch/index/query/plugin/CustomQueryParserIT.java
+++ b/core/src/test/java/org/elasticsearch/index/query/plugin/CustomQueryParserIT.java
@@ -59,11 +59,11 @@ public class CustomQueryParserIT extends ESIntegTestCase {
}
public void testCustomDummyQuery() {
- assertHitCount(client().prepareSearch("index").setQuery(new DummyQueryParserPlugin.DummyQueryBuilder()).get(), 1L);
+ assertHitCount(client().prepareSearch("index").setQuery(new DummyQueryBuilder()).get(), 1L);
}
public void testCustomDummyQueryWithinBooleanQuery() {
- assertHitCount(client().prepareSearch("index").setQuery(new BoolQueryBuilder().must(new DummyQueryParserPlugin.DummyQueryBuilder())).get(), 1L);
+ assertHitCount(client().prepareSearch("index").setQuery(new BoolQueryBuilder().must(new DummyQueryBuilder())).get(), 1L);
}
private static QueryShardContext queryShardContext() {
@@ -73,7 +73,7 @@ public class CustomQueryParserIT extends ESIntegTestCase {
//see #11120
public void testConstantScoreParsesFilter() throws Exception {
- Query q = constantScoreQuery(new DummyQueryParserPlugin.DummyQueryBuilder()).toQuery(queryShardContext());
+ Query q = constantScoreQuery(new DummyQueryBuilder()).toQuery(queryShardContext());
Query inner = ((ConstantScoreQuery) q).getQuery();
assertThat(inner, instanceOf(DummyQueryParserPlugin.DummyQuery.class));
assertEquals(true, ((DummyQueryParserPlugin.DummyQuery) inner).isFilter);
@@ -83,10 +83,10 @@ public class CustomQueryParserIT extends ESIntegTestCase {
public void testBooleanParsesFilter() throws Exception {
// single clause, serialized as inner object
Query q = boolQuery()
- .should(new DummyQueryParserPlugin.DummyQueryBuilder())
- .must(new DummyQueryParserPlugin.DummyQueryBuilder())
- .filter(new DummyQueryParserPlugin.DummyQueryBuilder())
- .mustNot(new DummyQueryParserPlugin.DummyQueryBuilder()).toQuery(queryShardContext());
+ .should(new DummyQueryBuilder())
+ .must(new DummyQueryBuilder())
+ .filter(new DummyQueryBuilder())
+ .mustNot(new DummyQueryBuilder()).toQuery(queryShardContext());
assertThat(q, instanceOf(BooleanQuery.class));
BooleanQuery bq = (BooleanQuery) q;
assertEquals(4, bq.clauses().size());
@@ -108,10 +108,10 @@ public class CustomQueryParserIT extends ESIntegTestCase {
// multiple clauses, serialized as inner arrays
q = boolQuery()
- .should(new DummyQueryParserPlugin.DummyQueryBuilder()).should(new DummyQueryParserPlugin.DummyQueryBuilder())
- .must(new DummyQueryParserPlugin.DummyQueryBuilder()).must(new DummyQueryParserPlugin.DummyQueryBuilder())
- .filter(new DummyQueryParserPlugin.DummyQueryBuilder()).filter(new DummyQueryParserPlugin.DummyQueryBuilder())
- .mustNot(new DummyQueryParserPlugin.DummyQueryBuilder()).mustNot(new DummyQueryParserPlugin.DummyQueryBuilder()).toQuery(queryShardContext());
+ .should(new DummyQueryBuilder()).should(new DummyQueryBuilder())
+ .must(new DummyQueryBuilder()).must(new DummyQueryBuilder())
+ .filter(new DummyQueryBuilder()).filter(new DummyQueryBuilder())
+ .mustNot(new DummyQueryBuilder()).mustNot(new DummyQueryBuilder()).toQuery(queryShardContext());
assertThat(q, instanceOf(BooleanQuery.class));
bq = (BooleanQuery) q;
assertEquals(8, bq.clauses().size());
diff --git a/core/src/main/java/org/elasticsearch/index/query/EmptyQueryBuilder.java b/core/src/test/java/org/elasticsearch/index/query/plugin/DummyQueryBuilder.java
index 3d09bb41b0..334244559c 100644
--- a/core/src/main/java/org/elasticsearch/index/query/EmptyQueryBuilder.java
+++ b/core/src/test/java/org/elasticsearch/index/query/plugin/DummyQueryBuilder.java
@@ -17,67 +17,66 @@
* under the License.
*/
-package org.elasticsearch.index.query;
+package org.elasticsearch.index.query.plugin;
import org.apache.lucene.search.Query;
+import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.XContentParser;
+import org.elasticsearch.index.query.AbstractQueryBuilder;
+import org.elasticsearch.index.query.QueryParseContext;
+import org.elasticsearch.index.query.QueryShardContext;
+import org.elasticsearch.index.query.plugin.DummyQueryParserPlugin.DummyQuery;
import java.io.IOException;
+import java.util.Optional;
-/**
- * A {@link QueryBuilder} that is a stand in replacement for an empty query clause in the DSL.
- * The current DSL allows parsing inner queries / filters like "{ }", in order to have a
- * valid non-null representation of these clauses that actually do nothing we can use this class.
- */
-public final class EmptyQueryBuilder extends AbstractQueryBuilder<EmptyQueryBuilder> {
-
- public static final String NAME = "empty_query";
+public class DummyQueryBuilder extends AbstractQueryBuilder<DummyQueryBuilder> {
+ private static final String NAME = "dummy";
+ static final ParseField QUERY_NAME_FIELD = new ParseField(NAME);
- /**
- * Construct an empty query. This query can *technically* be named and given a boost.
- */
- public EmptyQueryBuilder() {
+ public DummyQueryBuilder() {
}
- /**
- * Read from a stream.
- */
- public EmptyQueryBuilder(StreamInput in) throws IOException {
+ public DummyQueryBuilder(StreamInput in) throws IOException {
super(in);
}
@Override
protected void doWriteTo(StreamOutput out) throws IOException {
+ // only the superclass has state
}
@Override
- public String getWriteableName() {
- return NAME;
+ protected void doXContent(XContentBuilder builder, Params params) throws IOException {
+ builder.startObject(NAME).endObject();
}
- @Override
- protected Query doToQuery(QueryShardContext context) throws IOException {
- return null;
+ public static Optional<DummyQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
+ XContentParser.Token token = parseContext.parser().nextToken();
+ assert token == XContentParser.Token.END_OBJECT;
+ return Optional.of(new DummyQueryBuilder());
}
@Override
- public String getName() {
- return getWriteableName();
+ protected Query doToQuery(QueryShardContext context) throws IOException {
+ return new DummyQuery(context.isFilter());
}
@Override
- protected void doXContent(XContentBuilder builder, Params params) throws IOException {
+ protected int doHashCode() {
+ return 0;
}
@Override
- protected int doHashCode() {
- return 31;
+ protected boolean doEquals(DummyQueryBuilder other) {
+ return true;
}
@Override
- protected boolean doEquals(EmptyQueryBuilder other) {
- return true;
+ public String getWriteableName() {
+ return NAME;
}
-}
+} \ No newline at end of file
diff --git a/core/src/test/java/org/elasticsearch/index/query/plugin/DummyQueryParserPlugin.java b/core/src/test/java/org/elasticsearch/index/query/plugin/DummyQueryParserPlugin.java
index 54d1026a7f..fbb744f799 100644
--- a/core/src/test/java/org/elasticsearch/index/query/plugin/DummyQueryParserPlugin.java
+++ b/core/src/test/java/org/elasticsearch/index/query/plugin/DummyQueryParserPlugin.java
@@ -23,14 +23,6 @@ import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Weight;
-import org.elasticsearch.common.ParseField;
-import org.elasticsearch.common.io.stream.StreamInput;
-import org.elasticsearch.common.io.stream.StreamOutput;
-import org.elasticsearch.common.xcontent.XContentBuilder;
-import org.elasticsearch.common.xcontent.XContentParser;
-import org.elasticsearch.index.query.AbstractQueryBuilder;
-import org.elasticsearch.index.query.QueryParseContext;
-import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.search.SearchModule;
@@ -52,62 +44,11 @@ public class DummyQueryParserPlugin extends Plugin {
module.registerQuery(DummyQueryBuilder::new, DummyQueryBuilder::fromXContent, DummyQueryBuilder.QUERY_NAME_FIELD);
}
- public static class DummyQueryBuilder extends AbstractQueryBuilder<DummyQueryBuilder> {
- private static final String NAME = "dummy";
- private static final ParseField QUERY_NAME_FIELD = new ParseField(NAME);
-
- public DummyQueryBuilder() {
- }
-
- /**
- * Read from a stream.
- */
- public DummyQueryBuilder(StreamInput in) throws IOException {
- super(in);
- }
-
- @Override
- protected void doWriteTo(StreamOutput out) throws IOException {
- // only the superclass has state
- }
-
- @Override
- protected void doXContent(XContentBuilder builder, Params params) throws IOException {
- builder.startObject(NAME).endObject();
- }
-
- public static DummyQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
- XContentParser.Token token = parseContext.parser().nextToken();
- assert token == XContentParser.Token.END_OBJECT;
- return new DummyQueryBuilder();
- }
-
- @Override
- protected Query doToQuery(QueryShardContext context) throws IOException {
- return new DummyQuery(context.isFilter());
- }
-
- @Override
- protected int doHashCode() {
- return 0;
- }
-
- @Override
- protected boolean doEquals(DummyQueryBuilder other) {
- return true;
- }
-
- @Override
- public String getWriteableName() {
- return NAME;
- }
- }
-
public static class DummyQuery extends Query {
public final boolean isFilter;
private final Query matchAllDocsQuery = new MatchAllDocsQuery();
- private DummyQuery(boolean isFilter) {
+ public DummyQuery(boolean isFilter) {
this.isFilter = isFilter;
}
diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/FilterIT.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/FilterIT.java
index 9859936b41..ddb62d57ff 100644
--- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/FilterIT.java
+++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/FilterIT.java
@@ -21,11 +21,17 @@ package org.elasticsearch.search.aggregations.bucket;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
+import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.XContentFactory;
+import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.BoolQueryBuilder;
-import org.elasticsearch.index.query.EmptyQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
+import org.elasticsearch.index.query.QueryParseContext;
+import org.elasticsearch.indices.query.IndicesQueriesRegistry;
+import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.filter.Filter;
+import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.metrics.avg.Avg;
import org.elasticsearch.test.ESIntegTestCase;
@@ -42,8 +48,8 @@ import static org.elasticsearch.search.aggregations.AggregationBuilders.filter;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
+import static org.hamcrest.Matchers.is;
import static org.hamcrest.core.IsNull.notNullValue;
/**
@@ -119,9 +125,16 @@ public class FilterIT extends ESIntegTestCase {
assertThat(filter.getDocCount(), equalTo((long) numDocs));
}
+ /**
+ * test that "{ "filter" : {} }" is regarded as match_all when not parsing strict
+ */
public void testEmptyFilter() throws Exception {
- QueryBuilder emptyFilter = new EmptyQueryBuilder();
- SearchResponse response = client().prepareSearch("idx").addAggregation(filter("tag1", emptyFilter)).execute().actionGet();
+ String emtpyFilterBody = "{ }";
+ XContentParser parser = XContentFactory.xContent(emtpyFilterBody).createParser(emtpyFilterBody);
+ QueryParseContext parseContext = new QueryParseContext(new IndicesQueriesRegistry(), parser, ParseFieldMatcher.EMPTY);
+ AggregationBuilder<?> filterAgg = FilterAggregationBuilder.parse("tag1", parseContext);
+
+ SearchResponse response = client().prepareSearch("idx").addAggregation(filterAgg).execute().actionGet();
assertSearchResponse(response);
diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/FiltersIT.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/FiltersIT.java
index fd4db82f2d..0be0f76de9 100644
--- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/FiltersIT.java
+++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/FiltersIT.java
@@ -22,11 +22,17 @@ package org.elasticsearch.search.aggregations.bucket;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
+import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.XContentFactory;
+import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.BoolQueryBuilder;
-import org.elasticsearch.index.query.EmptyQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
+import org.elasticsearch.index.query.QueryParseContext;
+import org.elasticsearch.indices.query.IndicesQueriesRegistry;
+import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.filters.Filters;
+import org.elasticsearch.search.aggregations.bucket.filters.FiltersAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.filters.FiltersAggregator.KeyedFilter;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.metrics.avg.Avg;
@@ -207,8 +213,13 @@ public class FiltersIT extends ESIntegTestCase {
}
public void testEmptyFilter() throws Exception {
- QueryBuilder emptyFilter = new EmptyQueryBuilder();
- SearchResponse response = client().prepareSearch("idx").addAggregation(filters("tag1", emptyFilter)).execute().actionGet();
+ String emtpyFilterBody = "{ \"filters\" : [ {} ] }";
+ XContentParser parser = XContentFactory.xContent(emtpyFilterBody).createParser(emtpyFilterBody);
+ parser.nextToken();
+ QueryParseContext parseContext = new QueryParseContext(new IndicesQueriesRegistry(), parser, ParseFieldMatcher.EMPTY);
+ AggregationBuilder<?> filtersAgg = FiltersAggregationBuilder.parse("tag1", parseContext);
+
+ SearchResponse response = client().prepareSearch("idx").addAggregation(filtersAgg).execute().actionGet();
assertSearchResponse(response);
@@ -219,8 +230,13 @@ public class FiltersIT extends ESIntegTestCase {
}
public void testEmptyKeyedFilter() throws Exception {
- QueryBuilder emptyFilter = new EmptyQueryBuilder();
- SearchResponse response = client().prepareSearch("idx").addAggregation(filters("tag1", new KeyedFilter("foo", emptyFilter)))
+ String emtpyFilterBody = "{ \"filters\" : {\"foo\" : {} } }";
+ XContentParser parser = XContentFactory.xContent(emtpyFilterBody).createParser(emtpyFilterBody);
+ parser.nextToken();
+ QueryParseContext parseContext = new QueryParseContext(new IndicesQueriesRegistry(), parser, ParseFieldMatcher.EMPTY);
+ AggregationBuilder<?> filtersAgg = FiltersAggregationBuilder.parse("tag1", parseContext);
+
+ SearchResponse response = client().prepareSearch("idx").addAggregation(filtersAgg)
.execute().actionGet();
assertSearchResponse(response);
diff --git a/core/src/test/java/org/elasticsearch/search/builder/SearchSourceBuilderTests.java b/core/src/test/java/org/elasticsearch/search/builder/SearchSourceBuilderTests.java
index f8236f66e4..fc3c90b516 100644
--- a/core/src/test/java/org/elasticsearch/search/builder/SearchSourceBuilderTests.java
+++ b/core/src/test/java/org/elasticsearch/search/builder/SearchSourceBuilderTests.java
@@ -48,8 +48,6 @@ import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.env.Environment;
import org.elasticsearch.env.EnvironmentModule;
import org.elasticsearch.index.Index;
-import org.elasticsearch.test.AbstractQueryTestCase;
-import org.elasticsearch.index.query.EmptyQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.indices.IndicesModule;
@@ -80,6 +78,7 @@ import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.search.suggest.SuggestBuilderTests;
import org.elasticsearch.search.suggest.Suggesters;
+import org.elasticsearch.test.AbstractQueryTestCase;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.IndexSettingsModule;
import org.elasticsearch.test.InternalSettingsPlugin;
@@ -440,11 +439,17 @@ public class SearchSourceBuilderTests extends ESTestCase {
assertParseSearchSource(testSearchSourceBuilder, builder.bytes());
}
- private void assertParseSearchSource(SearchSourceBuilder testBuilder, BytesReference searchSourceAsBytes) throws IOException {
+ private static void assertParseSearchSource(SearchSourceBuilder testBuilder, BytesReference searchSourceAsBytes) throws IOException {
+ assertParseSearchSource(testBuilder, searchSourceAsBytes, ParseFieldMatcher.STRICT);
+ }
+
+ private static void assertParseSearchSource(SearchSourceBuilder testBuilder, BytesReference searchSourceAsBytes, ParseFieldMatcher pfm)
+ throws IOException {
XContentParser parser = XContentFactory.xContent(searchSourceAsBytes).createParser(searchSourceAsBytes);
- QueryParseContext parseContext = createParseContext(parser);
+ QueryParseContext parseContext = new QueryParseContext(indicesQueriesRegistry, parser, pfm);
if (randomBoolean()) {
- parser.nextToken(); // sometimes we move it on the START_OBJECT to test the embedded case
+ parser.nextToken(); // sometimes we move it on the START_OBJECT to
+ // test the embedded case
}
SearchSourceBuilder newBuilder = SearchSourceBuilder.fromXContent(parseContext, aggParsers, suggesters);
assertNull(parser.nextToken());
@@ -614,8 +619,13 @@ public class SearchSourceBuilderTests extends ESTestCase {
public void testEmptyPostFilter() throws IOException {
SearchSourceBuilder builder = new SearchSourceBuilder();
- builder.postFilter(new EmptyQueryBuilder());
String query = "{ \"post_filter\": {} }";
- assertParseSearchSource(builder, new BytesArray(query));
+ assertParseSearchSource(builder, new BytesArray(query), ParseFieldMatcher.EMPTY);
+ }
+
+ public void testEmptyQuery() throws IOException {
+ SearchSourceBuilder builder = new SearchSourceBuilder();
+ String query = "{ \"query\": {} }";
+ assertParseSearchSource(builder, new BytesArray(query), ParseFieldMatcher.EMPTY);
}
}
diff --git a/modules/lang-mustache/src/test/java/org/elasticsearch/messy/tests/TemplateQueryParserTests.java b/modules/lang-mustache/src/test/java/org/elasticsearch/messy/tests/TemplateQueryParserTests.java
index 7097718c6f..9aa5e1892e 100644
--- a/modules/lang-mustache/src/test/java/org/elasticsearch/messy/tests/TemplateQueryParserTests.java
+++ b/modules/lang-mustache/src/test/java/org/elasticsearch/messy/tests/TemplateQueryParserTests.java
@@ -169,7 +169,7 @@ public class TemplateQueryParserTests extends ESTestCase {
QueryShardContext context = contextFactory.get();
templateSourceParser.nextToken();
- Query query = QueryBuilder.rewriteQuery(TemplateQueryBuilder.fromXContent(context.newParseContext(templateSourceParser)),
+ Query query = QueryBuilder.rewriteQuery(TemplateQueryBuilder.fromXContent(context.newParseContext(templateSourceParser)).get(),
context).toQuery(context);
assertTrue("Parsing template query failed.", query instanceof MatchAllDocsQuery);
}
@@ -180,7 +180,9 @@ public class TemplateQueryParserTests extends ESTestCase {
XContentParser templateSourceParser = XContentFactory.xContent(templateString).createParser(templateString);
QueryShardContext context = contextFactory.get();
- Query query = QueryBuilder.rewriteQuery(TemplateQueryBuilder.fromXContent(context.newParseContext(templateSourceParser)), context).toQuery(context);
+ Query query = QueryBuilder
+ .rewriteQuery(TemplateQueryBuilder.fromXContent(context.newParseContext(templateSourceParser)).get(), context)
+ .toQuery(context);
assertTrue("Parsing template query failed.", query instanceof MatchAllDocsQuery);
}
@@ -197,7 +199,7 @@ public class TemplateQueryParserTests extends ESTestCase {
QueryShardContext context = contextFactory.get();
try {
- TemplateQueryBuilder.fromXContent(context.newParseContext(templateSourceParser)).rewrite(context);
+ TemplateQueryBuilder.fromXContent(context.newParseContext(templateSourceParser)).get().rewrite(context);
fail("Expected ParsingException");
} catch (ParsingException e) {
assertThat(e.getMessage(), containsString("query malformed, no field after start_object"));
@@ -212,7 +214,7 @@ public class TemplateQueryParserTests extends ESTestCase {
templateSourceParser.nextToken();
- Query query = QueryBuilder.rewriteQuery(TemplateQueryBuilder.fromXContent(context.newParseContext(templateSourceParser)),
+ Query query = QueryBuilder.rewriteQuery(TemplateQueryBuilder.fromXContent(context.newParseContext(templateSourceParser)).get(),
context).toQuery(context);
assertTrue("Parsing template query failed.", query instanceof MatchAllDocsQuery);
}
@@ -224,7 +226,7 @@ public class TemplateQueryParserTests extends ESTestCase {
QueryShardContext context = contextFactory.get();
templateSourceParser.nextToken();
try {
- TemplateQueryBuilder.fromXContent(context.newParseContext(templateSourceParser)).toQuery(context);
+ TemplateQueryBuilder.fromXContent(context.newParseContext(templateSourceParser)).get().toQuery(context);
fail();
} catch (UnsupportedOperationException ex) {
assertEquals("this query must be rewritten first", ex.getMessage());
diff --git a/modules/percolator/src/main/java/org/elasticsearch/percolator/PercolateQueryBuilder.java b/modules/percolator/src/main/java/org/elasticsearch/percolator/PercolateQueryBuilder.java
index 627cb09da1..aadcabda00 100644
--- a/modules/percolator/src/main/java/org/elasticsearch/percolator/PercolateQueryBuilder.java
+++ b/modules/percolator/src/main/java/org/elasticsearch/percolator/PercolateQueryBuilder.java
@@ -76,6 +76,7 @@ import org.elasticsearch.index.query.QueryShardException;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
import static org.elasticsearch.index.mapper.SourceToParse.source;
import static org.elasticsearch.percolator.PercolatorFieldMapper.parseQuery;
@@ -235,7 +236,7 @@ public class PercolateQueryBuilder extends AbstractQueryBuilder<PercolateQueryBu
builder.endObject();
}
- public static PercolateQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static Optional<PercolateQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
@@ -316,7 +317,7 @@ public class PercolateQueryBuilder extends AbstractQueryBuilder<PercolateQueryBu
}
queryBuilder.queryName(queryName);
queryBuilder.boost(boost);
- return queryBuilder;
+ return Optional.of(queryBuilder);
}
@Override
@@ -446,7 +447,7 @@ public class PercolateQueryBuilder extends AbstractQueryBuilder<PercolateQueryBu
return document;
}
- private IndexSearcher createMultiDocumentSearcher(Analyzer analyzer, ParsedDocument doc) {
+ private static IndexSearcher createMultiDocumentSearcher(Analyzer analyzer, ParsedDocument doc) {
IndexReader[] memoryIndices = new IndexReader[doc.docs().size()];
List<ParseContext.Document> docs = doc.docs();
int rootDocIndex = docs.size() - 1;
diff --git a/modules/percolator/src/main/java/org/elasticsearch/percolator/PercolatorFieldMapper.java b/modules/percolator/src/main/java/org/elasticsearch/percolator/PercolatorFieldMapper.java
index bf5c4c0ae8..a19a207eb7 100644
--- a/modules/percolator/src/main/java/org/elasticsearch/percolator/PercolatorFieldMapper.java
+++ b/modules/percolator/src/main/java/org/elasticsearch/percolator/PercolatorFieldMapper.java
@@ -250,7 +250,8 @@ public class PercolatorFieldMapper extends FieldMapper {
private static QueryBuilder parseQueryBuilder(QueryParseContext context, XContentLocation location) {
try {
- return context.parseInnerQueryBuilder();
+ return context.parseInnerQueryBuilder()
+ .orElseThrow(() -> new ParsingException(location, "Failed to parse inner query, was empty"));
} catch (IOException e) {
throw new ParsingException(location, "Failed to parse", e);
}
diff --git a/modules/percolator/src/main/java/org/elasticsearch/percolator/TransportPercolateAction.java b/modules/percolator/src/main/java/org/elasticsearch/percolator/TransportPercolateAction.java
index f3ee9230ea..9e86ae44cd 100644
--- a/modules/percolator/src/main/java/org/elasticsearch/percolator/TransportPercolateAction.java
+++ b/modules/percolator/src/main/java/org/elasticsearch/percolator/TransportPercolateAction.java
@@ -42,7 +42,6 @@ import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.ConstantScoreQueryBuilder;
-import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
@@ -202,9 +201,8 @@ public class TransportPercolateAction extends HandledTransportAction<PercolateRe
if (querySource != null) {
try (XContentParser parser = XContentHelper.createParser(querySource)) {
QueryParseContext queryParseContext = new QueryParseContext(queryRegistry, parser, parseFieldMatcher);
- QueryBuilder queryBuilder = queryParseContext.parseInnerQueryBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
- boolQueryBuilder.must(queryBuilder);
+ queryParseContext.parseInnerQueryBuilder().ifPresent(boolQueryBuilder::must);
boolQueryBuilder.filter(percolateQueryBuilder);
searchSource.field("query", boolQueryBuilder);
}
diff --git a/modules/percolator/src/test/java/org/elasticsearch/percolator/PercolatorFieldMapperTests.java b/modules/percolator/src/test/java/org/elasticsearch/percolator/PercolatorFieldMapperTests.java
index bcb9ed8d40..2175dabfef 100644
--- a/modules/percolator/src/test/java/org/elasticsearch/percolator/PercolatorFieldMapperTests.java
+++ b/modules/percolator/src/test/java/org/elasticsearch/percolator/PercolatorFieldMapperTests.java
@@ -272,6 +272,6 @@ public class PercolatorFieldMapperTests extends ESSingleNodeTestCase {
XContentParser sourceParser = PercolatorFieldMapper.QUERY_BUILDER_CONTENT_TYPE.xContent()
.createParser(actual.bytes, actual.offset, actual.length);
QueryParseContext qsc = indexService.newQueryShardContext().newParseContext(sourceParser);
- assertThat(qsc.parseInnerQueryBuilder(), equalTo(expected));
+ assertThat(qsc.parseInnerQueryBuilder().get(), equalTo(expected));
}
}
diff --git a/test/framework/src/main/java/org/elasticsearch/test/AbstractQueryTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/AbstractQueryTestCase.java
index c27617a728..2e0bfe2891 100644
--- a/test/framework/src/main/java/org/elasticsearch/test/AbstractQueryTestCase.java
+++ b/test/framework/src/main/java/org/elasticsearch/test/AbstractQueryTestCase.java
@@ -336,11 +336,11 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
/**
* Parses the query provided as string argument and compares it with the expected result provided as argument as a {@link QueryBuilder}
*/
- protected final void assertParsedQuery(String queryAsString, QueryBuilder expectedQuery) throws IOException {
+ protected final static void assertParsedQuery(String queryAsString, QueryBuilder expectedQuery) throws IOException {
assertParsedQuery(queryAsString, expectedQuery, ParseFieldMatcher.STRICT);
}
- protected final void assertParsedQuery(String queryAsString, QueryBuilder expectedQuery, ParseFieldMatcher matcher) throws IOException {
+ protected final static void assertParsedQuery(String queryAsString, QueryBuilder expectedQuery, ParseFieldMatcher matcher) throws IOException {
QueryBuilder newQuery = parseQuery(queryAsString, matcher);
assertNotSame(newQuery, expectedQuery);
assertEquals(expectedQuery, newQuery);
@@ -350,38 +350,39 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
/**
* Parses the query provided as bytes argument and compares it with the expected result provided as argument as a {@link QueryBuilder}
*/
- protected final void assertParsedQuery(BytesReference queryAsBytes, QueryBuilder expectedQuery) throws IOException {
+ protected final static void assertParsedQuery(BytesReference queryAsBytes, QueryBuilder expectedQuery) throws IOException {
assertParsedQuery(queryAsBytes, expectedQuery, ParseFieldMatcher.STRICT);
}
- protected final void assertParsedQuery(BytesReference queryAsBytes, QueryBuilder expectedQuery, ParseFieldMatcher matcher) throws IOException {
+ protected final static void assertParsedQuery(BytesReference queryAsBytes, QueryBuilder expectedQuery, ParseFieldMatcher matcher) throws IOException {
QueryBuilder newQuery = parseQuery(queryAsBytes, matcher);
assertNotSame(newQuery, expectedQuery);
assertEquals(expectedQuery, newQuery);
assertEquals(expectedQuery.hashCode(), newQuery.hashCode());
}
- protected final QueryBuilder parseQuery(String queryAsString) throws IOException {
+ protected final static QueryBuilder parseQuery(String queryAsString) throws IOException {
return parseQuery(queryAsString, ParseFieldMatcher.STRICT);
}
- protected final QueryBuilder parseQuery(String queryAsString, ParseFieldMatcher matcher) throws IOException {
+ protected final static QueryBuilder parseQuery(String queryAsString, ParseFieldMatcher matcher) throws IOException {
XContentParser parser = XContentFactory.xContent(queryAsString).createParser(queryAsString);
return parseQuery(parser, matcher);
}
- protected final QueryBuilder parseQuery(BytesReference queryAsBytes) throws IOException {
+ protected final static QueryBuilder parseQuery(BytesReference queryAsBytes) throws IOException {
return parseQuery(queryAsBytes, ParseFieldMatcher.STRICT);
}
- protected final QueryBuilder parseQuery(BytesReference queryAsBytes, ParseFieldMatcher matcher) throws IOException {
+ protected final static QueryBuilder parseQuery(BytesReference queryAsBytes, ParseFieldMatcher matcher) throws IOException {
XContentParser parser = XContentFactory.xContent(queryAsBytes).createParser(queryAsBytes);
return parseQuery(parser, matcher);
}
- private QueryBuilder parseQuery(XContentParser parser, ParseFieldMatcher matcher) throws IOException {
+ private static QueryBuilder parseQuery(XContentParser parser, ParseFieldMatcher matcher) throws IOException {
QueryParseContext context = createParseContext(parser, matcher);
- QueryBuilder parseInnerQueryBuilder = context.parseInnerQueryBuilder();
+ QueryBuilder parseInnerQueryBuilder = context.parseInnerQueryBuilder()
+ .orElseThrow(() -> new IllegalArgumentException("inner query body cannot be empty"));
assertNull(parser.nextToken());
return parseInnerQueryBuilder;
}
@@ -518,8 +519,7 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
/**
* Serialize the given query builder and asserts that both are equal
*/
- @SuppressWarnings("unchecked")
- protected <QB extends QueryBuilder> QB assertSerialization(QB testQuery) throws IOException {
+ protected QueryBuilder assertSerialization(QueryBuilder testQuery) throws IOException {
try (BytesStreamOutput output = new BytesStreamOutput()) {
output.writeNamedWriteable(testQuery);
try (StreamInput in = new NamedWriteableAwareStreamInput(StreamInput.wrap(output.bytes()), serviceHolder.namedWriteableRegistry)) {
@@ -527,7 +527,7 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
assertEquals(testQuery, deserializedQuery);
assertEquals(testQuery.hashCode(), deserializedQuery.hashCode());
assertNotSame(testQuery, deserializedQuery);
- return (QB) deserializedQuery;
+ return deserializedQuery;
}
}
}