-
Notifications
You must be signed in to change notification settings - Fork 25.2k
EQL: Add wildcard function #54020
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EQL: Add wildcard function #54020
Conversation
Pinging @elastic/es-search (:Search/EQL) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a round of comments
...ql/src/main/java/org/elasticsearch/xpack/eql/expression/function/scalar/string/Wildcard.java
Outdated
Show resolved
Hide resolved
...ql/src/main/java/org/elasticsearch/xpack/eql/expression/function/scalar/string/Wildcard.java
Outdated
Show resolved
Hide resolved
} | ||
|
||
public Wildcard(Source source, Expression field, List<Expression> patterns) { | ||
super(source, getArguments(field, patterns)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
super(source, getArguments(field, patterns)); | |
super(source, Arrays.asList(field, patterns)); |
like the rest of the subclasses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't seem to work if the first value is a T, and the next is a List<T>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CollectionUtils.combine(patterns, field)
or if you want to preserve the order:
CollectionUtils.combine(singletonList(field), patterns)
...ql/src/main/java/org/elasticsearch/xpack/eql/expression/function/scalar/string/Wildcard.java
Outdated
Show resolved
Hide resolved
...ql/src/main/java/org/elasticsearch/xpack/eql/expression/function/scalar/string/Wildcard.java
Outdated
Show resolved
Hide resolved
* wildcard(field, "*wildcard*pattern*", "*wildcard*pattern*") | ||
*/ | ||
|
||
public class Wildcard extends ScalarFunction { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please implement the methods in the order of the super class (which is not alphabetical) which roughly is:
constructor
nodeInfo/replaceChildren
type resolution
getters
datatype/nullable
foldable/fold
scripting & co
equals/hash
...ql/src/main/java/org/elasticsearch/xpack/eql/expression/function/scalar/string/Wildcard.java
Outdated
Show resolved
Hide resolved
x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/utils/StringUtils.java
Outdated
Show resolved
Hide resolved
@@ -421,4 +421,26 @@ public static FunctionDefinition def(Class<? extends Function> function, Functio | |||
protected interface CastFunctionBuilder<T> { | |||
T build(Source source, Expression expression, DataType dataType); | |||
} | |||
|
|||
@SuppressWarnings("overloads") // These are ambiguous if you aren't using ctor references but we always do | |||
public static <T extends Function> FunctionDefinition def(Class<T> function, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How many arguments does wildcard expect?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
at least two, but it's unbounded in the maximum number
https://eql.readthedocs.io/en/latest/query-guide/functions.html#wildcard
...in/ql/src/main/java/org/elasticsearch/xpack/ql/expression/predicate/logical/BinaryLogic.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some comments. Some of these are probably because of my lack of understanding of how wildcard
should work and what the scenarios it's covering.
private static FunctionDefinition[][] functions() { | ||
return new FunctionDefinition[][] { | ||
// Scalar functions | ||
// String | ||
new FunctionDefinition[] { | ||
def(Substring.class, Substring::new, "substring"), | ||
}, | ||
new FunctionDefinition[] { | ||
def(Wildcard.class, Wildcard::new, "wildcard"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't wildcard
a "string function"? If so, it should belong to the FunctionDefinition array that, also, has substring
in it. In SQL we were grouping these functions by their type: string, grouping, math, conditional, date etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh right, good catch
|
||
@Override | ||
protected TypeResolution resolveType() { | ||
if (!childrenResolved()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
childrenResolved() == false
|
||
@Override | ||
public boolean foldable() { | ||
return Expressions.foldable(arguments()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't the field be, also, foldable? (ie return Expressions.foldable(children());
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since wildcard
is converted to a bunch of LIKEs, I'm wondering if foldable()
shouldn't fall back to the result of the wildcard
-> LIKEs
transformation foldable()
functionality. Basically the Or.foldable()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
arguments() = field + patterns()
arguments() comes from the super and is identical to children()
I'll swap to children() since that's more obvious
} | ||
|
||
for (Expression p: patterns) { | ||
lastResolution = isStringAndExact(p, sourceText(), ParamOrdinal.DEFAULT); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think isStringAndExact
is correct here... "exact" refers to a field being of type keyword
or having a sub-field of type keyword
basically. isString
should be enough imo.
Also, shouldn't the p.foldable() == false
(comparison against variables basically) check be before this one?
return result; | ||
} | ||
|
||
private static List<Expression> toArguments(Expression src, List<Expression> patterns) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe move this method to org.elasticsearch.xpack.ql.util.CollectionUtils
and make it more generic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
saw this kind fo construct used in few places
CollectionUtils.combine(singletonList(src), patterns))
if (e instanceof Wildcard) { | ||
e = ((Wildcard) e).asLikes(); | ||
} | ||
|
||
return e; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return e instanceof Wildcard ? ((Wildcard) e).asLikes() : e;
as a shorter (hopefully more elegant) variant?
@@ -22,4 +24,19 @@ public void testPropertyEquationInClauseFilterUnsupported() { | |||
String msg = e.getMessage(); | |||
assertEquals("Line 1:52: Comparisons against variables are not (currently) supported; offender [parent_process_name] in [==]", msg); | |||
} | |||
|
|||
public void testWildcardNotEnoughArguments() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there are other error messages to check with wildcard
: the fact that the field needs to be string and exact and, also, that the "patterns" should be all strings, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@elastic/es-ql |
* EQL: Add wildcard function * EQL: Cleanup Wildcard.getArguments * EQL: Cleanup Wildcard and rearrange methods * EQL: Wildcard newline lint * EQL: Make StringUtils function final * EQL: Make Wildcard.asLikes return ScalarFunction * QL: Restore BinaryLogic.java * EQL: Add Wildcard PR feedback * EQL: Add Wildcard verification tests * EQL: Switch wildcard to isFoldable test * EQL: Change wildcard test to numeric field * EQL: Remove Wildcard.get_arguments
Backport 022f829 |
Resolves #53999
Or
ofLike
s, and updated Optimizer rule to uses that.Or
ofLike
s.