Skip to content

Commit 55fdb7e

Browse files
authored
EQL: make endsWith function use a wildcard ES query wherever possible (#61160)
1 parent 8da6bba commit 55fdb7e

File tree

3 files changed

+27
-15
lines changed

3 files changed

+27
-15
lines changed

x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/expression/function/scalar/string/EndsWith.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ protected TypeResolution resolveType() {
6464
return isStringAndExact(pattern, sourceText(), ParamOrdinal.SECOND);
6565
}
6666

67+
public Expression input() {
68+
return input;
69+
}
70+
71+
public Expression pattern() {
72+
return pattern;
73+
}
74+
6775
@Override
6876
protected Pipe makePipe() {
6977
return new EndsWithFunctionPipe(source(), this, Expressions.pipe(input), Expressions.pipe(pattern), isCaseSensitive());

x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/planner/QueryTranslator.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package org.elasticsearch.xpack.eql.planner;
88

99
import org.elasticsearch.xpack.eql.expression.function.scalar.string.CIDRMatch;
10+
import org.elasticsearch.xpack.eql.expression.function.scalar.string.EndsWith;
1011
import org.elasticsearch.xpack.eql.expression.function.scalar.string.StringContains;
1112
import org.elasticsearch.xpack.ql.QlIllegalArgumentException;
1213
import org.elasticsearch.xpack.ql.expression.Expression;
@@ -41,9 +42,6 @@ final class QueryTranslator {
4142
new ExpressionTranslators.Nots(),
4243
new ExpressionTranslators.Likes(),
4344
new ExpressionTranslators.InComparisons(),
44-
new ExpressionTranslators.StringQueries(),
45-
new ExpressionTranslators.Matches(),
46-
new ExpressionTranslators.MultiMatches(),
4745
new CaseSensitiveScalarFunctions(),
4846
new Scalars()
4947
);
@@ -132,15 +130,20 @@ public static Query doTranslate(CaseSensitiveScalarFunction f, TranslatorHandler
132130
StringContains sc = (StringContains) f;
133131
field = sc.string();
134132
constant = sc.substring();
133+
} else if (f instanceof EndsWith) {
134+
EndsWith ew = (EndsWith) f;
135+
field = ew.input();
136+
constant = ew.pattern();
135137
} else {
136138
return null;
137139
}
138140

139141
if (field instanceof FieldAttribute && constant.foldable()) {
140142
String targetFieldName = handler.nameOf(((FieldAttribute) field).exactAttribute());
141143
String substring = (String) constant.fold();
144+
String query = "*" + substring + (f instanceof StringContains ? "*" : "");
142145

143-
return new WildcardQuery(f.source(), targetFieldName, "*" + substring + "*");
146+
return new WildcardQuery(f.source(), targetFieldName, query);
144147
}
145148

146149
return null;

x-pack/plugin/eql/src/test/resources/queryfolder_tests.txt

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,8 @@ process where cidrMatch(source_address, "10.0.0.0/8") != false
105105
twoFunctionsEqualsBooleanLiterals-caseSensitive
106106
process where endsWith(process_path, 'x') == true and endsWith(process_path, 'yx') == false
107107
;
108-
"bool":{"must":[{"term":{"event.category":{"value":"process"
109-
"must":[{"script":{"script":{"source":"InternalQlScriptUtils.nullSafeFilter(
110-
InternalEqlScriptUtils.endsWith(InternalQlScriptUtils.docValue(doc,params.v0),params.v1,params.v2))","lang":"painless",
111-
"params":{"v0":"process_path","v1":"x","v2":true}}
112-
"script":{"script":{"source":"InternalQlScriptUtils.nullSafeFilter(InternalQlScriptUtils.not(
113-
InternalEqlScriptUtils.endsWith(InternalQlScriptUtils.docValue(doc,params.v0),params.v1,params.v2)))","lang":"painless",
114-
"params":{"v0":"process_path","v1":"yx","v2":true}}
108+
{"bool":{"must":[{"wildcard":{"process_path":{"wildcard":"*x","boost":1.0}}},
109+
{"bool":{"must_not":[{"wildcard":{"process_path":{"wildcard":"*yx","boost":1.0}}}],"boost":1.0}}],"boost":1.0}}
115110
;
116111

117112
twoFunctionsEqualsBooleanLiterals-caseInsensitive
@@ -126,12 +121,18 @@ InternalEqlScriptUtils.endsWith(InternalQlScriptUtils.docValue(doc,params.v0),pa
126121
"params":{"v0":"process_path","v1":"yx","v2":false}}
127122
;
128123

129-
endsWithFunction-caseSensitive
124+
endsWithKeywordFieldFunction-caseSensitive
130125
process where endsWith(user_name, 'c')
131126
;
132-
"script":{"source":"InternalQlScriptUtils.nullSafeFilter(InternalEqlScriptUtils.endsWith(
133-
InternalQlScriptUtils.docValue(doc,params.v0),params.v1,params.v2))",
134-
"params":{"v0":"user_name","v1":"c","v2":true}}
127+
{"bool":{"must":[{"term":{"event.category":{"value":"process","boost":1.0}}},
128+
{"wildcard":{"user_name":{"wildcard":"*c","boost":1.0}}}],"boost":1.0}}
129+
;
130+
131+
endsWithWildcardSubFieldFunction-caseSensitive
132+
process where endsWith(hostname, 'c')
133+
;
134+
{"bool":{"must":[{"term":{"event.category":{"value":"process","boost":1.0}}},
135+
{"wildcard":{"hostname.keyword":{"wildcard":"*c","boost":1.0}}}],"boost":1.0}}
135136
;
136137

137138
endsWithFunction-caseInsensitive

0 commit comments

Comments
 (0)