From 59d058483ca363aa93513620c6779fed8d770350 Mon Sep 17 00:00:00 2001 From: Andrei Stefan Date: Wed, 18 Dec 2024 14:20:56 +0200 Subject: [PATCH] Lookup join on multiple join fields not yet supported (#118858) (#118940) --- docs/changelog/118858.yaml | 5 +++ .../xpack/esql/parser/LogicalPlanBuilder.java | 5 +++ .../xpack/esql/analysis/ParsingTests.java | 41 +++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 docs/changelog/118858.yaml diff --git a/docs/changelog/118858.yaml b/docs/changelog/118858.yaml new file mode 100644 index 0000000000000..a2161df1c84c7 --- /dev/null +++ b/docs/changelog/118858.yaml @@ -0,0 +1,5 @@ +pr: 118858 +summary: Lookup join on multiple join fields not yet supported +area: ES|QL +type: enhancement +issues: [] diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java index 24398afa18010..49d77bc36fb2e 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java @@ -564,6 +564,11 @@ public PlanFactory visitJoinCommand(EsqlBaseParser.JoinCommandContext ctx) { } } + var matchFieldsCount = joinFields.size(); + if (matchFieldsCount > 1) { + throw new ParsingException(source, "JOIN ON clause only supports one field at the moment, found [{}]", matchFieldsCount); + } + return p -> new LookupJoin(source, p, right, joinFields); } } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/ParsingTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/ParsingTests.java index 205c8943d4e3c..90a215653f251 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/ParsingTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/ParsingTests.java @@ -12,6 +12,7 @@ import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.json.JsonXContent; import org.elasticsearch.xpack.esql.LoadMapping; +import org.elasticsearch.xpack.esql.action.EsqlCapabilities; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.type.DataType; import org.elasticsearch.xpack.esql.expression.function.EsqlFunctionRegistry; @@ -111,6 +112,46 @@ public void testTooBigQuery() { assertEquals("-1:-1: ESQL statement is too large [1000011 characters > 1000000]", error(query.toString())); } + public void testJoinOnConstant() { + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assertEquals( + "1:55: JOIN ON clause only supports fields at the moment, found [123]", + error("row languages = 1, gender = \"f\" | lookup join test on 123") + ); + assertEquals( + "1:55: JOIN ON clause only supports fields at the moment, found [\"abc\"]", + error("row languages = 1, gender = \"f\" | lookup join test on \"abc\"") + ); + assertEquals( + "1:55: JOIN ON clause only supports fields at the moment, found [false]", + error("row languages = 1, gender = \"f\" | lookup join test on false") + ); + } + + public void testJoinOnMultipleFields() { + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assertEquals( + "1:35: JOIN ON clause only supports one field at the moment, found [2]", + error("row languages = 1, gender = \"f\" | lookup join test on gender, languages") + ); + } + + public void testJoinTwiceOnTheSameField() { + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assertEquals( + "1:35: JOIN ON clause only supports one field at the moment, found [2]", + error("row languages = 1, gender = \"f\" | lookup join test on languages, languages") + ); + } + + public void testJoinTwiceOnTheSameField_TwoLookups() { + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assertEquals( + "1:80: JOIN ON clause only supports one field at the moment, found [2]", + error("row languages = 1, gender = \"f\" | lookup join test on languages | eval x = 1 | lookup join test on gender, gender") + ); + } + private String functionName(EsqlFunctionRegistry registry, Expression functionCall) { for (FunctionDefinition def : registry.listFunctions()) { if (functionCall.getClass().equals(def.clazz())) {