Skip to content

Commit a462700

Browse files
authored
EQL: Add AstBuilder to convert to QL tree (#51558)
* EQL: Add AstBuilder visitors * EQL: Add tests for wildcards and sets * EQL: Fix licensing * EQL: Fix ExpressionTests.java license * EQL: Cleanup imports * EQL: PR feedback and remove LiteralBuilder * EQL: Split off logical plan from expressions * EQL: Remove stray import * EQL: Add predicate handling for set checks * EQL: Remove commented out dead code * EQL: Remove wildcard test, wait until analyzer
1 parent c0646ea commit a462700

File tree

16 files changed

+949
-545
lines changed

16 files changed

+949
-545
lines changed

x-pack/plugin/eql/src/main/antlr/EqlBase.g4

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -73,32 +73,27 @@ expression
7373
booleanExpression
7474
: NOT booleanExpression #logicalNot
7575
| relationship=IDENTIFIER OF subquery #processCheck
76-
| predicated #booleanDefault
76+
| valueExpression #booleanDefault
7777
| left=booleanExpression operator=AND right=booleanExpression #logicalBinary
7878
| left=booleanExpression operator=OR right=booleanExpression #logicalBinary
7979
;
8080

81-
// workaround for:
82-
// https://github.com/antlr/antlr4/issues/780
83-
// https://github.com/antlr/antlr4/issues/781
84-
predicated
85-
: valueExpression predicate?
86-
;
87-
88-
// dedicated calls for each branch are not used to reuse the NOT handling across them
89-
// instead the property kind is used for differentiation
90-
predicate
91-
: NOT? kind=IN LP valueExpression (COMMA valueExpression)* RP
92-
;
9381

9482
valueExpression
95-
: primaryExpression #valueExpressionDefault
83+
: primaryExpression predicate? #valueExpressionDefault
9684
| operator=(MINUS | PLUS) valueExpression #arithmeticUnary
9785
| left=valueExpression operator=(ASTERISK | SLASH | PERCENT) right=valueExpression #arithmeticBinary
9886
| left=valueExpression operator=(PLUS | MINUS) right=valueExpression #arithmeticBinary
9987
| left=valueExpression comparisonOperator right=valueExpression #comparison
10088
;
10189

90+
// workaround for
91+
// https://github.com/antlr/antlr4/issues/780
92+
// https://github.com/antlr/antlr4/issues/781
93+
predicate
94+
: NOT? kind=IN LP expression (COMMA expression)* RP
95+
;
96+
10297
primaryExpression
10398
: constant #constantDefault
10499
| functionExpression #function

x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/parser/AbstractBuilder.java

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import org.antlr.v4.runtime.misc.Interval;
1111
import org.antlr.v4.runtime.tree.ParseTree;
1212
import org.antlr.v4.runtime.tree.TerminalNode;
13-
import org.elasticsearch.xpack.ql.expression.Expression;
13+
import org.elasticsearch.xpack.ql.plan.logical.LogicalPlan;
1414
import org.elasticsearch.xpack.ql.tree.Location;
1515
import org.elasticsearch.xpack.ql.tree.Source;
1616
import org.elasticsearch.xpack.ql.util.Check;
@@ -25,6 +25,8 @@
2525
*/
2626
abstract class AbstractBuilder extends EqlBaseBaseVisitor<Object> {
2727

28+
private static final Pattern slashPattern = Pattern.compile("\\\\.");
29+
2830
@Override
2931
public Object visit(ParseTree tree) {
3032
Object result = super.visit(tree);
@@ -44,12 +46,12 @@ protected <T> T typedParsing(ParseTree ctx, Class<T> type) {
4446
type.getSimpleName(), (result != null ? result.getClass().getSimpleName() : "null"));
4547
}
4648

47-
protected Expression expression(ParseTree ctx) {
48-
return typedParsing(ctx, Expression.class);
49+
protected LogicalPlan plan(ParseTree ctx) {
50+
return typedParsing(ctx, LogicalPlan.class);
4951
}
5052

51-
protected List<Expression> expressions(List<? extends ParserRuleContext> ctxs) {
52-
return visitList(ctxs, Expression.class);
53+
protected List<LogicalPlan> plans(List<? extends ParserRuleContext> ctxs) {
54+
return visitList(ctxs, LogicalPlan.class);
5355
}
5456

5557
protected <T> List<T> visitList(List<? extends ParserRuleContext> contexts, Class<T> clazz) {
@@ -113,14 +115,7 @@ static String text(ParseTree node) {
113115
return node == null ? null : node.getText();
114116
}
115117

116-
/**
117-
* Extracts the actual unescaped string (literal) value of a terminal node.
118-
*/
119-
static String string(TerminalNode node) {
120-
return node == null ? null : unquoteString(node.getText());
121-
}
122-
123-
static String unquoteString(String text) {
118+
public static String unquoteString(String text) {
124119
// remove leading and trailing ' for strings and also eliminate escaped single quotes
125120
if (text == null) {
126121
return null;
@@ -132,9 +127,8 @@ static String unquoteString(String text) {
132127
}
133128

134129
text = text.substring(1, text.length() - 1);
135-
Pattern regex = Pattern.compile("\\\\.");
136130
StringBuffer resultString = new StringBuffer();
137-
Matcher regexMatcher = regex.matcher(text);
131+
Matcher regexMatcher = slashPattern.matcher(text);
138132

139133
while (regexMatcher.find()) {
140134
String source = regexMatcher.group();
@@ -167,6 +161,7 @@ static String unquoteString(String text) {
167161
replacement = "\\\\";
168162
break;
169163
default:
164+
// unknown escape sequence, pass through as-is
170165
replacement = source;
171166
}
172167

@@ -183,4 +178,5 @@ public Object visitTerminal(TerminalNode node) {
183178
Source source = source(node);
184179
throw new ParsingException(source, "Does not know how to handle {}", source.text());
185180
}
181+
186182
}

x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/parser/AstBuilder.java

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

99
import org.elasticsearch.xpack.eql.parser.EqlBaseParser.SingleStatementContext;
10+
import org.elasticsearch.xpack.ql.plan.logical.LogicalPlan;
1011

11-
public class AstBuilder extends ExpressionBuilder {
12+
public class AstBuilder extends LogicalPlanBuilder {
1213

1314
@Override
14-
public Object visitSingleStatement(SingleStatementContext ctx) {
15-
return expression(ctx.statement());
15+
public LogicalPlan visitSingleStatement(SingleStatementContext ctx) {
16+
return plan(ctx.statement());
1617
}
17-
}
18+
}

x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/parser/EqlBaseBaseListener.java

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -232,73 +232,61 @@ class EqlBaseBaseListener implements EqlBaseListener {
232232
*
233233
* <p>The default implementation does nothing.</p>
234234
*/
235-
@Override public void enterPredicated(EqlBaseParser.PredicatedContext ctx) { }
236-
/**
237-
* {@inheritDoc}
238-
*
239-
* <p>The default implementation does nothing.</p>
240-
*/
241-
@Override public void exitPredicated(EqlBaseParser.PredicatedContext ctx) { }
242-
/**
243-
* {@inheritDoc}
244-
*
245-
* <p>The default implementation does nothing.</p>
246-
*/
247-
@Override public void enterPredicate(EqlBaseParser.PredicateContext ctx) { }
235+
@Override public void enterValueExpressionDefault(EqlBaseParser.ValueExpressionDefaultContext ctx) { }
248236
/**
249237
* {@inheritDoc}
250238
*
251239
* <p>The default implementation does nothing.</p>
252240
*/
253-
@Override public void exitPredicate(EqlBaseParser.PredicateContext ctx) { }
241+
@Override public void exitValueExpressionDefault(EqlBaseParser.ValueExpressionDefaultContext ctx) { }
254242
/**
255243
* {@inheritDoc}
256244
*
257245
* <p>The default implementation does nothing.</p>
258246
*/
259-
@Override public void enterValueExpressionDefault(EqlBaseParser.ValueExpressionDefaultContext ctx) { }
247+
@Override public void enterComparison(EqlBaseParser.ComparisonContext ctx) { }
260248
/**
261249
* {@inheritDoc}
262250
*
263251
* <p>The default implementation does nothing.</p>
264252
*/
265-
@Override public void exitValueExpressionDefault(EqlBaseParser.ValueExpressionDefaultContext ctx) { }
253+
@Override public void exitComparison(EqlBaseParser.ComparisonContext ctx) { }
266254
/**
267255
* {@inheritDoc}
268256
*
269257
* <p>The default implementation does nothing.</p>
270258
*/
271-
@Override public void enterComparison(EqlBaseParser.ComparisonContext ctx) { }
259+
@Override public void enterArithmeticBinary(EqlBaseParser.ArithmeticBinaryContext ctx) { }
272260
/**
273261
* {@inheritDoc}
274262
*
275263
* <p>The default implementation does nothing.</p>
276264
*/
277-
@Override public void exitComparison(EqlBaseParser.ComparisonContext ctx) { }
265+
@Override public void exitArithmeticBinary(EqlBaseParser.ArithmeticBinaryContext ctx) { }
278266
/**
279267
* {@inheritDoc}
280268
*
281269
* <p>The default implementation does nothing.</p>
282270
*/
283-
@Override public void enterArithmeticBinary(EqlBaseParser.ArithmeticBinaryContext ctx) { }
271+
@Override public void enterArithmeticUnary(EqlBaseParser.ArithmeticUnaryContext ctx) { }
284272
/**
285273
* {@inheritDoc}
286274
*
287275
* <p>The default implementation does nothing.</p>
288276
*/
289-
@Override public void exitArithmeticBinary(EqlBaseParser.ArithmeticBinaryContext ctx) { }
277+
@Override public void exitArithmeticUnary(EqlBaseParser.ArithmeticUnaryContext ctx) { }
290278
/**
291279
* {@inheritDoc}
292280
*
293281
* <p>The default implementation does nothing.</p>
294282
*/
295-
@Override public void enterArithmeticUnary(EqlBaseParser.ArithmeticUnaryContext ctx) { }
283+
@Override public void enterPredicate(EqlBaseParser.PredicateContext ctx) { }
296284
/**
297285
* {@inheritDoc}
298286
*
299287
* <p>The default implementation does nothing.</p>
300288
*/
301-
@Override public void exitArithmeticUnary(EqlBaseParser.ArithmeticUnaryContext ctx) { }
289+
@Override public void exitPredicate(EqlBaseParser.PredicateContext ctx) { }
302290
/**
303291
* {@inheritDoc}
304292
*

x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/parser/EqlBaseBaseVisitor.java

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -143,42 +143,35 @@ class EqlBaseBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements EqlBa
143143
* <p>The default implementation returns the result of calling
144144
* {@link #visitChildren} on {@code ctx}.</p>
145145
*/
146-
@Override public T visitPredicated(EqlBaseParser.PredicatedContext ctx) { return visitChildren(ctx); }
147-
/**
148-
* {@inheritDoc}
149-
*
150-
* <p>The default implementation returns the result of calling
151-
* {@link #visitChildren} on {@code ctx}.</p>
152-
*/
153-
@Override public T visitPredicate(EqlBaseParser.PredicateContext ctx) { return visitChildren(ctx); }
146+
@Override public T visitValueExpressionDefault(EqlBaseParser.ValueExpressionDefaultContext ctx) { return visitChildren(ctx); }
154147
/**
155148
* {@inheritDoc}
156149
*
157150
* <p>The default implementation returns the result of calling
158151
* {@link #visitChildren} on {@code ctx}.</p>
159152
*/
160-
@Override public T visitValueExpressionDefault(EqlBaseParser.ValueExpressionDefaultContext ctx) { return visitChildren(ctx); }
153+
@Override public T visitComparison(EqlBaseParser.ComparisonContext ctx) { return visitChildren(ctx); }
161154
/**
162155
* {@inheritDoc}
163156
*
164157
* <p>The default implementation returns the result of calling
165158
* {@link #visitChildren} on {@code ctx}.</p>
166159
*/
167-
@Override public T visitComparison(EqlBaseParser.ComparisonContext ctx) { return visitChildren(ctx); }
160+
@Override public T visitArithmeticBinary(EqlBaseParser.ArithmeticBinaryContext ctx) { return visitChildren(ctx); }
168161
/**
169162
* {@inheritDoc}
170163
*
171164
* <p>The default implementation returns the result of calling
172165
* {@link #visitChildren} on {@code ctx}.</p>
173166
*/
174-
@Override public T visitArithmeticBinary(EqlBaseParser.ArithmeticBinaryContext ctx) { return visitChildren(ctx); }
167+
@Override public T visitArithmeticUnary(EqlBaseParser.ArithmeticUnaryContext ctx) { return visitChildren(ctx); }
175168
/**
176169
* {@inheritDoc}
177170
*
178171
* <p>The default implementation returns the result of calling
179172
* {@link #visitChildren} on {@code ctx}.</p>
180173
*/
181-
@Override public T visitArithmeticUnary(EqlBaseParser.ArithmeticUnaryContext ctx) { return visitChildren(ctx); }
174+
@Override public T visitPredicate(EqlBaseParser.PredicateContext ctx) { return visitChildren(ctx); }
182175
/**
183176
* {@inheritDoc}
184177
*

x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/parser/EqlBaseListener.java

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -195,26 +195,6 @@ interface EqlBaseListener extends ParseTreeListener {
195195
* @param ctx the parse tree
196196
*/
197197
void exitLogicalBinary(EqlBaseParser.LogicalBinaryContext ctx);
198-
/**
199-
* Enter a parse tree produced by {@link EqlBaseParser#predicated}.
200-
* @param ctx the parse tree
201-
*/
202-
void enterPredicated(EqlBaseParser.PredicatedContext ctx);
203-
/**
204-
* Exit a parse tree produced by {@link EqlBaseParser#predicated}.
205-
* @param ctx the parse tree
206-
*/
207-
void exitPredicated(EqlBaseParser.PredicatedContext ctx);
208-
/**
209-
* Enter a parse tree produced by {@link EqlBaseParser#predicate}.
210-
* @param ctx the parse tree
211-
*/
212-
void enterPredicate(EqlBaseParser.PredicateContext ctx);
213-
/**
214-
* Exit a parse tree produced by {@link EqlBaseParser#predicate}.
215-
* @param ctx the parse tree
216-
*/
217-
void exitPredicate(EqlBaseParser.PredicateContext ctx);
218198
/**
219199
* Enter a parse tree produced by the {@code valueExpressionDefault}
220200
* labeled alternative in {@link EqlBaseParser#valueExpression}.
@@ -263,6 +243,16 @@ interface EqlBaseListener extends ParseTreeListener {
263243
* @param ctx the parse tree
264244
*/
265245
void exitArithmeticUnary(EqlBaseParser.ArithmeticUnaryContext ctx);
246+
/**
247+
* Enter a parse tree produced by {@link EqlBaseParser#predicate}.
248+
* @param ctx the parse tree
249+
*/
250+
void enterPredicate(EqlBaseParser.PredicateContext ctx);
251+
/**
252+
* Exit a parse tree produced by {@link EqlBaseParser#predicate}.
253+
* @param ctx the parse tree
254+
*/
255+
void exitPredicate(EqlBaseParser.PredicateContext ctx);
266256
/**
267257
* Enter a parse tree produced by the {@code constantDefault}
268258
* labeled alternative in {@link EqlBaseParser#primaryExpression}.

0 commit comments

Comments
 (0)