Skip to content

Commit 2f99cd3

Browse files
pmpailisfzowl
authored andcommitted
[ES|QL] Allow single fork branch (elastic#136805)
1 parent f9bd78a commit 2f99cd3

File tree

6 files changed

+45
-14
lines changed

6 files changed

+45
-14
lines changed

docs/changelog/136805.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 136805
2+
summary: Allow single fork branch
3+
area: ES|QL
4+
type: enhancement
5+
issues:
6+
- 135825

x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/ForkIT.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,8 +1005,14 @@ public void testOneSubQuery() {
10051005
| FORK
10061006
( WHERE content:"fox" )
10071007
""";
1008-
var e = expectThrows(ParsingException.class, () -> run(query));
1009-
assertTrue(e.getMessage().contains("Fork requires at least 2 branches"));
1008+
try (var resp = run(query)) {
1009+
assertColumnTypes(resp.columns(), List.of("text", "integer", "keyword"));
1010+
assertColumnNames(resp.columns(), List.of("content", "id", "_fork"));
1011+
Iterable<Iterable<Object>> expectedValues = List.of(
1012+
Arrays.stream(new Object[] { "The quick brown fox jumps over the lazy dog", 6, "fork1" }).toList()
1013+
);
1014+
assertValues(resp.values(), expectedValues);
1015+
}
10101016
}
10111017

10121018
public void testForkWithinFork() {

x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/FuseIT.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.elasticsearch.action.support.WriteRequest;
1212
import org.elasticsearch.common.settings.Settings;
1313
import org.elasticsearch.plugins.Plugin;
14+
import org.elasticsearch.xpack.esql.plan.logical.fuse.Fuse;
1415
import org.junit.Before;
1516

1617
import java.util.Collection;
@@ -163,6 +164,30 @@ public void testFuseLinearWithWeightsAndNormalizer() {
163164
}
164165
}
165166

167+
public void testFuseWithSingleFork() {
168+
for (Fuse.FuseType type : Fuse.FuseType.values()) {
169+
var query = """
170+
FROM test METADATA _score, _id, _index
171+
| WHERE id > 2
172+
| FORK
173+
( WHERE content:"fox" | SORT _score, _id DESC )
174+
| FUSE
175+
""" + type.name() + """
176+
| SORT _score DESC, _id, _index
177+
| EVAL _fork = mv_sort(_fork)
178+
| EVAL _score = round(_score, 4)
179+
| KEEP id, content, _fork
180+
""";
181+
try (var resp = run(query)) {
182+
assertColumnNames(resp.columns(), List.of("id", "content", "_fork"));
183+
assertColumnTypes(resp.columns(), List.of("integer", "keyword", "keyword"));
184+
assertThat(getValuesList(resp.values()).size(), equalTo(1));
185+
Iterable<Iterable<Object>> expectedValues = List.of(List.of(6, "The quick brown fox jumps over the lazy dog", "fork1"));
186+
assertValues(resp.values(), expectedValues);
187+
}
188+
}
189+
}
190+
166191
private void createAndPopulateIndex() {
167192
var indexName = "test";
168193
var client = client().admin().indices();

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -848,9 +848,6 @@ private void checkForRemoteClusters(LogicalPlan plan, Source source, String comm
848848
@SuppressWarnings("unchecked")
849849
public PlanFactory visitForkCommand(EsqlBaseParser.ForkCommandContext ctx) {
850850
List<PlanFactory> subQueries = visitForkSubQueries(ctx.forkSubQueries());
851-
if (subQueries.size() < Fork.MIN_BRANCHES) {
852-
throw new ParsingException(source(ctx), "Fork requires at least " + Fork.MIN_BRANCHES + " branches");
853-
}
854851
if (subQueries.size() > Fork.MAX_BRANCHES) {
855852
throw new ParsingException(source(ctx), "Fork supports up to " + Fork.MAX_BRANCHES + " branches");
856853
}

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Fork.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,10 @@ public class Fork extends LogicalPlan implements PostAnalysisPlanVerificationAwa
3939

4040
public static final String FORK_FIELD = "_fork";
4141
public static final int MAX_BRANCHES = 8;
42-
public static final int MIN_BRANCHES = 2;
4342
private final List<Attribute> output;
4443

4544
public Fork(Source source, List<LogicalPlan> children, List<Attribute> output) {
4645
super(source, children);
47-
if (children.size() < MIN_BRANCHES) {
48-
throw new IllegalArgumentException("FORK requires more than " + MIN_BRANCHES + " branches, got: " + children.size());
49-
}
5046
if (children.size() > MAX_BRANCHES) {
5147
throw new IllegalArgumentException("FORK supports up to " + MAX_BRANCHES + " branches, got: " + children.size());
5248
}

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/StatementParserTests.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3861,11 +3861,12 @@ public void testForkAllCommands() {
38613861
}
38623862

38633863
public void testInvalidFork() {
3864-
expectError("FROM foo* | FORK (WHERE a:\"baz\")", "line 1:13: Fork requires at least 2 branches");
3865-
expectError("FROM foo* | FORK (LIMIT 10)", "line 1:13: Fork requires at least 2 branches");
3866-
expectError("FROM foo* | FORK (SORT a)", "line 1:13: Fork requires at least 2 branches");
3867-
expectError("FROM foo* | FORK (WHERE x>1 | LIMIT 5)", "line 1:13: Fork requires at least 2 branches");
3868-
expectError("FROM foo* | WHERE x>1 | FORK (WHERE a:\"baz\")", "Fork requires at least 2 branches");
3864+
expectError("""
3865+
FROM foo* | FORK
3866+
""", "line 2:1: mismatched input '<EOF>' expecting '('");
3867+
expectError("""
3868+
FROM foo* | FORK ()
3869+
""", "line 1:19: mismatched input ')'");
38693870

38703871
expectError("""
38713872
FROM foo*

0 commit comments

Comments
 (0)