Skip to content

Commit 42b7a20

Browse files
committed
Fix delegate for ignored fields
1 parent 9bd4b89 commit 42b7a20

File tree

5 files changed

+96
-40
lines changed

5 files changed

+96
-40
lines changed

x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestsDataLoader.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ public class CsvTestsDataLoader {
139139
private static final TestDataset BOOKS = new TestDataset("books").withSetting("books-settings.json");
140140
private static final TestDataset SEMANTIC_TEXT = new TestDataset("semantic_text").withInferenceEndpoint(true);
141141
private static final TestDataset LOGS = new TestDataset("logs");
142+
private static final TestDataset MV_TEXT = new TestDataset("mv_text");
142143

143144
public static final Map<String, TestDataset> CSV_DATASET_MAP = Map.ofEntries(
144145
Map.entry(EMPLOYEES.indexName, EMPLOYEES),
@@ -196,7 +197,8 @@ public class CsvTestsDataLoader {
196197
Map.entry(ADDRESSES.indexName, ADDRESSES),
197198
Map.entry(BOOKS.indexName, BOOKS),
198199
Map.entry(SEMANTIC_TEXT.indexName, SEMANTIC_TEXT),
199-
Map.entry(LOGS.indexName, LOGS)
200+
Map.entry(LOGS.indexName, LOGS),
201+
Map.entry(MV_TEXT.indexName, MV_TEXT)
200202
);
201203

202204
private static final EnrichConfig LANGUAGES_ENRICH = new EnrichConfig("languages_policy", "enrich-policy-languages.json");
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@timestamp:date ,message:text
2+
2023-10-23T13:55:01.543Z,[Connected to 10.1.0.1, Banana]
3+
2023-10-23T13:55:01.544Z,Connected to 10.1.0.1
4+
2023-10-23T13:55:01.545Z,[Connected to 10.1.0.1, More than one hundred characters long so it isn't indexed by the sub keyword field with ignore_above:100]
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"properties": {
3+
"@timestamp": {
4+
"type": "date"
5+
},
6+
"message": {
7+
"type": "text",
8+
"fields": {
9+
"raw": {
10+
"type": "keyword",
11+
"ignore_above": 100
12+
}
13+
}
14+
}
15+
}
16+
}

x-pack/plugin/esql/qa/testFixtures/src/main/resources/string.csv-spec

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2308,3 +2308,15 @@ message:keyword
23082308
foo ( bar
23092309
// end::rlikeEscapingTripleQuotes-result[]
23102310
;
2311+
2312+
mvStringEquals
2313+
FROM mv_text
2314+
| WHERE message == "Connected to 10.1.0.1"
2315+
| KEEP @timestamp, message
2316+
;
2317+
warning:Line 2:9: evaluation of [message == \"Connected to 10.1.0.1\"] failed, treating result as null. Only first 20 failures recorded.
2318+
warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value
2319+
2320+
@timestamp:date | message:text
2321+
2023-10-23T13:55:01.544Z|Connected to 10.1.0.1
2322+
;

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/querydsl/query/SingleValueQuery.java

Lines changed: 61 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.apache.lucene.search.BooleanQuery;
1212
import org.apache.lucene.search.MatchAllDocsQuery;
1313
import org.apache.lucene.search.MatchNoDocsQuery;
14+
import org.apache.lucene.search.TermQuery;
1415
import org.elasticsearch.TransportVersion;
1516
import org.elasticsearch.TransportVersions;
1617
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
@@ -19,6 +20,7 @@
1920
import org.elasticsearch.compute.operator.DriverContext;
2021
import org.elasticsearch.compute.operator.Warnings;
2122
import org.elasticsearch.compute.querydsl.query.SingleValueMatchQuery;
23+
import org.elasticsearch.index.mapper.IgnoredFieldMapper;
2224
import org.elasticsearch.index.mapper.MappedFieldType;
2325
import org.elasticsearch.index.mapper.TextFieldMapper;
2426
import org.elasticsearch.index.query.AbstractQueryBuilder;
@@ -30,6 +32,7 @@
3032
import org.elasticsearch.xpack.esql.core.querydsl.query.Query;
3133
import org.elasticsearch.xpack.esql.core.tree.Location;
3234
import org.elasticsearch.xpack.esql.core.tree.Source;
35+
import org.elasticsearch.xpack.esql.expression.function.fulltext.Term;
3336
import org.elasticsearch.xpack.esql.io.stream.PlanStreamInput;
3437

3538
import java.io.IOException;
@@ -163,35 +166,6 @@ public Source source() {
163166
return source;
164167
}
165168

166-
protected abstract MappedFieldType mappedFieldType(SearchExecutionContext context);
167-
168-
@Override
169-
protected final org.apache.lucene.search.Query doToQuery(SearchExecutionContext context) throws IOException {
170-
MappedFieldType ft = mappedFieldType(context);
171-
if (ft == null) {
172-
return new MatchNoDocsQuery("missing field [" + field + "]");
173-
}
174-
SingleValueMatchQuery singleValueQuery = new SingleValueMatchQuery(
175-
context.getForField(ft, MappedFieldType.FielddataOperation.SEARCH),
176-
Warnings.createWarnings(
177-
DriverContext.WarningsMode.COLLECT,
178-
source.source().getLineNumber(),
179-
source.source().getColumnNumber(),
180-
source.text()
181-
),
182-
"single-value function encountered multi-value"
183-
);
184-
org.apache.lucene.search.Query rewrite = singleValueQuery.rewrite(context.searcher());
185-
if (rewrite instanceof MatchAllDocsQuery) {
186-
// nothing to filter
187-
return next.toQuery(context);
188-
}
189-
BooleanQuery.Builder builder = new BooleanQuery.Builder();
190-
builder.add(next.toQuery(context), BooleanClause.Occur.FILTER);
191-
builder.add(rewrite, BooleanClause.Occur.FILTER);
192-
return builder.build();
193-
}
194-
195169
protected abstract AbstractBuilder rewrite(QueryBuilder next);
196170

197171
@Override
@@ -246,8 +220,30 @@ public TransportVersion getMinimalSupportedVersion() {
246220
}
247221

248222
@Override
249-
protected MappedFieldType mappedFieldType(SearchExecutionContext context) {
250-
return context.getFieldType(field());
223+
protected final org.apache.lucene.search.Query doToQuery(SearchExecutionContext context) throws IOException {
224+
MappedFieldType ft = context.getFieldType(field());
225+
if (ft == null) {
226+
return new MatchNoDocsQuery("missing field [" + field() + "]");
227+
}
228+
SingleValueMatchQuery singleValueQuery = new SingleValueMatchQuery(
229+
context.getForField(ft, MappedFieldType.FielddataOperation.SEARCH),
230+
Warnings.createWarnings(
231+
DriverContext.WarningsMode.COLLECT,
232+
source().source().getLineNumber(),
233+
source().source().getColumnNumber(),
234+
source().text()
235+
),
236+
"single-value function encountered multi-value"
237+
);
238+
org.apache.lucene.search.Query rewrite = singleValueQuery.rewrite(context.searcher());
239+
if (rewrite instanceof MatchAllDocsQuery) {
240+
// nothing to filter
241+
return next().toQuery(context);
242+
}
243+
BooleanQuery.Builder builder = new BooleanQuery.Builder();
244+
builder.add(next().toQuery(context), BooleanClause.Occur.FILTER);
245+
builder.add(rewrite, BooleanClause.Occur.FILTER);
246+
return builder.build();
251247
}
252248

253249
@Override
@@ -261,13 +257,9 @@ public static class SyntheticSourceDelegateBuilder extends AbstractBuilder {
261257
super(next, field, source);
262258
}
263259

264-
SyntheticSourceDelegateBuilder(StreamInput in) throws IOException {
265-
super(in);
266-
}
267-
268260
@Override
269261
public String getWriteableName() {
270-
throw new UnsupportedOperationException();
262+
throw new UnsupportedOperationException("Not serialized");
271263
}
272264

273265
@Override
@@ -281,12 +273,42 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep
281273

282274
@Override
283275
public TransportVersion getMinimalSupportedVersion() {
284-
throw new UnsupportedOperationException();
276+
throw new UnsupportedOperationException("Not serialized");
285277
}
286278

287279
@Override
288-
protected MappedFieldType mappedFieldType(SearchExecutionContext context) {
289-
return ((TextFieldMapper.TextFieldType) context.getFieldType(field())).syntheticSourceDelegate();
280+
protected final org.apache.lucene.search.Query doToQuery(SearchExecutionContext context) throws IOException {
281+
MappedFieldType ft = context.getFieldType(field());
282+
if (ft == null) {
283+
return new MatchNoDocsQuery("missing field [" + field() + "]");
284+
}
285+
ft = ((TextFieldMapper.TextFieldType) ft).syntheticSourceDelegate();
286+
287+
BooleanQuery.Builder builder = new BooleanQuery.Builder();
288+
builder.add(next().toQuery(context), BooleanClause.Occur.FILTER);
289+
290+
org.apache.lucene.search.Query singleValueQuery = new SingleValueMatchQuery(
291+
context.getForField(ft, MappedFieldType.FielddataOperation.SEARCH),
292+
Warnings.createWarnings(
293+
DriverContext.WarningsMode.COLLECT,
294+
source().source().getLineNumber(),
295+
source().source().getColumnNumber(),
296+
source().text()
297+
),
298+
"single-value function encountered multi-value"
299+
);
300+
singleValueQuery = singleValueQuery.rewrite(context.searcher());
301+
if (singleValueQuery instanceof MatchAllDocsQuery == false) {
302+
builder.add(singleValueQuery, BooleanClause.Occur.FILTER);
303+
}
304+
305+
org.apache.lucene.search.Query ignored = new TermQuery(new org.apache.lucene.index.Term(IgnoredFieldMapper.NAME, ft.name()));
306+
ignored = ignored.rewrite(context.searcher());
307+
if (ignored instanceof MatchNoDocsQuery == false) {
308+
builder.add(ignored, BooleanClause.Occur.MUST_NOT);
309+
}
310+
311+
return builder.build();
290312
}
291313

292314
@Override

0 commit comments

Comments
 (0)