From f4e6e68ea93aa779a0be00f15877e0d153a10418 Mon Sep 17 00:00:00 2001 From: Aurelien FOUCRET <aurelien.foucret@elastic.co> Date: Thu, 24 Oct 2024 18:55:20 +0200 Subject: [PATCH] Improved tests. --- x-pack/plugin/kql/src/main/antlr/KqlBase.g4 | 2 +- .../xpack/kql/parser/KqlAstBuilder.java | 14 +- .../xpack/kql/parser/KqlBase.interp | 2 +- .../xpack/kql/parser/KqlBaseParser.java | 273 +++++++++--------- .../kql/parser/AbstractKqlParserTestCase.java | 44 +++ .../parser/KqlParserBooleanQueryTests.java | 16 +- .../kql/parser/KqlParserExistsQueryTests.java | 12 +- .../kql/parser/KqlParserFieldQueryTests.java | 137 +++++++++ .../parser/KqlParserFieldlessQueryTests.java | 44 ++- .../xpack/kql/parser/ParserUtilsTests.java | 26 +- .../src/test/resources/unsupported-queries | 2 - 11 files changed, 389 insertions(+), 183 deletions(-) create mode 100644 x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/KqlParserFieldQueryTests.java diff --git a/x-pack/plugin/kql/src/main/antlr/KqlBase.g4 b/x-pack/plugin/kql/src/main/antlr/KqlBase.g4 index 429ebce9b123b..aa5f399c7049a 100644 --- a/x-pack/plugin/kql/src/main/antlr/KqlBase.g4 +++ b/x-pack/plugin/kql/src/main/antlr/KqlBase.g4 @@ -26,7 +26,7 @@ topLevelQuery ; query - : <assoc=right> query operator=(AND | OR) query #booleanQuery + : <assoc=right> query operator=(AND | OR) query? #booleanQuery | NOT subQuery=simpleQuery #notQuery | simpleQuery #defaultQuery ; diff --git a/x-pack/plugin/kql/src/main/java/org/elasticsearch/xpack/kql/parser/KqlAstBuilder.java b/x-pack/plugin/kql/src/main/java/org/elasticsearch/xpack/kql/parser/KqlAstBuilder.java index 8325c1e9fdd0d..b8413b25655e7 100644 --- a/x-pack/plugin/kql/src/main/java/org/elasticsearch/xpack/kql/parser/KqlAstBuilder.java +++ b/x-pack/plugin/kql/src/main/java/org/elasticsearch/xpack/kql/parser/KqlAstBuilder.java @@ -65,7 +65,7 @@ public QueryBuilder visitAndBooleanQuery(KqlBaseParser.BooleanQueryContext ctx) } } - return builder; + return rewriteConjonctionQuery(builder); } public QueryBuilder visitOrBooleanQuery(KqlBaseParser.BooleanQueryContext ctx) { @@ -79,7 +79,7 @@ public QueryBuilder visitOrBooleanQuery(KqlBaseParser.BooleanQueryContext ctx) { } } - return builder; + return rewriteDisjunctionQuery(builder); } @Override @@ -207,6 +207,16 @@ private QueryBuilder rewriteDisjunctionQuery(BoolQueryBuilder boolQueryBuilder) return boolQueryBuilder.should().size() == 1 ? boolQueryBuilder.should().getFirst() : boolQueryBuilder; } + private QueryBuilder rewriteConjonctionQuery(BoolQueryBuilder boolQueryBuilder) { + assert boolQueryBuilder.should().isEmpty() && boolQueryBuilder.filter().isEmpty() && boolQueryBuilder.mustNot().isEmpty(); + + if (boolQueryBuilder.must().isEmpty()) { + return new MatchNoneQueryBuilder(); + } + + return boolQueryBuilder.must().size() == 1 ? boolQueryBuilder.must().getFirst() : boolQueryBuilder; + } + private BiFunction<RangeQueryBuilder, String, RangeQueryBuilder> rangeOperation(Token operator) { return switch (operator.getType()) { case KqlBaseParser.OP_LESS -> RangeQueryBuilder::lt; diff --git a/x-pack/plugin/kql/src/main/java/org/elasticsearch/xpack/kql/parser/KqlBase.interp b/x-pack/plugin/kql/src/main/java/org/elasticsearch/xpack/kql/parser/KqlBase.interp index eac047d5ffaf1..56fadeca97f21 100644 --- a/x-pack/plugin/kql/src/main/java/org/elasticsearch/xpack/kql/parser/KqlBase.interp +++ b/x-pack/plugin/kql/src/main/java/org/elasticsearch/xpack/kql/parser/KqlBase.interp @@ -53,4 +53,4 @@ fieldName atn: -[4, 1, 16, 123, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 1, 0, 3, 0, 28, 8, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 36, 8, 1, 1, 1, 1, 1, 1, 1, 5, 1, 41, 8, 1, 10, 1, 12, 1, 44, 9, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 53, 8, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 3, 4, 63, 8, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 4, 7, 76, 8, 7, 11, 7, 12, 7, 77, 1, 7, 3, 7, 81, 8, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 3, 9, 97, 8, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 3, 10, 104, 8, 10, 1, 11, 4, 11, 107, 8, 11, 11, 11, 12, 11, 108, 1, 11, 3, 11, 112, 8, 11, 1, 12, 4, 12, 115, 8, 12, 11, 12, 12, 12, 116, 1, 12, 1, 12, 3, 12, 121, 8, 12, 1, 12, 0, 1, 2, 13, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 0, 3, 1, 0, 2, 3, 1, 0, 6, 9, 2, 0, 14, 14, 16, 16, 128, 0, 27, 1, 0, 0, 0, 2, 35, 1, 0, 0, 0, 4, 52, 1, 0, 0, 0, 6, 54, 1, 0, 0, 0, 8, 62, 1, 0, 0, 0, 10, 66, 1, 0, 0, 0, 12, 70, 1, 0, 0, 0, 14, 80, 1, 0, 0, 0, 16, 82, 1, 0, 0, 0, 18, 96, 1, 0, 0, 0, 20, 103, 1, 0, 0, 0, 22, 111, 1, 0, 0, 0, 24, 120, 1, 0, 0, 0, 26, 28, 3, 2, 1, 0, 27, 26, 1, 0, 0, 0, 27, 28, 1, 0, 0, 0, 28, 29, 1, 0, 0, 0, 29, 30, 5, 0, 0, 1, 30, 1, 1, 0, 0, 0, 31, 32, 6, 1, -1, 0, 32, 33, 5, 4, 0, 0, 33, 36, 3, 4, 2, 0, 34, 36, 3, 4, 2, 0, 35, 31, 1, 0, 0, 0, 35, 34, 1, 0, 0, 0, 36, 42, 1, 0, 0, 0, 37, 38, 10, 3, 0, 0, 38, 39, 7, 0, 0, 0, 39, 41, 3, 2, 1, 3, 40, 37, 1, 0, 0, 0, 41, 44, 1, 0, 0, 0, 42, 40, 1, 0, 0, 0, 42, 43, 1, 0, 0, 0, 43, 3, 1, 0, 0, 0, 44, 42, 1, 0, 0, 0, 45, 53, 3, 6, 3, 0, 46, 53, 3, 10, 5, 0, 47, 53, 3, 8, 4, 0, 48, 53, 3, 16, 8, 0, 49, 53, 3, 12, 6, 0, 50, 53, 3, 18, 9, 0, 51, 53, 3, 20, 10, 0, 52, 45, 1, 0, 0, 0, 52, 46, 1, 0, 0, 0, 52, 47, 1, 0, 0, 0, 52, 48, 1, 0, 0, 0, 52, 49, 1, 0, 0, 0, 52, 50, 1, 0, 0, 0, 52, 51, 1, 0, 0, 0, 53, 5, 1, 0, 0, 0, 54, 55, 3, 24, 12, 0, 55, 56, 5, 5, 0, 0, 56, 57, 5, 12, 0, 0, 57, 58, 3, 2, 1, 0, 58, 59, 5, 13, 0, 0, 59, 7, 1, 0, 0, 0, 60, 61, 5, 16, 0, 0, 61, 63, 5, 5, 0, 0, 62, 60, 1, 0, 0, 0, 62, 63, 1, 0, 0, 0, 63, 64, 1, 0, 0, 0, 64, 65, 5, 16, 0, 0, 65, 9, 1, 0, 0, 0, 66, 67, 5, 10, 0, 0, 67, 68, 3, 2, 1, 0, 68, 69, 5, 11, 0, 0, 69, 11, 1, 0, 0, 0, 70, 71, 3, 24, 12, 0, 71, 72, 7, 1, 0, 0, 72, 73, 3, 14, 7, 0, 73, 13, 1, 0, 0, 0, 74, 76, 7, 2, 0, 0, 75, 74, 1, 0, 0, 0, 76, 77, 1, 0, 0, 0, 77, 75, 1, 0, 0, 0, 77, 78, 1, 0, 0, 0, 78, 81, 1, 0, 0, 0, 79, 81, 5, 15, 0, 0, 80, 75, 1, 0, 0, 0, 80, 79, 1, 0, 0, 0, 81, 15, 1, 0, 0, 0, 82, 83, 3, 24, 12, 0, 83, 84, 5, 5, 0, 0, 84, 85, 5, 16, 0, 0, 85, 17, 1, 0, 0, 0, 86, 87, 3, 24, 12, 0, 87, 88, 5, 5, 0, 0, 88, 89, 3, 22, 11, 0, 89, 97, 1, 0, 0, 0, 90, 91, 3, 24, 12, 0, 91, 92, 5, 5, 0, 0, 92, 93, 5, 10, 0, 0, 93, 94, 3, 22, 11, 0, 94, 95, 5, 11, 0, 0, 95, 97, 1, 0, 0, 0, 96, 86, 1, 0, 0, 0, 96, 90, 1, 0, 0, 0, 97, 19, 1, 0, 0, 0, 98, 104, 3, 22, 11, 0, 99, 100, 5, 10, 0, 0, 100, 101, 3, 22, 11, 0, 101, 102, 5, 11, 0, 0, 102, 104, 1, 0, 0, 0, 103, 98, 1, 0, 0, 0, 103, 99, 1, 0, 0, 0, 104, 21, 1, 0, 0, 0, 105, 107, 7, 2, 0, 0, 106, 105, 1, 0, 0, 0, 107, 108, 1, 0, 0, 0, 108, 106, 1, 0, 0, 0, 108, 109, 1, 0, 0, 0, 109, 112, 1, 0, 0, 0, 110, 112, 5, 15, 0, 0, 111, 106, 1, 0, 0, 0, 111, 110, 1, 0, 0, 0, 112, 23, 1, 0, 0, 0, 113, 115, 5, 14, 0, 0, 114, 113, 1, 0, 0, 0, 115, 116, 1, 0, 0, 0, 116, 114, 1, 0, 0, 0, 116, 117, 1, 0, 0, 0, 117, 121, 1, 0, 0, 0, 118, 121, 5, 15, 0, 0, 119, 121, 5, 16, 0, 0, 120, 114, 1, 0, 0, 0, 120, 118, 1, 0, 0, 0, 120, 119, 1, 0, 0, 0, 121, 25, 1, 0, 0, 0, 13, 27, 35, 42, 52, 62, 77, 80, 96, 103, 108, 111, 116, 120] \ No newline at end of file +[4, 1, 16, 125, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 1, 0, 3, 0, 28, 8, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 36, 8, 1, 1, 1, 1, 1, 1, 1, 3, 1, 41, 8, 1, 5, 1, 43, 8, 1, 10, 1, 12, 1, 46, 9, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 55, 8, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 3, 4, 65, 8, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 4, 7, 78, 8, 7, 11, 7, 12, 7, 79, 1, 7, 3, 7, 83, 8, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 3, 9, 99, 8, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 3, 10, 106, 8, 10, 1, 11, 4, 11, 109, 8, 11, 11, 11, 12, 11, 110, 1, 11, 3, 11, 114, 8, 11, 1, 12, 4, 12, 117, 8, 12, 11, 12, 12, 12, 118, 1, 12, 1, 12, 3, 12, 123, 8, 12, 1, 12, 0, 1, 2, 13, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 0, 3, 1, 0, 2, 3, 1, 0, 6, 9, 2, 0, 14, 14, 16, 16, 131, 0, 27, 1, 0, 0, 0, 2, 35, 1, 0, 0, 0, 4, 54, 1, 0, 0, 0, 6, 56, 1, 0, 0, 0, 8, 64, 1, 0, 0, 0, 10, 68, 1, 0, 0, 0, 12, 72, 1, 0, 0, 0, 14, 82, 1, 0, 0, 0, 16, 84, 1, 0, 0, 0, 18, 98, 1, 0, 0, 0, 20, 105, 1, 0, 0, 0, 22, 113, 1, 0, 0, 0, 24, 122, 1, 0, 0, 0, 26, 28, 3, 2, 1, 0, 27, 26, 1, 0, 0, 0, 27, 28, 1, 0, 0, 0, 28, 29, 1, 0, 0, 0, 29, 30, 5, 0, 0, 1, 30, 1, 1, 0, 0, 0, 31, 32, 6, 1, -1, 0, 32, 33, 5, 4, 0, 0, 33, 36, 3, 4, 2, 0, 34, 36, 3, 4, 2, 0, 35, 31, 1, 0, 0, 0, 35, 34, 1, 0, 0, 0, 36, 44, 1, 0, 0, 0, 37, 38, 10, 3, 0, 0, 38, 40, 7, 0, 0, 0, 39, 41, 3, 2, 1, 0, 40, 39, 1, 0, 0, 0, 40, 41, 1, 0, 0, 0, 41, 43, 1, 0, 0, 0, 42, 37, 1, 0, 0, 0, 43, 46, 1, 0, 0, 0, 44, 42, 1, 0, 0, 0, 44, 45, 1, 0, 0, 0, 45, 3, 1, 0, 0, 0, 46, 44, 1, 0, 0, 0, 47, 55, 3, 6, 3, 0, 48, 55, 3, 10, 5, 0, 49, 55, 3, 8, 4, 0, 50, 55, 3, 16, 8, 0, 51, 55, 3, 12, 6, 0, 52, 55, 3, 18, 9, 0, 53, 55, 3, 20, 10, 0, 54, 47, 1, 0, 0, 0, 54, 48, 1, 0, 0, 0, 54, 49, 1, 0, 0, 0, 54, 50, 1, 0, 0, 0, 54, 51, 1, 0, 0, 0, 54, 52, 1, 0, 0, 0, 54, 53, 1, 0, 0, 0, 55, 5, 1, 0, 0, 0, 56, 57, 3, 24, 12, 0, 57, 58, 5, 5, 0, 0, 58, 59, 5, 12, 0, 0, 59, 60, 3, 2, 1, 0, 60, 61, 5, 13, 0, 0, 61, 7, 1, 0, 0, 0, 62, 63, 5, 16, 0, 0, 63, 65, 5, 5, 0, 0, 64, 62, 1, 0, 0, 0, 64, 65, 1, 0, 0, 0, 65, 66, 1, 0, 0, 0, 66, 67, 5, 16, 0, 0, 67, 9, 1, 0, 0, 0, 68, 69, 5, 10, 0, 0, 69, 70, 3, 2, 1, 0, 70, 71, 5, 11, 0, 0, 71, 11, 1, 0, 0, 0, 72, 73, 3, 24, 12, 0, 73, 74, 7, 1, 0, 0, 74, 75, 3, 14, 7, 0, 75, 13, 1, 0, 0, 0, 76, 78, 7, 2, 0, 0, 77, 76, 1, 0, 0, 0, 78, 79, 1, 0, 0, 0, 79, 77, 1, 0, 0, 0, 79, 80, 1, 0, 0, 0, 80, 83, 1, 0, 0, 0, 81, 83, 5, 15, 0, 0, 82, 77, 1, 0, 0, 0, 82, 81, 1, 0, 0, 0, 83, 15, 1, 0, 0, 0, 84, 85, 3, 24, 12, 0, 85, 86, 5, 5, 0, 0, 86, 87, 5, 16, 0, 0, 87, 17, 1, 0, 0, 0, 88, 89, 3, 24, 12, 0, 89, 90, 5, 5, 0, 0, 90, 91, 3, 22, 11, 0, 91, 99, 1, 0, 0, 0, 92, 93, 3, 24, 12, 0, 93, 94, 5, 5, 0, 0, 94, 95, 5, 10, 0, 0, 95, 96, 3, 22, 11, 0, 96, 97, 5, 11, 0, 0, 97, 99, 1, 0, 0, 0, 98, 88, 1, 0, 0, 0, 98, 92, 1, 0, 0, 0, 99, 19, 1, 0, 0, 0, 100, 106, 3, 22, 11, 0, 101, 102, 5, 10, 0, 0, 102, 103, 3, 22, 11, 0, 103, 104, 5, 11, 0, 0, 104, 106, 1, 0, 0, 0, 105, 100, 1, 0, 0, 0, 105, 101, 1, 0, 0, 0, 106, 21, 1, 0, 0, 0, 107, 109, 7, 2, 0, 0, 108, 107, 1, 0, 0, 0, 109, 110, 1, 0, 0, 0, 110, 108, 1, 0, 0, 0, 110, 111, 1, 0, 0, 0, 111, 114, 1, 0, 0, 0, 112, 114, 5, 15, 0, 0, 113, 108, 1, 0, 0, 0, 113, 112, 1, 0, 0, 0, 114, 23, 1, 0, 0, 0, 115, 117, 5, 14, 0, 0, 116, 115, 1, 0, 0, 0, 117, 118, 1, 0, 0, 0, 118, 116, 1, 0, 0, 0, 118, 119, 1, 0, 0, 0, 119, 123, 1, 0, 0, 0, 120, 123, 5, 15, 0, 0, 121, 123, 5, 16, 0, 0, 122, 116, 1, 0, 0, 0, 122, 120, 1, 0, 0, 0, 122, 121, 1, 0, 0, 0, 123, 25, 1, 0, 0, 0, 14, 27, 35, 40, 44, 54, 64, 79, 82, 98, 105, 110, 113, 118, 122] \ No newline at end of file diff --git a/x-pack/plugin/kql/src/main/java/org/elasticsearch/xpack/kql/parser/KqlBaseParser.java b/x-pack/plugin/kql/src/main/java/org/elasticsearch/xpack/kql/parser/KqlBaseParser.java index 8c6e6eb040c14..0e95f438702df 100644 --- a/x-pack/plugin/kql/src/main/java/org/elasticsearch/xpack/kql/parser/KqlBaseParser.java +++ b/x-pack/plugin/kql/src/main/java/org/elasticsearch/xpack/kql/parser/KqlBaseParser.java @@ -292,9 +292,9 @@ private QueryContext query(int _p) throws RecognitionException { throw new NoViableAltException(this); } _ctx.stop = _input.LT(-1); - setState(42); + setState(44); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,2,_ctx); + _alt = getInterpreter().adaptivePredict(_input,3,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { if ( _parseListeners!=null ) triggerExitRuleEvent(); @@ -316,14 +316,22 @@ private QueryContext query(int _p) throws RecognitionException { _errHandler.reportMatch(this); consume(); } - setState(39); - query(3); + setState(40); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,2,_ctx) ) { + case 1: + { + setState(39); + query(0); + } + break; + } } } } - setState(44); + setState(46); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,2,_ctx); + _alt = getInterpreter().adaptivePredict(_input,3,_ctx); } } } @@ -384,55 +392,55 @@ public final SimpleQueryContext simpleQuery() throws RecognitionException { SimpleQueryContext _localctx = new SimpleQueryContext(_ctx, getState()); enterRule(_localctx, 4, RULE_simpleQuery); try { - setState(52); + setState(54); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,3,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,4,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(45); + setState(47); nestedQuery(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(46); + setState(48); parenthesizedQuery(); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(47); + setState(49); matchAllQuery(); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(48); + setState(50); existsQuery(); } break; case 5: enterOuterAlt(_localctx, 5); { - setState(49); + setState(51); rangeQuery(); } break; case 6: enterOuterAlt(_localctx, 6); { - setState(50); + setState(52); fieldQuery(); } break; case 7: enterOuterAlt(_localctx, 7); { - setState(51); + setState(53); fieldLessQuery(); } break; @@ -485,15 +493,15 @@ public final NestedQueryContext nestedQuery() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(54); + setState(56); fieldName(); - setState(55); + setState(57); match(COLON); - setState(56); + setState(58); match(LEFT_CURLY_BRACKET); - setState(57); + setState(59); query(0); - setState(58); + setState(60); match(RIGHT_CURLY_BRACKET); } } @@ -540,19 +548,19 @@ public final MatchAllQueryContext matchAllQuery() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(62); + setState(64); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,4,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,5,_ctx) ) { case 1: { - setState(60); + setState(62); match(WILDCARD); - setState(61); + setState(63); match(COLON); } break; } - setState(64); + setState(66); match(WILDCARD); } } @@ -599,11 +607,11 @@ public final ParenthesizedQueryContext parenthesizedQuery() throws RecognitionEx try { enterOuterAlt(_localctx, 1); { - setState(66); + setState(68); match(LEFT_PARENTHESIS); - setState(67); + setState(69); query(0); - setState(68); + setState(70); match(RIGHT_PARENTHESIS); } } @@ -657,9 +665,9 @@ public final RangeQueryContext rangeQuery() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(70); + setState(72); fieldName(); - setState(71); + setState(73); ((RangeQueryContext)_localctx).operator = _input.LT(1); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 960L) != 0)) ) { @@ -670,7 +678,7 @@ public final RangeQueryContext rangeQuery() throws RecognitionException { _errHandler.reportMatch(this); consume(); } - setState(72); + setState(74); rangeQueryValue(); } } @@ -721,14 +729,14 @@ public final RangeQueryValueContext rangeQueryValue() throws RecognitionExceptio int _la; try { int _alt; - setState(80); + setState(82); _errHandler.sync(this); switch (_input.LA(1)) { case UNQUOTED_LITERAL: case WILDCARD: enterOuterAlt(_localctx, 1); { - setState(75); + setState(77); _errHandler.sync(this); _alt = 1; do { @@ -736,7 +744,7 @@ public final RangeQueryValueContext rangeQueryValue() throws RecognitionExceptio case 1: { { - setState(74); + setState(76); _la = _input.LA(1); if ( !(_la==UNQUOTED_LITERAL || _la==WILDCARD) ) { _errHandler.recoverInline(this); @@ -752,16 +760,16 @@ public final RangeQueryValueContext rangeQueryValue() throws RecognitionExceptio default: throw new NoViableAltException(this); } - setState(77); + setState(79); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,5,_ctx); + _alt = getInterpreter().adaptivePredict(_input,6,_ctx); } while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); } break; case QUOTED_STRING: enterOuterAlt(_localctx, 2); { - setState(79); + setState(81); match(QUOTED_STRING); } break; @@ -812,11 +820,11 @@ public final ExistsQueryContext existsQuery() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(82); + setState(84); fieldName(); - setState(83); + setState(85); match(COLON); - setState(84); + setState(86); match(WILDCARD); } } @@ -865,32 +873,32 @@ public final FieldQueryContext fieldQuery() throws RecognitionException { FieldQueryContext _localctx = new FieldQueryContext(_ctx, getState()); enterRule(_localctx, 18, RULE_fieldQuery); try { - setState(96); + setState(98); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,7,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,8,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(86); + setState(88); fieldName(); - setState(87); + setState(89); match(COLON); - setState(88); + setState(90); fieldQueryValue(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(90); + setState(92); fieldName(); - setState(91); + setState(93); match(COLON); - setState(92); + setState(94); match(LEFT_PARENTHESIS); - setState(93); + setState(95); fieldQueryValue(); - setState(94); + setState(96); match(RIGHT_PARENTHESIS); } break; @@ -937,7 +945,7 @@ public final FieldLessQueryContext fieldLessQuery() throws RecognitionException FieldLessQueryContext _localctx = new FieldLessQueryContext(_ctx, getState()); enterRule(_localctx, 20, RULE_fieldLessQuery); try { - setState(103); + setState(105); _errHandler.sync(this); switch (_input.LA(1)) { case UNQUOTED_LITERAL: @@ -945,18 +953,18 @@ public final FieldLessQueryContext fieldLessQuery() throws RecognitionException case WILDCARD: enterOuterAlt(_localctx, 1); { - setState(98); + setState(100); fieldQueryValue(); } break; case LEFT_PARENTHESIS: enterOuterAlt(_localctx, 2); { - setState(99); + setState(101); match(LEFT_PARENTHESIS); - setState(100); + setState(102); fieldQueryValue(); - setState(101); + setState(103); match(RIGHT_PARENTHESIS); } break; @@ -1011,14 +1019,14 @@ public final FieldQueryValueContext fieldQueryValue() throws RecognitionExceptio int _la; try { int _alt; - setState(111); + setState(113); _errHandler.sync(this); switch (_input.LA(1)) { case UNQUOTED_LITERAL: case WILDCARD: enterOuterAlt(_localctx, 1); { - setState(106); + setState(108); _errHandler.sync(this); _alt = 1; do { @@ -1026,7 +1034,7 @@ public final FieldQueryValueContext fieldQueryValue() throws RecognitionExceptio case 1: { { - setState(105); + setState(107); _la = _input.LA(1); if ( !(_la==UNQUOTED_LITERAL || _la==WILDCARD) ) { _errHandler.recoverInline(this); @@ -1042,16 +1050,16 @@ public final FieldQueryValueContext fieldQueryValue() throws RecognitionExceptio default: throw new NoViableAltException(this); } - setState(108); + setState(110); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,9,_ctx); + _alt = getInterpreter().adaptivePredict(_input,10,_ctx); } while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); } break; case QUOTED_STRING: enterOuterAlt(_localctx, 2); { - setState(110); + setState(112); match(QUOTED_STRING); } break; @@ -1103,23 +1111,23 @@ public final FieldNameContext fieldName() throws RecognitionException { enterRule(_localctx, 24, RULE_fieldName); int _la; try { - setState(120); + setState(122); _errHandler.sync(this); switch (_input.LA(1)) { case UNQUOTED_LITERAL: enterOuterAlt(_localctx, 1); { - setState(114); + setState(116); _errHandler.sync(this); _la = _input.LA(1); do { { { - setState(113); + setState(115); ((FieldNameContext)_localctx).value = match(UNQUOTED_LITERAL); } } - setState(116); + setState(118); _errHandler.sync(this); _la = _input.LA(1); } while ( _la==UNQUOTED_LITERAL ); @@ -1128,14 +1136,14 @@ public final FieldNameContext fieldName() throws RecognitionException { case QUOTED_STRING: enterOuterAlt(_localctx, 2); { - setState(118); + setState(120); ((FieldNameContext)_localctx).value = match(QUOTED_STRING); } break; case WILDCARD: enterOuterAlt(_localctx, 3); { - setState(119); + setState(121); ((FieldNameContext)_localctx).value = match(WILDCARD); } break; @@ -1170,76 +1178,77 @@ private boolean query_sempred(QueryContext _localctx, int predIndex) { } public static final String _serializedATN = - "\u0004\u0001\u0010{\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002"+ + "\u0004\u0001\u0010}\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002"+ "\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004\u0007\u0004\u0002"+ "\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007\u0007\u0007\u0002"+ "\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002\u000b\u0007\u000b\u0002"+ "\f\u0007\f\u0001\u0000\u0003\u0000\u001c\b\u0000\u0001\u0000\u0001\u0000"+ "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0003\u0001$\b\u0001"+ - "\u0001\u0001\u0001\u0001\u0001\u0001\u0005\u0001)\b\u0001\n\u0001\f\u0001"+ - ",\t\u0001\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002"+ - "\u0001\u0002\u0001\u0002\u0003\u00025\b\u0002\u0001\u0003\u0001\u0003"+ - "\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0004\u0001\u0004"+ - "\u0003\u0004?\b\u0004\u0001\u0004\u0001\u0004\u0001\u0005\u0001\u0005"+ - "\u0001\u0005\u0001\u0005\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006"+ - "\u0001\u0007\u0004\u0007L\b\u0007\u000b\u0007\f\u0007M\u0001\u0007\u0003"+ - "\u0007Q\b\u0007\u0001\b\u0001\b\u0001\b\u0001\b\u0001\t\u0001\t\u0001"+ - "\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0003\ta\b"+ - "\t\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0003\nh\b\n\u0001\u000b\u0004"+ - "\u000bk\b\u000b\u000b\u000b\f\u000bl\u0001\u000b\u0003\u000bp\b\u000b"+ - "\u0001\f\u0004\fs\b\f\u000b\f\f\ft\u0001\f\u0001\f\u0003\fy\b\f\u0001"+ - "\f\u0000\u0001\u0002\r\u0000\u0002\u0004\u0006\b\n\f\u000e\u0010\u0012"+ - "\u0014\u0016\u0018\u0000\u0003\u0001\u0000\u0002\u0003\u0001\u0000\u0006"+ - "\t\u0002\u0000\u000e\u000e\u0010\u0010\u0080\u0000\u001b\u0001\u0000\u0000"+ - "\u0000\u0002#\u0001\u0000\u0000\u0000\u00044\u0001\u0000\u0000\u0000\u0006"+ - "6\u0001\u0000\u0000\u0000\b>\u0001\u0000\u0000\u0000\nB\u0001\u0000\u0000"+ - "\u0000\fF\u0001\u0000\u0000\u0000\u000eP\u0001\u0000\u0000\u0000\u0010"+ - "R\u0001\u0000\u0000\u0000\u0012`\u0001\u0000\u0000\u0000\u0014g\u0001"+ - "\u0000\u0000\u0000\u0016o\u0001\u0000\u0000\u0000\u0018x\u0001\u0000\u0000"+ - "\u0000\u001a\u001c\u0003\u0002\u0001\u0000\u001b\u001a\u0001\u0000\u0000"+ - "\u0000\u001b\u001c\u0001\u0000\u0000\u0000\u001c\u001d\u0001\u0000\u0000"+ - "\u0000\u001d\u001e\u0005\u0000\u0000\u0001\u001e\u0001\u0001\u0000\u0000"+ - "\u0000\u001f \u0006\u0001\uffff\uffff\u0000 !\u0005\u0004\u0000\u0000"+ - "!$\u0003\u0004\u0002\u0000\"$\u0003\u0004\u0002\u0000#\u001f\u0001\u0000"+ - "\u0000\u0000#\"\u0001\u0000\u0000\u0000$*\u0001\u0000\u0000\u0000%&\n"+ - "\u0003\u0000\u0000&\'\u0007\u0000\u0000\u0000\')\u0003\u0002\u0001\u0003"+ - "(%\u0001\u0000\u0000\u0000),\u0001\u0000\u0000\u0000*(\u0001\u0000\u0000"+ - "\u0000*+\u0001\u0000\u0000\u0000+\u0003\u0001\u0000\u0000\u0000,*\u0001"+ - "\u0000\u0000\u0000-5\u0003\u0006\u0003\u0000.5\u0003\n\u0005\u0000/5\u0003"+ - "\b\u0004\u000005\u0003\u0010\b\u000015\u0003\f\u0006\u000025\u0003\u0012"+ - "\t\u000035\u0003\u0014\n\u00004-\u0001\u0000\u0000\u00004.\u0001\u0000"+ - "\u0000\u00004/\u0001\u0000\u0000\u000040\u0001\u0000\u0000\u000041\u0001"+ - "\u0000\u0000\u000042\u0001\u0000\u0000\u000043\u0001\u0000\u0000\u0000"+ - "5\u0005\u0001\u0000\u0000\u000067\u0003\u0018\f\u000078\u0005\u0005\u0000"+ - "\u000089\u0005\f\u0000\u00009:\u0003\u0002\u0001\u0000:;\u0005\r\u0000"+ - "\u0000;\u0007\u0001\u0000\u0000\u0000<=\u0005\u0010\u0000\u0000=?\u0005"+ - "\u0005\u0000\u0000><\u0001\u0000\u0000\u0000>?\u0001\u0000\u0000\u0000"+ - "?@\u0001\u0000\u0000\u0000@A\u0005\u0010\u0000\u0000A\t\u0001\u0000\u0000"+ - "\u0000BC\u0005\n\u0000\u0000CD\u0003\u0002\u0001\u0000DE\u0005\u000b\u0000"+ - "\u0000E\u000b\u0001\u0000\u0000\u0000FG\u0003\u0018\f\u0000GH\u0007\u0001"+ - "\u0000\u0000HI\u0003\u000e\u0007\u0000I\r\u0001\u0000\u0000\u0000JL\u0007"+ - "\u0002\u0000\u0000KJ\u0001\u0000\u0000\u0000LM\u0001\u0000\u0000\u0000"+ - "MK\u0001\u0000\u0000\u0000MN\u0001\u0000\u0000\u0000NQ\u0001\u0000\u0000"+ - "\u0000OQ\u0005\u000f\u0000\u0000PK\u0001\u0000\u0000\u0000PO\u0001\u0000"+ - "\u0000\u0000Q\u000f\u0001\u0000\u0000\u0000RS\u0003\u0018\f\u0000ST\u0005"+ - "\u0005\u0000\u0000TU\u0005\u0010\u0000\u0000U\u0011\u0001\u0000\u0000"+ - "\u0000VW\u0003\u0018\f\u0000WX\u0005\u0005\u0000\u0000XY\u0003\u0016\u000b"+ - "\u0000Ya\u0001\u0000\u0000\u0000Z[\u0003\u0018\f\u0000[\\\u0005\u0005"+ - "\u0000\u0000\\]\u0005\n\u0000\u0000]^\u0003\u0016\u000b\u0000^_\u0005"+ - "\u000b\u0000\u0000_a\u0001\u0000\u0000\u0000`V\u0001\u0000\u0000\u0000"+ - "`Z\u0001\u0000\u0000\u0000a\u0013\u0001\u0000\u0000\u0000bh\u0003\u0016"+ - "\u000b\u0000cd\u0005\n\u0000\u0000de\u0003\u0016\u000b\u0000ef\u0005\u000b"+ - "\u0000\u0000fh\u0001\u0000\u0000\u0000gb\u0001\u0000\u0000\u0000gc\u0001"+ - "\u0000\u0000\u0000h\u0015\u0001\u0000\u0000\u0000ik\u0007\u0002\u0000"+ - "\u0000ji\u0001\u0000\u0000\u0000kl\u0001\u0000\u0000\u0000lj\u0001\u0000"+ - "\u0000\u0000lm\u0001\u0000\u0000\u0000mp\u0001\u0000\u0000\u0000np\u0005"+ - "\u000f\u0000\u0000oj\u0001\u0000\u0000\u0000on\u0001\u0000\u0000\u0000"+ - "p\u0017\u0001\u0000\u0000\u0000qs\u0005\u000e\u0000\u0000rq\u0001\u0000"+ - "\u0000\u0000st\u0001\u0000\u0000\u0000tr\u0001\u0000\u0000\u0000tu\u0001"+ - "\u0000\u0000\u0000uy\u0001\u0000\u0000\u0000vy\u0005\u000f\u0000\u0000"+ - "wy\u0005\u0010\u0000\u0000xr\u0001\u0000\u0000\u0000xv\u0001\u0000\u0000"+ - "\u0000xw\u0001\u0000\u0000\u0000y\u0019\u0001\u0000\u0000\u0000\r\u001b"+ - "#*4>MP`glotx"; + "\u0001\u0001\u0001\u0001\u0001\u0001\u0003\u0001)\b\u0001\u0005\u0001"+ + "+\b\u0001\n\u0001\f\u0001.\t\u0001\u0001\u0002\u0001\u0002\u0001\u0002"+ + "\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0003\u00027\b\u0002"+ + "\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+ + "\u0001\u0004\u0001\u0004\u0003\u0004A\b\u0004\u0001\u0004\u0001\u0004"+ + "\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0006\u0001\u0006"+ + "\u0001\u0006\u0001\u0006\u0001\u0007\u0004\u0007N\b\u0007\u000b\u0007"+ + "\f\u0007O\u0001\u0007\u0003\u0007S\b\u0007\u0001\b\u0001\b\u0001\b\u0001"+ + "\b\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001"+ + "\t\u0001\t\u0003\tc\b\t\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0003"+ + "\nj\b\n\u0001\u000b\u0004\u000bm\b\u000b\u000b\u000b\f\u000bn\u0001\u000b"+ + "\u0003\u000br\b\u000b\u0001\f\u0004\fu\b\f\u000b\f\f\fv\u0001\f\u0001"+ + "\f\u0003\f{\b\f\u0001\f\u0000\u0001\u0002\r\u0000\u0002\u0004\u0006\b"+ + "\n\f\u000e\u0010\u0012\u0014\u0016\u0018\u0000\u0003\u0001\u0000\u0002"+ + "\u0003\u0001\u0000\u0006\t\u0002\u0000\u000e\u000e\u0010\u0010\u0083\u0000"+ + "\u001b\u0001\u0000\u0000\u0000\u0002#\u0001\u0000\u0000\u0000\u00046\u0001"+ + "\u0000\u0000\u0000\u00068\u0001\u0000\u0000\u0000\b@\u0001\u0000\u0000"+ + "\u0000\nD\u0001\u0000\u0000\u0000\fH\u0001\u0000\u0000\u0000\u000eR\u0001"+ + "\u0000\u0000\u0000\u0010T\u0001\u0000\u0000\u0000\u0012b\u0001\u0000\u0000"+ + "\u0000\u0014i\u0001\u0000\u0000\u0000\u0016q\u0001\u0000\u0000\u0000\u0018"+ + "z\u0001\u0000\u0000\u0000\u001a\u001c\u0003\u0002\u0001\u0000\u001b\u001a"+ + "\u0001\u0000\u0000\u0000\u001b\u001c\u0001\u0000\u0000\u0000\u001c\u001d"+ + "\u0001\u0000\u0000\u0000\u001d\u001e\u0005\u0000\u0000\u0001\u001e\u0001"+ + "\u0001\u0000\u0000\u0000\u001f \u0006\u0001\uffff\uffff\u0000 !\u0005"+ + "\u0004\u0000\u0000!$\u0003\u0004\u0002\u0000\"$\u0003\u0004\u0002\u0000"+ + "#\u001f\u0001\u0000\u0000\u0000#\"\u0001\u0000\u0000\u0000$,\u0001\u0000"+ + "\u0000\u0000%&\n\u0003\u0000\u0000&(\u0007\u0000\u0000\u0000\')\u0003"+ + "\u0002\u0001\u0000(\'\u0001\u0000\u0000\u0000()\u0001\u0000\u0000\u0000"+ + ")+\u0001\u0000\u0000\u0000*%\u0001\u0000\u0000\u0000+.\u0001\u0000\u0000"+ + "\u0000,*\u0001\u0000\u0000\u0000,-\u0001\u0000\u0000\u0000-\u0003\u0001"+ + "\u0000\u0000\u0000.,\u0001\u0000\u0000\u0000/7\u0003\u0006\u0003\u0000"+ + "07\u0003\n\u0005\u000017\u0003\b\u0004\u000027\u0003\u0010\b\u000037\u0003"+ + "\f\u0006\u000047\u0003\u0012\t\u000057\u0003\u0014\n\u00006/\u0001\u0000"+ + "\u0000\u000060\u0001\u0000\u0000\u000061\u0001\u0000\u0000\u000062\u0001"+ + "\u0000\u0000\u000063\u0001\u0000\u0000\u000064\u0001\u0000\u0000\u0000"+ + "65\u0001\u0000\u0000\u00007\u0005\u0001\u0000\u0000\u000089\u0003\u0018"+ + "\f\u00009:\u0005\u0005\u0000\u0000:;\u0005\f\u0000\u0000;<\u0003\u0002"+ + "\u0001\u0000<=\u0005\r\u0000\u0000=\u0007\u0001\u0000\u0000\u0000>?\u0005"+ + "\u0010\u0000\u0000?A\u0005\u0005\u0000\u0000@>\u0001\u0000\u0000\u0000"+ + "@A\u0001\u0000\u0000\u0000AB\u0001\u0000\u0000\u0000BC\u0005\u0010\u0000"+ + "\u0000C\t\u0001\u0000\u0000\u0000DE\u0005\n\u0000\u0000EF\u0003\u0002"+ + "\u0001\u0000FG\u0005\u000b\u0000\u0000G\u000b\u0001\u0000\u0000\u0000"+ + "HI\u0003\u0018\f\u0000IJ\u0007\u0001\u0000\u0000JK\u0003\u000e\u0007\u0000"+ + "K\r\u0001\u0000\u0000\u0000LN\u0007\u0002\u0000\u0000ML\u0001\u0000\u0000"+ + "\u0000NO\u0001\u0000\u0000\u0000OM\u0001\u0000\u0000\u0000OP\u0001\u0000"+ + "\u0000\u0000PS\u0001\u0000\u0000\u0000QS\u0005\u000f\u0000\u0000RM\u0001"+ + "\u0000\u0000\u0000RQ\u0001\u0000\u0000\u0000S\u000f\u0001\u0000\u0000"+ + "\u0000TU\u0003\u0018\f\u0000UV\u0005\u0005\u0000\u0000VW\u0005\u0010\u0000"+ + "\u0000W\u0011\u0001\u0000\u0000\u0000XY\u0003\u0018\f\u0000YZ\u0005\u0005"+ + "\u0000\u0000Z[\u0003\u0016\u000b\u0000[c\u0001\u0000\u0000\u0000\\]\u0003"+ + "\u0018\f\u0000]^\u0005\u0005\u0000\u0000^_\u0005\n\u0000\u0000_`\u0003"+ + "\u0016\u000b\u0000`a\u0005\u000b\u0000\u0000ac\u0001\u0000\u0000\u0000"+ + "bX\u0001\u0000\u0000\u0000b\\\u0001\u0000\u0000\u0000c\u0013\u0001\u0000"+ + "\u0000\u0000dj\u0003\u0016\u000b\u0000ef\u0005\n\u0000\u0000fg\u0003\u0016"+ + "\u000b\u0000gh\u0005\u000b\u0000\u0000hj\u0001\u0000\u0000\u0000id\u0001"+ + "\u0000\u0000\u0000ie\u0001\u0000\u0000\u0000j\u0015\u0001\u0000\u0000"+ + "\u0000km\u0007\u0002\u0000\u0000lk\u0001\u0000\u0000\u0000mn\u0001\u0000"+ + "\u0000\u0000nl\u0001\u0000\u0000\u0000no\u0001\u0000\u0000\u0000or\u0001"+ + "\u0000\u0000\u0000pr\u0005\u000f\u0000\u0000ql\u0001\u0000\u0000\u0000"+ + "qp\u0001\u0000\u0000\u0000r\u0017\u0001\u0000\u0000\u0000su\u0005\u000e"+ + "\u0000\u0000ts\u0001\u0000\u0000\u0000uv\u0001\u0000\u0000\u0000vt\u0001"+ + "\u0000\u0000\u0000vw\u0001\u0000\u0000\u0000w{\u0001\u0000\u0000\u0000"+ + "x{\u0005\u000f\u0000\u0000y{\u0005\u0010\u0000\u0000zt\u0001\u0000\u0000"+ + "\u0000zx\u0001\u0000\u0000\u0000zy\u0001\u0000\u0000\u0000{\u0019\u0001"+ + "\u0000\u0000\u0000\u000e\u001b#(,6@ORbinqvz"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/AbstractKqlParserTestCase.java b/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/AbstractKqlParserTestCase.java index 2395aec7e933f..f31feb9b604bb 100644 --- a/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/AbstractKqlParserTestCase.java +++ b/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/AbstractKqlParserTestCase.java @@ -9,8 +9,13 @@ import org.elasticsearch.core.Predicates; import org.elasticsearch.core.SuppressForbidden; +import org.elasticsearch.index.query.MatchQueryBuilder; +import org.elasticsearch.index.query.MultiMatchQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; +import org.elasticsearch.index.query.QueryStringQueryBuilder; +import org.elasticsearch.index.query.RangeQueryBuilder; import org.elasticsearch.index.query.SearchExecutionContext; +import org.elasticsearch.index.query.TermQueryBuilder; import org.elasticsearch.test.AbstractBuilderTestCase; import java.io.BufferedReader; @@ -24,10 +29,14 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; +import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; +import static org.hamcrest.Matchers.anEmptyMap; +import static org.hamcrest.Matchers.equalTo; + public abstract class AbstractKqlParserTestCase extends AbstractBuilderTestCase { protected static final String SUPPORTED_QUERY_FILE_PATH = "/supported-queries"; @@ -91,4 +100,39 @@ protected QueryBuilder parseKqlQuery(String kqlQuery) { return parser.parseKqlQuery(kqlQuery, searchExecutionContext); } + + protected static void assertMultiMatchQuery(QueryBuilder query, String expectedValue, MultiMatchQueryBuilder.Type expectedType) { + MultiMatchQueryBuilder multiMatchQuery = asInstanceOf(MultiMatchQueryBuilder.class, query); + assertThat(multiMatchQuery.fields(), anEmptyMap()); + assertThat(multiMatchQuery.lenient(), equalTo(true)); + assertThat(multiMatchQuery.type(), equalTo(expectedType)); + assertThat(multiMatchQuery.value(), equalTo(expectedValue)); + } + + protected static void assertQueryStringBuilder(QueryBuilder query, String expectedValue) { + QueryStringQueryBuilder queryStringQuery = asInstanceOf(QueryStringQueryBuilder.class, query); + assertThat(queryStringQuery.queryString(), equalTo(expectedValue)); + } + + protected static void assertTermQueryBuilder(QueryBuilder queryBuilder, String expectedFieldName, String expectedValue) { + TermQueryBuilder termQuery = asInstanceOf(TermQueryBuilder.class, queryBuilder); + assertThat(termQuery.fieldName(), equalTo(expectedFieldName)); + assertThat(termQuery.value(), equalTo(expectedValue)); + } + + protected static void assertMatchQueryBuilder(QueryBuilder queryBuilder, String expectedFieldName, String expectedValue) { + MatchQueryBuilder matchQuery = asInstanceOf(MatchQueryBuilder.class, queryBuilder); + assertThat(matchQuery.fieldName(), equalTo(expectedFieldName)); + assertThat(matchQuery.value(), equalTo(expectedValue)); + } + + protected static void assertRangeQueryBuilder( + QueryBuilder queryBuilder, + String expectedFieldName, + Consumer<RangeQueryBuilder> codeBlock + ) { + RangeQueryBuilder rangeQuery = asInstanceOf(RangeQueryBuilder.class, queryBuilder); + assertThat(rangeQuery.fieldName(), equalTo(expectedFieldName)); + codeBlock.accept(rangeQuery); + } } diff --git a/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/KqlParserBooleanQueryTests.java b/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/KqlParserBooleanQueryTests.java index 0e836495717d8..e25e5b7049961 100644 --- a/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/KqlParserBooleanQueryTests.java +++ b/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/KqlParserBooleanQueryTests.java @@ -23,7 +23,7 @@ public class KqlParserBooleanQueryTests extends AbstractKqlParserTestCase { - public void testNotQuery() throws IOException { + public void testParseNotQuery() throws IOException { for (String baseQuery : readQueries(SUPPORTED_QUERY_FILE_PATH)) { if (baseQuery.startsWith("NOT") || BOOLEAN_QUERY_FILTER.test(baseQuery)) { baseQuery = wrapWithRandomWhitespaces("(") + baseQuery + wrapWithRandomWhitespaces(")"); @@ -46,7 +46,7 @@ public void testNotQuery() throws IOException { } } - public void testOrQuery() throws IOException { + public void testParseOrQuery() throws IOException { List<String> supportedQueries = readQueries(SUPPORTED_QUERY_FILE_PATH, Predicate.not(BOOLEAN_QUERY_FILTER)); for (int runs = 0; runs < 100; runs++) { @@ -83,7 +83,7 @@ public void testOrQuery() throws IOException { } } - public void testAndQuery() throws IOException { + public void testParseAndQuery() throws IOException { List<String> supportedQueries = readQueries(SUPPORTED_QUERY_FILE_PATH, Predicate.not(BOOLEAN_QUERY_FILTER)); for (int runs = 0; runs < 100; runs++) { @@ -119,6 +119,16 @@ public void testAndQuery() throws IOException { } } + public void testIgnoreTrailingOperatorsDuringParsing() throws IOException { + List<String> supportedQueries = readQueries(SUPPORTED_QUERY_FILE_PATH, Predicate.not(BOOLEAN_QUERY_FILTER)); + + for (String query : supportedQueries) { + // KQL ignore the following trailing operators + assertThat(parseKqlQuery(query), equalTo(parseKqlQuery(Strings.format("%s AND", query)))); + assertThat(parseKqlQuery(query), equalTo(parseKqlQuery(Strings.format("%s OR", query)))); + } + } + public void testOperatorPrecedence() throws IOException { KqlParser parser = new KqlParser(); SearchExecutionContext searchExecutionContext = createSearchExecutionContext(); diff --git a/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/KqlParserExistsQueryTests.java b/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/KqlParserExistsQueryTests.java index 49c2b58e6370f..78550922593e4 100644 --- a/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/KqlParserExistsQueryTests.java +++ b/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/KqlParserExistsQueryTests.java @@ -19,12 +19,12 @@ public class KqlParserExistsQueryTests extends AbstractKqlParserTestCase { - public void testExistsQueryWithNonExistingField() { + public void testParseExistsQueryWithNoMatchingFields() { // Using an unquoted literal - assertThat(parseKqlQuery(kqlExistsQuery("foo")), isA(MatchNoneQueryBuilder.class)); + assertThat(parseKqlQuery(kqlExistsQuery("not_a_valid_field")), isA(MatchNoneQueryBuilder.class)); // Using an a quoted string - assertThat(parseKqlQuery(kqlExistsQuery("\"foo\"")), isA(MatchNoneQueryBuilder.class)); + assertThat(parseKqlQuery(kqlExistsQuery("\"not_a_valid_field\"")), isA(MatchNoneQueryBuilder.class)); // Not expanding wildcard with quoted string assertThat(parseKqlQuery(kqlExistsQuery("\"mapped_*\"")), isA(MatchNoneQueryBuilder.class)); @@ -33,7 +33,7 @@ public void testExistsQueryWithNonExistingField() { assertThat(parseKqlQuery(kqlExistsQuery(OBJECT_FIELD_NAME)), isA(MatchNoneQueryBuilder.class)); } - public void testExistsQueryWithASingleField() { + public void testParseExistsQueryWithASingleField() { for (String fieldName : mappedLeafFields()) { ExistsQueryBuilder parsedQuery = asInstanceOf(ExistsQueryBuilder.class, parseKqlQuery(kqlExistsQuery(fieldName))); assertThat(parsedQuery.fieldName(), equalTo(fieldName)); @@ -43,7 +43,7 @@ public void testExistsQueryWithASingleField() { } } - public void testExistsQueryUsingAWildcard() { + public void testParseExistsQueryUsingWildcardFieldName() { BoolQueryBuilder parsedQuery = asInstanceOf(BoolQueryBuilder.class, parseKqlQuery(kqlExistsQuery("mapped_*"))); assertThat(parsedQuery.minimumShouldMatch(), equalTo("1")); assertThat(parsedQuery.must(), empty()); @@ -53,7 +53,7 @@ public void testExistsQueryUsingAWildcard() { assertThat(parsedQuery.should(), containsInAnyOrder(mappedLeafFields().stream().map(QueryBuilders::existsQuery).toArray())); } - private String kqlExistsQuery(String field) { + private static String kqlExistsQuery(String field) { return wrapWithRandomWhitespaces(field) + wrapWithRandomWhitespaces(":") + wrapWithRandomWhitespaces("*"); } } diff --git a/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/KqlParserFieldQueryTests.java b/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/KqlParserFieldQueryTests.java new file mode 100644 index 0000000000000..6f8f6e07b9722 --- /dev/null +++ b/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/KqlParserFieldQueryTests.java @@ -0,0 +1,137 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.kql.parser; + +import org.elasticsearch.core.Strings; +import org.elasticsearch.index.query.MatchNoneQueryBuilder; + +import java.util.List; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.isA; + +public class KqlParserFieldQueryTests extends AbstractKqlParserTestCase { + + public void testParseFieldQueryWithNoMatchingFields() { + // Using an unquoted literal + assertThat(parseKqlQuery(kqlFieldQuery("not_a_field", randomIdentifier())), isA(MatchNoneQueryBuilder.class)); + assertThat(parseKqlQuery(kqlFieldQuery("not_a_field", randomInt())), isA(MatchNoneQueryBuilder.class)); + assertThat(parseKqlQuery(kqlFieldQuery("not_a_field", quoteString(randomIdentifier()))), isA(MatchNoneQueryBuilder.class)); + + // Using a quoted string as field name + assertThat(parseKqlQuery(kqlFieldQuery(quoteString("not_a_field"), randomIdentifier())), isA(MatchNoneQueryBuilder.class)); + assertThat(parseKqlQuery(kqlFieldQuery(quoteString("not_a_field"), randomInt())), isA(MatchNoneQueryBuilder.class)); + assertThat( + parseKqlQuery(kqlFieldQuery(quoteString("not_a_field"), quoteString(randomIdentifier()))), + isA(MatchNoneQueryBuilder.class) + ); + + // Not expanding wildcard with quoted string + assertThat(parseKqlQuery(kqlFieldQuery(quoteString("mapped_*"), randomIdentifier())), isA(MatchNoneQueryBuilder.class)); + assertThat(parseKqlQuery(kqlFieldQuery(quoteString("mapped_*"), randomInt())), isA(MatchNoneQueryBuilder.class)); + assertThat( + parseKqlQuery(kqlFieldQuery(quoteString("mapped_*"), quoteString(randomIdentifier()))), + isA(MatchNoneQueryBuilder.class) + ); + } + + public void testParseUnquotedLiteralKeywordFieldQuery() { + // Single word + assertTermQueryBuilder(parseKqlQuery(kqlFieldQuery(KEYWORD_FIELD_NAME, "foo")), KEYWORD_FIELD_NAME, "foo"); + + // Multiple words + assertTermQueryBuilder(parseKqlQuery(kqlFieldQuery(KEYWORD_FIELD_NAME, "foo bar")), KEYWORD_FIELD_NAME, "foo bar"); + + // Escaped keywords + assertTermQueryBuilder(parseKqlQuery(kqlFieldQuery(KEYWORD_FIELD_NAME, "foo \\and bar")), KEYWORD_FIELD_NAME, "foo and bar"); + assertTermQueryBuilder(parseKqlQuery(kqlFieldQuery(KEYWORD_FIELD_NAME, "foo \\or bar")), KEYWORD_FIELD_NAME, "foo or bar"); + assertTermQueryBuilder(parseKqlQuery(kqlFieldQuery(KEYWORD_FIELD_NAME, "\\not foo bar")), KEYWORD_FIELD_NAME, "not foo bar"); + + // Escaped characters + assertTermQueryBuilder(parseKqlQuery(kqlFieldQuery(KEYWORD_FIELD_NAME, "foo \\* bar")), KEYWORD_FIELD_NAME, "foo * bar"); + assertTermQueryBuilder(parseKqlQuery(kqlFieldQuery(KEYWORD_FIELD_NAME, "foo\\(bar\\)")), KEYWORD_FIELD_NAME, "foo(bar)"); + assertTermQueryBuilder(parseKqlQuery(kqlFieldQuery(KEYWORD_FIELD_NAME, "foo\\{bar\\}")), KEYWORD_FIELD_NAME, "foo{bar}"); + assertTermQueryBuilder(parseKqlQuery(kqlFieldQuery(KEYWORD_FIELD_NAME, "foo\\:bar")), KEYWORD_FIELD_NAME, "foo:bar"); + assertTermQueryBuilder(parseKqlQuery(kqlFieldQuery(KEYWORD_FIELD_NAME, "foo\\<bar")), KEYWORD_FIELD_NAME, "foo<bar"); + assertTermQueryBuilder(parseKqlQuery(kqlFieldQuery(KEYWORD_FIELD_NAME, "foo\\>bar")), KEYWORD_FIELD_NAME, "foo>bar"); + assertTermQueryBuilder(parseKqlQuery(kqlFieldQuery(KEYWORD_FIELD_NAME, "foo \\\\ bar")), KEYWORD_FIELD_NAME, "foo \\ bar"); + assertTermQueryBuilder(parseKqlQuery(kqlFieldQuery(KEYWORD_FIELD_NAME, "foo\\\"bar\\\"")), KEYWORD_FIELD_NAME, "foo\"bar\""); + + // Wrapping terms into parentheses + assertTermQueryBuilder(parseKqlQuery(kqlFieldQuery(KEYWORD_FIELD_NAME, "(foo baz)")), KEYWORD_FIELD_NAME, "foo baz"); + + // Check we can use quoted field name as well + assertThat( + parseKqlQuery(kqlFieldQuery(KEYWORD_FIELD_NAME, "foo")), + equalTo(parseKqlQuery(kqlFieldQuery(quoteString(KEYWORD_FIELD_NAME), "foo"))) + ); + } + + public void testParseDateFieldQuery() { + + assertRangeQueryBuilder(parseKqlQuery(kqlFieldQuery(DATE_FIELD_NAME, "2010-06-03")), DATE_FIELD_NAME, (rangeQuery) -> { + assertThat(rangeQuery.from(), equalTo("2010-06-03")); + assertThat(rangeQuery.includeLower(), equalTo(true)); + assertThat(rangeQuery.to(), equalTo("2010-06-03")); + assertThat(rangeQuery.includeUpper(), equalTo(true)); + + // Check we can use quoted field name as well + assertThat(parseKqlQuery(kqlFieldQuery(quoteString(DATE_FIELD_NAME), "2010-06-03")), equalTo(rangeQuery)); + + // Check we can use quoted value as well + assertThat(parseKqlQuery(kqlFieldQuery(DATE_FIELD_NAME, quoteString("2010-06-03"))), equalTo(rangeQuery)); + }); + + } + + public void testParseUnquotedLiteralMatchFieldsQuery() { + for (String fieldName : List.of(TEXT_FIELD_NAME, INT_FIELD_NAME, DOUBLE_FIELD_NAME)) { + // Single word + assertMatchQueryBuilder(parseKqlQuery(kqlFieldQuery(fieldName, "foo")), fieldName, "foo"); + + // Numbers are converted to string + assertMatchQueryBuilder(parseKqlQuery(kqlFieldQuery(fieldName, 1)), fieldName, "1"); + assertMatchQueryBuilder(parseKqlQuery(kqlFieldQuery(fieldName, 1.5)), fieldName, "1.5"); + + // Multiple words + assertMatchQueryBuilder(parseKqlQuery(kqlFieldQuery(fieldName, "foo bar")), fieldName, "foo bar"); + + // Escaped keywords + assertMatchQueryBuilder(parseKqlQuery(kqlFieldQuery(fieldName, "foo \\and bar")), fieldName, "foo and bar"); + assertMatchQueryBuilder(parseKqlQuery(kqlFieldQuery(fieldName, "foo \\or bar")), fieldName, "foo or bar"); + assertMatchQueryBuilder(parseKqlQuery(kqlFieldQuery(fieldName, "\\not foo bar")), fieldName, "not foo bar"); + + // Escaped characters + assertMatchQueryBuilder(parseKqlQuery(kqlFieldQuery(fieldName, "foo \\* bar")), fieldName, "foo * bar"); + assertMatchQueryBuilder(parseKqlQuery(kqlFieldQuery(fieldName, "foo\\(bar\\)")), fieldName, "foo(bar)"); + assertMatchQueryBuilder(parseKqlQuery(kqlFieldQuery(fieldName, "foo\\{bar\\}")), fieldName, "foo{bar}"); + assertMatchQueryBuilder(parseKqlQuery(kqlFieldQuery(fieldName, "foo\\:bar")), fieldName, "foo:bar"); + assertMatchQueryBuilder(parseKqlQuery(kqlFieldQuery(fieldName, "foo\\<bar")), fieldName, "foo<bar"); + assertMatchQueryBuilder(parseKqlQuery(kqlFieldQuery(fieldName, "foo\\>bar")), fieldName, "foo>bar"); + assertMatchQueryBuilder(parseKqlQuery(kqlFieldQuery(fieldName, "foo \\\\ bar")), fieldName, "foo \\ bar"); + assertMatchQueryBuilder(parseKqlQuery(kqlFieldQuery(fieldName, "foo\\\"bar\\\"")), fieldName, "foo\"bar\""); + + // Wrapping terms into parentheses + assertMatchQueryBuilder(parseKqlQuery(kqlFieldQuery(fieldName, "(foo baz)")), fieldName, "foo baz"); + + // Check we can use quoted field name as well + assertThat( + parseKqlQuery(kqlFieldQuery(fieldName, "foo")), + equalTo(parseKqlQuery(kqlFieldQuery(quoteString(fieldName), "foo"))) + ); + } + } + + private static String kqlFieldQuery(String field, Object value) { + return wrapWithRandomWhitespaces(field) + wrapWithRandomWhitespaces(":") + wrapWithRandomWhitespaces(value.toString()); + } + + private static String quoteString(String input) { + return Strings.format("\"%s\"", input); + } +} diff --git a/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/KqlParserFieldlessQueryTests.java b/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/KqlParserFieldlessQueryTests.java index 2edcd6b395557..9a4a801ba8a86 100644 --- a/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/KqlParserFieldlessQueryTests.java +++ b/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/KqlParserFieldlessQueryTests.java @@ -8,26 +8,35 @@ package org.elasticsearch.xpack.kql.parser; import org.elasticsearch.index.query.MultiMatchQueryBuilder; -import org.elasticsearch.index.query.QueryBuilder; -import org.elasticsearch.index.query.QueryStringQueryBuilder; - -import static org.hamcrest.Matchers.anEmptyMap; -import static org.hamcrest.Matchers.equalTo; public class KqlParserFieldlessQueryTests extends AbstractKqlParserTestCase { - public void testLiteralFieldlessQuery() { + public void testParseUnquotedLiteralQuery() { // Single word assertMultiMatchQuery(parseKqlQuery("foo"), "foo", MultiMatchQueryBuilder.Type.BEST_FIELDS); // Multiple words assertMultiMatchQuery(parseKqlQuery("foo bar baz"), "foo bar baz", MultiMatchQueryBuilder.Type.BEST_FIELDS); - // With an escaped wildcard - assertMultiMatchQuery(parseKqlQuery("foo \\* baz"), "foo * baz", MultiMatchQueryBuilder.Type.BEST_FIELDS); + + // Escaped keywords + assertMultiMatchQuery(parseKqlQuery("foo \\and bar"), "foo and bar", MultiMatchQueryBuilder.Type.BEST_FIELDS); + assertMultiMatchQuery(parseKqlQuery("foo \\or bar"), "foo or bar", MultiMatchQueryBuilder.Type.BEST_FIELDS); + assertMultiMatchQuery(parseKqlQuery("\\not foo bar"), "not foo bar", MultiMatchQueryBuilder.Type.BEST_FIELDS); + + // With an escaped characters + assertMultiMatchQuery(parseKqlQuery("foo \\* bar"), "foo * bar", MultiMatchQueryBuilder.Type.BEST_FIELDS); + assertMultiMatchQuery(parseKqlQuery("foo\\(bar\\)"), "foo(bar)", MultiMatchQueryBuilder.Type.BEST_FIELDS); + assertMultiMatchQuery(parseKqlQuery("foo\\{bar\\}"), "foo{bar}", MultiMatchQueryBuilder.Type.BEST_FIELDS); + assertMultiMatchQuery(parseKqlQuery("foo\\:bar"), "foo:bar", MultiMatchQueryBuilder.Type.BEST_FIELDS); + assertMultiMatchQuery(parseKqlQuery("foo\\<bar"), "foo<bar", MultiMatchQueryBuilder.Type.BEST_FIELDS); + assertMultiMatchQuery(parseKqlQuery("foo\\>bar"), "foo>bar", MultiMatchQueryBuilder.Type.BEST_FIELDS); + assertMultiMatchQuery(parseKqlQuery("foo \\\\ bar"), "foo \\ bar", MultiMatchQueryBuilder.Type.BEST_FIELDS); + assertMultiMatchQuery(parseKqlQuery("foo\\\"bar\\\""), "foo\"bar\"", MultiMatchQueryBuilder.Type.BEST_FIELDS); + // Wrapping terms into parentheses - assertMultiMatchQuery(parseKqlQuery("foo baz"), "foo baz", MultiMatchQueryBuilder.Type.BEST_FIELDS); + assertMultiMatchQuery(parseKqlQuery("(foo baz)"), "foo baz", MultiMatchQueryBuilder.Type.BEST_FIELDS); } - public void testWildcardFieldlessQuery() { + public void testParseWildcardQuery() { // Single word assertQueryStringBuilder(parseKqlQuery("foo*"), "foo*"); assertQueryStringBuilder(parseKqlQuery("*foo"), "*foo"); @@ -44,7 +53,7 @@ public void testWildcardFieldlessQuery() { assertQueryStringBuilder(parseKqlQuery("+foo* -bar"), "\\+foo* \\-bar"); } - public void testMatchPhraseQuery() { + public void testParseQuotedStringQuery() { // Single word assertMultiMatchQuery(parseKqlQuery("\"foo\""), "foo", MultiMatchQueryBuilder.Type.PHRASE); // Multiple words @@ -54,17 +63,4 @@ public void testMatchPhraseQuery() { // Containing unescaped KQL reserved characters assertMultiMatchQuery(parseKqlQuery("\"foo*: {(<bar>})\""), "foo*: {(<bar>})", MultiMatchQueryBuilder.Type.PHRASE); } - - private void assertMultiMatchQuery(QueryBuilder query, String expectedValue, MultiMatchQueryBuilder.Type expectedType) { - MultiMatchQueryBuilder multiMatchQuery = asInstanceOf(MultiMatchQueryBuilder.class, query); - assertThat(multiMatchQuery.fields(), anEmptyMap()); - assertThat(multiMatchQuery.lenient(), equalTo(true)); - assertThat(multiMatchQuery.type(), equalTo(expectedType)); - assertThat(multiMatchQuery.value(), equalTo(expectedValue)); - } - - private void assertQueryStringBuilder(QueryBuilder query, String expectedValue) { - QueryStringQueryBuilder queryStringQuery = asInstanceOf(QueryStringQueryBuilder.class, query); - assertThat(queryStringQuery.queryString(), equalTo(expectedValue)); - } } diff --git a/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/ParserUtilsTests.java b/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/ParserUtilsTests.java index ddcd09c40f530..1d374b11a790b 100644 --- a/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/ParserUtilsTests.java +++ b/x-pack/plugin/kql/src/test/java/org/elasticsearch/xpack/kql/parser/ParserUtilsTests.java @@ -141,7 +141,7 @@ public void testHasWildcard() { assertTrue(hasWildcard(parserRuleContext(randomTextNodeListWithNode(wildcardNode())))); // All children are literals - assertFalse(hasWildcard(parserRuleContext(randomList(1, randomInt(100), this::randomLiteralNode)))); + assertFalse(hasWildcard(parserRuleContext(randomList(1, randomInt(100), ParserUtilsTests::randomLiteralNode)))); // Quoted string assertFalse(hasWildcard(parserRuleContext(randomQuotedStringNode()))); @@ -186,30 +186,32 @@ public void testEscapeQueryString() { assertThat(escapeQueryString("foo*", false), equalTo("foo\\*")); } - private ParserRuleContext parserRuleContext(ParseTree child) { + private static ParserRuleContext parserRuleContext(ParseTree child) { return parserRuleContext(List.of(child)); } - private ParserRuleContext parserRuleContext(List<ParseTree> children) { + private static ParserRuleContext parserRuleContext(List<ParseTree> children) { ParserRuleContext ctx = new ParserRuleContext(null, randomInt()); ctx.children = children; return ctx; } - private TerminalNode terminalNode(int type, String text) { + private static TerminalNode terminalNode(int type, String text) { Token symbol = mock(Token.class); when(symbol.getType()).thenReturn(type); when(symbol.getText()).thenReturn(text); return new TerminalNodeImpl(symbol); } - private List<ParseTree> randomTextNodeListWithNode(TerminalNode node) { - List<ParseTree> nodes = new ArrayList<>(Stream.concat(Stream.generate(this::randomTextNode).limit(100), Stream.of(node)).toList()); + private static List<ParseTree> randomTextNodeListWithNode(TerminalNode node) { + List<ParseTree> nodes = new ArrayList<>( + Stream.concat(Stream.generate(ParserUtilsTests::randomTextNode).limit(100), Stream.of(node)).toList() + ); Collections.shuffle(nodes, random()); return nodes; } - private TerminalNode randomTextNode() { + private static TerminalNode randomTextNode() { return switch (randomInt() % 3) { case 0 -> wildcardNode(); case 1 -> randomQuotedStringNode(); @@ -217,23 +219,23 @@ private TerminalNode randomTextNode() { }; } - private TerminalNode quotedStringNode(String quotedStringText) { + private static TerminalNode quotedStringNode(String quotedStringText) { return terminalNode(QUOTED_STRING, "\"" + quotedStringText + "\""); } - private TerminalNode randomQuotedStringNode() { + private static TerminalNode randomQuotedStringNode() { return quotedStringNode(randomIdentifier()); } - private TerminalNode literalNode(String literalText) { + private static TerminalNode literalNode(String literalText) { return terminalNode(UNQUOTED_LITERAL, literalText); } - private TerminalNode randomLiteralNode() { + private static TerminalNode randomLiteralNode() { return terminalNode(UNQUOTED_LITERAL, randomIdentifier()); } - private TerminalNode wildcardNode() { + private static TerminalNode wildcardNode() { return terminalNode(WILDCARD, "*"); } } diff --git a/x-pack/plugin/kql/src/test/resources/unsupported-queries b/x-pack/plugin/kql/src/test/resources/unsupported-queries index 9c9876db79d2b..0b377ce8d5d82 100644 --- a/x-pack/plugin/kql/src/test/resources/unsupported-queries +++ b/x-pack/plugin/kql/src/test/resources/unsupported-queries @@ -21,9 +21,7 @@ foo_field: foo bar" // Invalid boolean queries -foo AND AND foo -foo OR OR foo NOT foo: