Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,7 @@ public void testOneSubQuery() {
( WHERE content:"fox" )
""";
var e = expectThrows(ParsingException.class, () -> run(query));
assertTrue(e.getMessage().contains("Fork requires at least two branches"));
assertTrue(e.getMessage().contains("Fork requires at least 2 branches"));
}

public void testForkWithinFork() {
Expand Down Expand Up @@ -1047,6 +1047,17 @@ public void testProfile() {
}
}

public void testWithTooManySubqueries() {
var query = """
FROM test
| FORK (WHERE true) (WHERE true) (WHERE true) (WHERE true) (WHERE true)
(WHERE true) (WHERE true) (WHERE true) (WHERE true)
""";
var e = expectThrows(ParsingException.class, () -> run(query));
assertTrue(e.getMessage().contains("Fork requires less than 8 branches"));

}

private void createAndPopulateIndices() {
var indexName = "test";
var client = client().admin().indices();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -651,9 +651,13 @@ private void checkForRemoteClusters(LogicalPlan plan, Source source, String comm
@SuppressWarnings("unchecked")
public PlanFactory visitForkCommand(EsqlBaseParser.ForkCommandContext ctx) {
List<PlanFactory> subQueries = visitForkSubQueries(ctx.forkSubQueries());
if (subQueries.size() < 2) {
throw new ParsingException(source(ctx), "Fork requires at least two branches");
if (subQueries.size() < Fork.MIN_BRANCHES) {
throw new ParsingException(source(ctx), "Fork requires at least " + Fork.MIN_BRANCHES + " branches");
}
if (subQueries.size() > Fork.MAX_BRANCHES) {
throw new ParsingException(source(ctx), "Fork requires less than " + Fork.MAX_BRANCHES + " branches");
}

return input -> {
checkForRemoteClusters(input, source(ctx), "FORK");
List<LogicalPlan> subPlans = subQueries.stream().map(planFactory -> planFactory.apply(input)).toList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,19 @@
public class Fork extends LogicalPlan implements PostAnalysisPlanVerificationAware, TelemetryAware {

public static final String FORK_FIELD = "_fork";
public static final int MAX_BRANCHES = 8;
public static final int MIN_BRANCHES = 2;
private final List<Attribute> output;

public Fork(Source source, List<LogicalPlan> children, List<Attribute> output) {
super(source, children);
if (children.size() < 2) {
throw new IllegalArgumentException("requires more than two subqueries, got:" + children.size());
if (children.size() < MIN_BRANCHES) {
throw new IllegalArgumentException("FORK requires more than " + MIN_BRANCHES + " branches, got: " + children.size());
}
if (children.size() > MAX_BRANCHES) {
throw new IllegalArgumentException("FORK requires less than " + MAX_BRANCHES + " subqueries, got: " + children.size());
}

this.output = output;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3403,11 +3403,18 @@ public void testForkAllCommands() {
}

public void testInvalidFork() {
expectError("FROM foo* | FORK (WHERE a:\"baz\")", "line 1:13: Fork requires at least two branches");
expectError("FROM foo* | FORK (LIMIT 10)", "line 1:13: Fork requires at least two branches");
expectError("FROM foo* | FORK (SORT a)", "line 1:13: Fork requires at least two branches");
expectError("FROM foo* | FORK (WHERE x>1 | LIMIT 5)", "line 1:13: Fork requires at least two branches");
expectError("FROM foo* | WHERE x>1 | FORK (WHERE a:\"baz\")", "Fork requires at least two branches");
expectError("FROM foo* | FORK (WHERE a:\"baz\")", "line 1:13: Fork requires at least 2 branches");
expectError("FROM foo* | FORK (LIMIT 10)", "line 1:13: Fork requires at least 2 branches");
expectError("FROM foo* | FORK (SORT a)", "line 1:13: Fork requires at least 2 branches");
expectError("FROM foo* | FORK (WHERE x>1 | LIMIT 5)", "line 1:13: Fork requires at least 2 branches");
expectError("FROM foo* | WHERE x>1 | FORK (WHERE a:\"baz\")", "Fork requires at least 2 branches");

expectError("""
FROM foo*
| FORK (where true) (where true) (where true) (where true)
(where true) (where true) (where true) (where true)
(where true)
""", "Fork requires less than 8 branches");

expectError("FROM foo* | FORK ( x+1 ) ( WHERE y>2 )", "line 1:20: mismatched input 'x+1'");
expectError("FROM foo* | FORK ( LIMIT 10 ) ( y+2 )", "line 1:33: mismatched input 'y+2'");
Expand Down