Skip to content

Commit f339282

Browse files
authored
[Rest Api Compatibility] Typed query (#75453)
Type query support was removed in #47207. This query will throw an exception in v7 rest api compatibility indicating that the support was removed + deprecation warnings. In v8 it will not be available and error about type query being not found will be returned. relates main meta issue #51816 relates types removal meta #54160
1 parent d671e3f commit f339282

File tree

5 files changed

+170
-6
lines changed

5 files changed

+170
-6
lines changed

rest-api-spec/build.gradle

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,10 @@ def v7compatibilityNotSupportedTests = {
8080

8181
'field_caps/30_filter/Field caps with index filter', //behaviour change after #63692 4digits dates are parsed as epoch and in quotes as year
8282

83-
'indices.forcemerge/10_basic/Check deprecation warning when incompatible only_expunge_deletes and max_num_segments values are both set', //#44761 bug fix
83+
'indices.forcemerge/10_basic/Check deprecation warning when incompatible only_expunge_deletes and max_num_segments values are both set', //#44761 bug fix,
84+
85+
'search/340_type_query/type query' //#47207 type query throws exception in compatible mode
86+
8487
]
8588
}
8689
tasks.named("yamlRestCompatTest").configure {
@@ -91,7 +94,6 @@ tasks.named("yamlRestCompatTest").configure {
9194
systemProperty 'tests.rest.blacklist', ([
9295
'search.aggregation/200_top_hits_metric/top_hits aggregation with sequence numbers',
9396
'search/310_match_bool_prefix/multi_match multiple fields with cutoff_frequency throws exception', //cutoff_frequency
94-
'search/340_type_query/type query', // type_query - probably should behave like match_all
9597
] + v7compatibilityNotSupportedTests())
9698
.join(',')
9799

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
setup:
3+
- skip:
4+
features:
5+
- "headers"
6+
- "allowed_warnings_regex"
7+
---
8+
type query throws exception when used:
9+
- do:
10+
index:
11+
index: "test1"
12+
id: 1
13+
type: "cat"
14+
refresh: true
15+
body:
16+
foo: "bar"
17+
headers:
18+
Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
19+
Accept: "application/vnd.elasticsearch+json;compatible-with=7"
20+
allowed_warnings_regex:
21+
- "\\[types removal\\].*"
22+
23+
- do:
24+
catch: /\[types removal\] Type queries are deprecated, prefer to filter on a field instead./
25+
search:
26+
rest_total_hits_as_int: true
27+
index: "test1"
28+
body:
29+
query:
30+
type:
31+
value: "cat"
32+
headers:
33+
Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
34+
Accept: "application/vnd.elasticsearch+json;compatible-with=7"
35+
allowed_warnings_regex:
36+
- "\\[types removal\\].*"
37+
38+
- do:
39+
catch: /\[types removal\] Type queries are deprecated, prefer to filter on a field instead./
40+
search:
41+
rest_total_hits_as_int: true
42+
index: "test1"
43+
body:
44+
query:
45+
type:
46+
value: "_doc"
47+
headers:
48+
Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
49+
Accept: "application/vnd.elasticsearch+json;compatible-with=7"
50+
allowed_warnings_regex:
51+
- "\\[types removal\\].*"
52+
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
package org.elasticsearch.index.query;
10+
11+
import org.apache.lucene.search.MatchNoDocsQuery;
12+
import org.apache.lucene.search.Query;
13+
import org.elasticsearch.common.ParsingException;
14+
import org.elasticsearch.common.io.stream.StreamInput;
15+
import org.elasticsearch.common.io.stream.StreamOutput;
16+
import org.elasticsearch.common.logging.DeprecationLogger;
17+
import org.elasticsearch.common.xcontent.ObjectParser;
18+
import org.elasticsearch.common.xcontent.ParseField;
19+
import org.elasticsearch.common.xcontent.XContentBuilder;
20+
import org.elasticsearch.common.xcontent.XContentParser;
21+
import org.elasticsearch.core.RestApiVersion;
22+
import org.elasticsearch.index.mapper.MapperService;
23+
24+
import java.io.IOException;
25+
26+
public class TypeQueryV7Builder extends AbstractQueryBuilder<TypeQueryV7Builder> {
27+
private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(TypeQueryV7Builder.class);
28+
public static final String TYPES_DEPRECATION_MESSAGE = "[types removal] Type queries are deprecated, " +
29+
"prefer to filter on a field instead.";
30+
31+
private static final String NAME = "type";
32+
public static final ParseField NAME_V7 = new ParseField(NAME).forRestApiVersion(RestApiVersion.equalTo(RestApiVersion.V_7));
33+
private static final ParseField VALUE_FIELD = new ParseField("value");
34+
private static final ObjectParser<TypeQueryV7Builder, Void> PARSER = new ObjectParser<>(NAME, TypeQueryV7Builder::new);
35+
36+
static {
37+
PARSER.declareString(QueryBuilder::queryName,
38+
AbstractQueryBuilder.NAME_FIELD.forRestApiVersion(RestApiVersion.equalTo(RestApiVersion.V_7)));
39+
PARSER.declareFloat(QueryBuilder::boost,
40+
AbstractQueryBuilder.BOOST_FIELD.forRestApiVersion(RestApiVersion.equalTo(RestApiVersion.V_7)));
41+
PARSER.declareString(TypeQueryV7Builder::setValue,
42+
VALUE_FIELD.forRestApiVersion(RestApiVersion.equalTo(RestApiVersion.V_7)));
43+
}
44+
45+
private String value;
46+
47+
public TypeQueryV7Builder() {
48+
}
49+
50+
/**
51+
* Read from a stream.
52+
*/
53+
public TypeQueryV7Builder(StreamInput in) throws IOException {
54+
super(in);
55+
}
56+
57+
@Override
58+
protected void doWriteTo(StreamOutput out) throws IOException {
59+
}
60+
61+
@Override
62+
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
63+
builder.startObject(NAME);
64+
builder.field(VALUE_FIELD.getPreferredName(), MapperService.SINGLE_MAPPING_NAME);
65+
printBoostAndQueryName(builder);
66+
builder.endObject();
67+
}
68+
69+
@Override
70+
protected Query doToQuery(SearchExecutionContext context) throws IOException {
71+
return new MatchNoDocsQuery();
72+
}
73+
74+
@Override
75+
protected boolean doEquals(TypeQueryV7Builder other) {
76+
return true;
77+
}
78+
79+
@Override
80+
protected int doHashCode() {
81+
return 0;
82+
}
83+
84+
public static TypeQueryV7Builder fromXContent(XContentParser parser) throws IOException {
85+
deprecationLogger.compatibleApiWarning("type_query", TYPES_DEPRECATION_MESSAGE);
86+
throw new ParsingException(parser.getTokenLocation(), TYPES_DEPRECATION_MESSAGE);
87+
}
88+
89+
@Override
90+
public String getWriteableName() {
91+
return NAME;
92+
}
93+
94+
public void setValue(String value){
95+
this.value = value;
96+
}
97+
}

server/src/main/java/org/elasticsearch/search/SearchModule.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import org.apache.lucene.search.BooleanQuery;
1212
import org.elasticsearch.common.CheckedBiConsumer;
1313
import org.elasticsearch.common.NamedRegistry;
14-
import org.elasticsearch.common.xcontent.ParseField;
1514
import org.elasticsearch.common.geo.GeoShapeType;
1615
import org.elasticsearch.common.geo.ShapesAvailability;
1716
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
@@ -21,8 +20,10 @@
2120
import org.elasticsearch.common.settings.Setting;
2221
import org.elasticsearch.common.settings.Settings;
2322
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
23+
import org.elasticsearch.common.xcontent.ParseField;
2424
import org.elasticsearch.common.xcontent.XContentParser;
2525
import org.elasticsearch.core.Nullable;
26+
import org.elasticsearch.core.RestApiVersion;
2627
import org.elasticsearch.index.query.BoolQueryBuilder;
2728
import org.elasticsearch.index.query.BoostingQueryBuilder;
2829
import org.elasticsearch.index.query.CombinedFieldsQueryBuilder;
@@ -67,6 +68,7 @@
6768
import org.elasticsearch.index.query.TermQueryBuilder;
6869
import org.elasticsearch.index.query.TermsQueryBuilder;
6970
import org.elasticsearch.index.query.TermsSetQueryBuilder;
71+
import org.elasticsearch.index.query.TypeQueryV7Builder;
7072
import org.elasticsearch.index.query.WildcardQueryBuilder;
7173
import org.elasticsearch.index.query.WrapperQueryBuilder;
7274
import org.elasticsearch.index.query.functionscore.ExponentialDecayFunctionBuilder;
@@ -839,6 +841,10 @@ private void registerQueryParsers(List<SearchPlugin> plugins) {
839841
}
840842

841843
registerFromPlugin(plugins, SearchPlugin::getQueries, this::registerQuery);
844+
845+
if (RestApiVersion.minimumSupported() == RestApiVersion.V_7) {
846+
registerQuery(new QuerySpec<>(TypeQueryV7Builder.NAME_V7, TypeQueryV7Builder::new, TypeQueryV7Builder::fromXContent));
847+
}
842848
}
843849

844850
private void registerIntervalsSourceProviders() {
@@ -893,4 +899,5 @@ private void registerBoolQuery(ParseField name, Writeable.Reader<QueryBuilder> r
893899
public FetchPhase getFetchPhase() {
894900
return new FetchPhase(fetchSubPhases);
895901
}
902+
896903
}

server/src/test/java/org/elasticsearch/search/SearchModuleTests.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.elasticsearch.index.query.QueryRewriteContext;
2626
import org.elasticsearch.index.query.SearchExecutionContext;
2727
import org.elasticsearch.index.query.TermQueryBuilder;
28+
import org.elasticsearch.index.query.TypeQueryV7Builder;
2829
import org.elasticsearch.index.query.functionscore.GaussDecayFunctionBuilder;
2930
import org.elasticsearch.plugins.SearchPlugin;
3031
import org.elasticsearch.search.aggregations.AggregationBuilder;
@@ -241,11 +242,14 @@ public void testRegisteredQueries() {
241242
List<String> allSupportedQueries = new ArrayList<>();
242243
Collections.addAll(allSupportedQueries, NON_DEPRECATED_QUERIES);
243244
Collections.addAll(allSupportedQueries, DEPRECATED_QUERIES);
245+
Collections.addAll(allSupportedQueries, REST_COMPATIBLE_QUERIES);
246+
244247
SearchModule module = new SearchModule(Settings.EMPTY, emptyList());
245248

246249
Set<String> registeredNonDeprecated = module.getNamedXContents().stream()
247250
.filter(e -> e.categoryClass.equals(QueryBuilder.class))
248251
.filter(e -> e.name.getAllReplacedWith() == null)
252+
.filter(e -> RestApiVersion.current().matches(e.restApiCompatibility))
249253
.map(e -> e.name.getPreferredName())
250254
.collect(toSet());
251255
Set<String> registeredAll = module.getNamedXContents().stream()
@@ -389,6 +393,7 @@ public CheckedBiConsumer<ShardSearchRequest, StreamOutput, IOException> getReque
389393

390394
//add here deprecated queries to make sure we log a deprecation warnings when they are used
391395
private static final String[] DEPRECATED_QUERIES = new String[] {"field_masking_span", "geo_polygon"};
396+
private static final String[] REST_COMPATIBLE_QUERIES = new String[] {TypeQueryV7Builder.NAME_V7.getPreferredName()};
392397

393398
/**
394399
* Dummy test {@link AggregationBuilder} used to test registering aggregation builders.
@@ -669,14 +674,15 @@ public List<SearchPlugin.QuerySpec<?>> getQueries() {
669674
.filter(e -> RestApiVersion.minimumSupported().matches(e.restApiCompatibility))
670675
.filter(e -> RestApiVersion.current().matches(e.restApiCompatibility))
671676
.collect(toSet()),
672-
hasSize(searchModule.getNamedXContents().size() - 1));
677+
hasSize(searchModule.getNamedXContents().size()- REST_COMPATIBLE_QUERIES.length - 1 ));
673678

674679

675680
final List<NamedXContentRegistry.Entry> compatEntry = searchModule.getNamedXContents().stream()
676681
.filter(e -> e.categoryClass.equals(QueryBuilder.class) &&
677-
e.name.match(CompatQueryBuilder.NAME_OLD.getPreferredName(), LoggingDeprecationHandler.INSTANCE))
682+
RestApiVersion.minimumSupported().matches(e.name.getForRestApiVersion()) // v7 compatbile
683+
&& RestApiVersion.current().matches(e.name.getForRestApiVersion()) == false) // but not v8 compatible
678684
.collect(toList());
679-
assertThat(compatEntry, hasSize(1));
685+
assertThat(compatEntry, hasSize(REST_COMPATIBLE_QUERIES.length + 1));//+1 because of registered in the test
680686
assertTrue(RestApiVersion.minimumSupported().matches(compatEntry.get(0).restApiCompatibility));
681687
assertFalse(RestApiVersion.current().matches(compatEntry.get(0).restApiCompatibility));
682688
}

0 commit comments

Comments
 (0)