Skip to content

Commit 927111c

Browse files
authored
Remove QueryParseContext from parsing QueryBuilders (#25448)
Currently QueryParseContext is only a thin wrapper around an XContentParser that adds little functionality of its own. I provides helpers for long deprecated field names which can be removed and two helper methods that can be made static and moved to other classes. This is a first step in helping to remove QueryParseContext entirely.
1 parent 22ff76d commit 927111c

File tree

97 files changed

+462
-562
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+462
-562
lines changed

core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,14 @@
3030
import org.elasticsearch.common.xcontent.XContentHelper;
3131
import org.elasticsearch.common.xcontent.XContentParser;
3232
import org.elasticsearch.index.query.QueryBuilder;
33-
import org.elasticsearch.index.query.QueryParseContext;
3433
import org.elasticsearch.index.query.QueryShardContext;
3534
import org.elasticsearch.indices.InvalidAliasNameException;
3635

3736
import java.io.IOException;
3837
import java.util.function.Function;
3938

39+
import static org.elasticsearch.index.query.AbstractQueryBuilder.parseInnerQueryBuilder;
40+
4041
/**
4142
* Validator for an alias, to be used before adding an alias to the index metadata
4243
* and make sure the alias is valid
@@ -141,8 +142,7 @@ public void validateAliasFilter(String alias, byte[] filter, QueryShardContext q
141142
}
142143

143144
private static void validateAliasFilter(XContentParser parser, QueryShardContext queryShardContext) throws IOException {
144-
QueryParseContext queryParseContext = queryShardContext.newParseContext(parser);
145-
QueryBuilder parseInnerQueryBuilder = queryParseContext.parseInnerQueryBuilder();
145+
QueryBuilder parseInnerQueryBuilder = parseInnerQueryBuilder(parser);
146146
QueryBuilder queryBuilder = QueryBuilder.rewriteQuery(parseInnerQueryBuilder, queryShardContext);
147147
queryBuilder.toFilter(queryShardContext);
148148
}

core/src/main/java/org/elasticsearch/index/query/AbstractQueryBuilder.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,11 @@
3131
import org.elasticsearch.common.io.stream.StreamOutput;
3232
import org.elasticsearch.common.lucene.BytesRefs;
3333
import org.elasticsearch.common.xcontent.AbstractObjectParser;
34+
import org.elasticsearch.common.xcontent.NamedXContentRegistry.UnknownNamedObjectException;
3435
import org.elasticsearch.common.xcontent.XContentBuilder;
3536
import org.elasticsearch.common.xcontent.XContentLocation;
37+
import org.elasticsearch.common.xcontent.XContentParser;
38+
import org.elasticsearch.common.xcontent.XContentParser.Token;
3639
import org.elasticsearch.common.xcontent.XContentType;
3740

3841
import java.io.IOException;
@@ -286,6 +289,50 @@ protected QueryBuilder doRewrite(QueryRewriteContext queryShardContext) throws I
286289
protected void extractInnerHitBuilders(Map<String, InnerHitContextBuilder> innerHits) {
287290
}
288291

292+
/**
293+
* Parses a query excluding the query element that wraps it
294+
*/
295+
public static QueryBuilder parseInnerQueryBuilder(XContentParser parser) throws IOException {
296+
if (parser.currentToken() != XContentParser.Token.START_OBJECT) {
297+
if (parser.nextToken() != XContentParser.Token.START_OBJECT) {
298+
throw new ParsingException(parser.getTokenLocation(), "[_na] query malformed, must start with start_object");
299+
}
300+
}
301+
if (parser.nextToken() == XContentParser.Token.END_OBJECT) {
302+
// we encountered '{}' for a query clause, it used to be supported, deprecated in 5.0 and removed in 6.0
303+
throw new IllegalArgumentException("query malformed, empty clause found at [" + parser.getTokenLocation() +"]");
304+
}
305+
if (parser.currentToken() != XContentParser.Token.FIELD_NAME) {
306+
throw new ParsingException(parser.getTokenLocation(), "[_na] query malformed, no field after start_object");
307+
}
308+
String queryName = parser.currentName();
309+
// move to the next START_OBJECT
310+
if (parser.nextToken() != XContentParser.Token.START_OBJECT) {
311+
throw new ParsingException(parser.getTokenLocation(), "[" + queryName + "] query malformed, no start_object after query name");
312+
}
313+
QueryBuilder result;
314+
try {
315+
// TODO what can we pass in here
316+
result = parser.namedObject(QueryBuilder.class, queryName, null);
317+
} catch (UnknownNamedObjectException e) {
318+
// Preserve the error message from 5.0 until we have a compellingly better message so we don't break BWC.
319+
// This intentionally doesn't include the causing exception because that'd change the "root_cause" of any unknown query errors
320+
throw new ParsingException(new XContentLocation(e.getLineNumber(), e.getColumnNumber()),
321+
"no [query] registered for [" + e.getName() + "]");
322+
}
323+
//end_object of the specific query (e.g. match, multi_match etc.) element
324+
if (parser.currentToken() != XContentParser.Token.END_OBJECT) {
325+
throw new ParsingException(parser.getTokenLocation(),
326+
"[" + queryName + "] malformed query, expected [END_OBJECT] but found [" + parser.currentToken() + "]");
327+
}
328+
//end_object of the query object
329+
if (parser.nextToken() != XContentParser.Token.END_OBJECT) {
330+
throw new ParsingException(parser.getTokenLocation(),
331+
"[" + queryName + "] malformed query, expected [END_OBJECT] but found [" + parser.currentToken() + "]");
332+
}
333+
return result;
334+
}
335+
289336
// Like Objects.requireNotNull(...) but instead throws a IllegalArgumentException
290337
protected static <T> T requireValue(T value, String message) {
291338
if (value == null) {

core/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -275,11 +275,9 @@ private static void doXArrayContent(String field, List<QueryBuilder> clauses, XC
275275
builder.endArray();
276276
}
277277

278-
public static BoolQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException, ParsingException {
279-
XContentParser parser = parseContext.parser();
280-
278+
public static BoolQueryBuilder fromXContent(XContentParser parser) throws IOException, ParsingException {
281279
boolean adjustPureNegative = BoolQueryBuilder.ADJUST_PURE_NEGATIVE_DEFAULT;
282-
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
280+
float boost = DEFAULT_BOOST;
283281
String minimumShouldMatch = null;
284282

285283
final List<QueryBuilder> mustClauses = new ArrayList<>();
@@ -293,22 +291,20 @@ public static BoolQueryBuilder fromXContent(QueryParseContext parseContext) thro
293291
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
294292
if (token == XContentParser.Token.FIELD_NAME) {
295293
currentFieldName = parser.currentName();
296-
} else if (parseContext.isDeprecatedSetting(currentFieldName)) {
297-
// skip
298294
} else if (token == XContentParser.Token.START_OBJECT) {
299295
switch (currentFieldName) {
300296
case MUST:
301-
mustClauses.add(parseContext.parseInnerQueryBuilder());
297+
mustClauses.add(parseInnerQueryBuilder(parser));
302298
break;
303299
case SHOULD:
304-
shouldClauses.add(parseContext.parseInnerQueryBuilder());
300+
shouldClauses.add(parseInnerQueryBuilder(parser));
305301
break;
306302
case FILTER:
307-
filterClauses.add(parseContext.parseInnerQueryBuilder());
303+
filterClauses.add(parseInnerQueryBuilder(parser));
308304
break;
309305
case MUST_NOT:
310306
case MUSTNOT:
311-
mustNotClauses.add(parseContext.parseInnerQueryBuilder());
307+
mustNotClauses.add(parseInnerQueryBuilder(parser));
312308
break;
313309
default:
314310
throw new ParsingException(parser.getTokenLocation(), "[bool] query does not support [" + currentFieldName + "]");
@@ -317,17 +313,17 @@ public static BoolQueryBuilder fromXContent(QueryParseContext parseContext) thro
317313
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
318314
switch (currentFieldName) {
319315
case MUST:
320-
mustClauses.add(parseContext.parseInnerQueryBuilder());
316+
mustClauses.add(parseInnerQueryBuilder(parser));
321317
break;
322318
case SHOULD:
323-
shouldClauses.add(parseContext.parseInnerQueryBuilder());
319+
shouldClauses.add(parseInnerQueryBuilder(parser));
324320
break;
325321
case FILTER:
326-
filterClauses.add(parseContext.parseInnerQueryBuilder());
322+
filterClauses.add(parseInnerQueryBuilder(parser));
327323
break;
328324
case MUST_NOT:
329325
case MUSTNOT:
330-
mustNotClauses.add(parseContext.parseInnerQueryBuilder());
326+
mustNotClauses.add(parseInnerQueryBuilder(parser));
331327
break;
332328
default:
333329
throw new ParsingException(parser.getTokenLocation(), "bool query does not support [" + currentFieldName + "]");
@@ -338,11 +334,11 @@ public static BoolQueryBuilder fromXContent(QueryParseContext parseContext) thro
338334
// ignore
339335
} else if (MINIMUM_SHOULD_MATCH.match(currentFieldName)) {
340336
minimumShouldMatch = parser.textOrNull();
341-
} else if (AbstractQueryBuilder.BOOST_FIELD.match(currentFieldName)) {
337+
} else if (BOOST_FIELD.match(currentFieldName)) {
342338
boost = parser.floatValue();
343339
} else if (ADJUST_PURE_NEGATIVE.match(currentFieldName)) {
344340
adjustPureNegative = parser.booleanValue();
345-
} else if (AbstractQueryBuilder.NAME_FIELD.match(currentFieldName)) {
341+
} else if (NAME_FIELD.match(currentFieldName)) {
346342
queryName = parser.text();
347343
} else {
348344
throw new ParsingException(parser.getTokenLocation(), "[bool] query does not support [" + currentFieldName + "]");

core/src/main/java/org/elasticsearch/index/query/BoostingQueryBuilder.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import java.util.Map;
3333
import java.util.Objects;
3434

35+
3536
/**
3637
* The BoostingQuery class can be used to effectively demote results that match a given query.
3738
* Unlike the "NOT" clause, this still selects documents that contain undesirable terms,
@@ -136,14 +137,12 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep
136137
builder.endObject();
137138
}
138139

139-
public static BoostingQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
140-
XContentParser parser = parseContext.parser();
141-
140+
public static BoostingQueryBuilder fromXContent(XContentParser parser) throws IOException {
142141
QueryBuilder positiveQuery = null;
143142
boolean positiveQueryFound = false;
144143
QueryBuilder negativeQuery = null;
145144
boolean negativeQueryFound = false;
146-
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
145+
float boost = DEFAULT_BOOST;
147146
float negativeBoost = -1;
148147
String queryName = null;
149148

@@ -154,20 +153,20 @@ public static BoostingQueryBuilder fromXContent(QueryParseContext parseContext)
154153
currentFieldName = parser.currentName();
155154
} else if (token == XContentParser.Token.START_OBJECT) {
156155
if (POSITIVE_FIELD.match(currentFieldName)) {
157-
positiveQuery = parseContext.parseInnerQueryBuilder();
156+
positiveQuery = parseInnerQueryBuilder(parser);
158157
positiveQueryFound = true;
159158
} else if (NEGATIVE_FIELD.match(currentFieldName)) {
160-
negativeQuery = parseContext.parseInnerQueryBuilder();
159+
negativeQuery = parseInnerQueryBuilder(parser);
161160
negativeQueryFound = true;
162161
} else {
163162
throw new ParsingException(parser.getTokenLocation(), "[boosting] query does not support [" + currentFieldName + "]");
164163
}
165164
} else if (token.isValue()) {
166165
if (NEGATIVE_BOOST_FIELD.match(currentFieldName)) {
167166
negativeBoost = parser.floatValue();
168-
} else if (AbstractQueryBuilder.NAME_FIELD.match(currentFieldName)) {
167+
} else if (NAME_FIELD.match(currentFieldName)) {
169168
queryName = parser.text();
170-
} else if (AbstractQueryBuilder.BOOST_FIELD.match(currentFieldName)) {
169+
} else if (BOOST_FIELD.match(currentFieldName)) {
171170
boost = parser.floatValue();
172171
} else {
173172
throw new ParsingException(parser.getTokenLocation(), "[boosting] query does not support [" + currentFieldName + "]");

core/src/main/java/org/elasticsearch/index/query/CommonTermsQueryBuilder.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,7 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep
248248
builder.endObject();
249249
}
250250

251-
public static CommonTermsQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
252-
XContentParser parser = parseContext.parser();
253-
251+
public static CommonTermsQueryBuilder fromXContent(XContentParser parser) throws IOException {
254252
String fieldName = null;
255253
Object text = null;
256254
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
@@ -266,8 +264,6 @@ public static CommonTermsQueryBuilder fromXContent(QueryParseContext parseContex
266264
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
267265
if (token == XContentParser.Token.FIELD_NAME) {
268266
currentFieldName = parser.currentName();
269-
} else if (parseContext.isDeprecatedSetting(currentFieldName)) {
270-
// skip
271267
} else if (token == XContentParser.Token.START_OBJECT) {
272268
throwParsingExceptionOnMultipleFields(NAME, parser.getTokenLocation(), fieldName, currentFieldName);
273269
fieldName = currentFieldName;

core/src/main/java/org/elasticsearch/index/query/ConstantScoreQueryBuilder.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,7 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep
8585
builder.endObject();
8686
}
8787

88-
public static ConstantScoreQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
89-
XContentParser parser = parseContext.parser();
90-
88+
public static ConstantScoreQueryBuilder fromXContent(XContentParser parser) throws IOException {
9189
QueryBuilder query = null;
9290
boolean queryFound = false;
9391
String queryName = null;
@@ -98,15 +96,13 @@ public static ConstantScoreQueryBuilder fromXContent(QueryParseContext parseCont
9896
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
9997
if (token == XContentParser.Token.FIELD_NAME) {
10098
currentFieldName = parser.currentName();
101-
} else if (parseContext.isDeprecatedSetting(currentFieldName)) {
102-
// skip
10399
} else if (token == XContentParser.Token.START_OBJECT) {
104100
if (INNER_QUERY_FIELD.match(currentFieldName)) {
105101
if (queryFound) {
106102
throw new ParsingException(parser.getTokenLocation(), "[" + ConstantScoreQueryBuilder.NAME + "]"
107103
+ " accepts only one 'filter' element.");
108104
}
109-
query = parseContext.parseInnerQueryBuilder();
105+
query = parseInnerQueryBuilder(parser);
110106
queryFound = true;
111107
} else {
112108
throw new ParsingException(parser.getTokenLocation(),

core/src/main/java/org/elasticsearch/index/query/DisMaxQueryBuilder.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,7 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep
122122
builder.endObject();
123123
}
124124

125-
public static DisMaxQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
126-
XContentParser parser = parseContext.parser();
127-
125+
public static DisMaxQueryBuilder fromXContent(XContentParser parser) throws IOException {
128126
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
129127
float tieBreaker = DisMaxQueryBuilder.DEFAULT_TIE_BREAKER;
130128

@@ -140,15 +138,15 @@ public static DisMaxQueryBuilder fromXContent(QueryParseContext parseContext) th
140138
} else if (token == XContentParser.Token.START_OBJECT) {
141139
if (QUERIES_FIELD.match(currentFieldName)) {
142140
queriesFound = true;
143-
queries.add(parseContext.parseInnerQueryBuilder());
141+
queries.add(parseInnerQueryBuilder(parser));
144142
} else {
145143
throw new ParsingException(parser.getTokenLocation(), "[dis_max] query does not support [" + currentFieldName + "]");
146144
}
147145
} else if (token == XContentParser.Token.START_ARRAY) {
148146
if (QUERIES_FIELD.match(currentFieldName)) {
149147
queriesFound = true;
150148
while (token != XContentParser.Token.END_ARRAY) {
151-
queries.add(parseContext.parseInnerQueryBuilder());
149+
queries.add(parseInnerQueryBuilder(parser));
152150
token = parser.nextToken();
153151
}
154152
} else {

core/src/main/java/org/elasticsearch/index/query/ExistsQueryBuilder.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,7 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep
8383
builder.endObject();
8484
}
8585

86-
public static ExistsQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
87-
XContentParser parser = parseContext.parser();
88-
86+
public static ExistsQueryBuilder fromXContent(XContentParser parser) throws IOException {
8987
String fieldPattern = null;
9088
String queryName = null;
9189
float boost = AbstractQueryBuilder.DEFAULT_BOOST;

core/src/main/java/org/elasticsearch/index/query/FieldMaskingSpanQueryBuilder.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,7 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep
100100
builder.endObject();
101101
}
102102

103-
public static FieldMaskingSpanQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
104-
XContentParser parser = parseContext.parser();
105-
103+
public static FieldMaskingSpanQueryBuilder fromXContent(XContentParser parser) throws IOException {
106104
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
107105

108106
SpanQueryBuilder inner = null;
@@ -116,7 +114,7 @@ public static FieldMaskingSpanQueryBuilder fromXContent(QueryParseContext parseC
116114
currentFieldName = parser.currentName();
117115
} else if (token == XContentParser.Token.START_OBJECT) {
118116
if (QUERY_FIELD.match(currentFieldName)) {
119-
QueryBuilder query = parseContext.parseInnerQueryBuilder();
117+
QueryBuilder query = parseInnerQueryBuilder(parser);
120118
if (query instanceof SpanQueryBuilder == false) {
121119
throw new ParsingException(parser.getTokenLocation(), "[field_masking_span] query must be of type span query");
122120
}

core/src/main/java/org/elasticsearch/index/query/FuzzyQueryBuilder.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,7 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep
251251
builder.endObject();
252252
}
253253

254-
public static FuzzyQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
255-
XContentParser parser = parseContext.parser();
254+
public static FuzzyQueryBuilder fromXContent(XContentParser parser) throws IOException {
256255
String fieldName = null;
257256
Object value = null;
258257
Fuzziness fuzziness = FuzzyQueryBuilder.DEFAULT_FUZZINESS;
@@ -267,8 +266,6 @@ public static FuzzyQueryBuilder fromXContent(QueryParseContext parseContext) thr
267266
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
268267
if (token == XContentParser.Token.FIELD_NAME) {
269268
currentFieldName = parser.currentName();
270-
} else if (parseContext.isDeprecatedSetting(currentFieldName)) {
271-
// skip
272269
} else if (token == XContentParser.Token.START_OBJECT) {
273270
throwParsingExceptionOnMultipleFields(NAME, parser.getTokenLocation(), fieldName, currentFieldName);
274271
fieldName = currentFieldName;

0 commit comments

Comments
 (0)