diff --git a/docs/reference/query-languages/esql/_snippets/commands/examples/fork.csv-spec/simpleFork.md b/docs/reference/query-languages/esql/_snippets/commands/examples/fork.csv-spec/simpleFork.md new file mode 100644 index 0000000000000..c4752cb9648c6 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/commands/examples/fork.csv-spec/simpleFork.md @@ -0,0 +1,14 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +```esql +FROM employees +| FORK ( WHERE emp_no == 10001 ) + ( WHERE emp_no == 10002 ) +| KEEP emp_no, _fork +| SORT emp_no +``` + +| emp_no:integer | _fork:keyword | +| --- | --- | +| 10001 | fork1 | +| 10002 | fork2 | diff --git a/docs/reference/query-languages/esql/_snippets/commands/examples/fork.csv-spec/simpleForkWithStats.md b/docs/reference/query-languages/esql/_snippets/commands/examples/fork.csv-spec/simpleForkWithStats.md new file mode 100644 index 0000000000000..d72ea42b3106f --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/commands/examples/fork.csv-spec/simpleForkWithStats.md @@ -0,0 +1,19 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +```esql +FROM books METADATA _score +| WHERE author:"Faulkner" +| EVAL score = round(_score, 2) +| FORK (SORT score DESC, author | LIMIT 5 | KEEP author, score) + (STATS total = COUNT(*)) +| SORT _fork, score DESC, author +``` + +| author:text | score:double | _fork:keyword | total:long | +| --- | --- | --- | --- | +| William Faulkner | 2.39 | fork1 | null | +| William Faulkner | 2.39 | fork1 | null | +| Colleen Faulkner | 1.59 | fork1 | null | +| Danny Faulkner | 1.59 | fork1 | null | +| Keith Faulkner | 1.59 | fork1 | null | +| null | null | fork2 | 18 | diff --git a/docs/reference/query-languages/esql/_snippets/commands/layout/fork.md b/docs/reference/query-languages/esql/_snippets/commands/layout/fork.md new file mode 100644 index 0000000000000..836daa7bbaddb --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/commands/layout/fork.md @@ -0,0 +1,57 @@ +## `FORK` [esql-fork] + +```yaml {applies_to} +serverless: preview +stack: preview 9.1.0 +``` + +The `FORK` processing command creates multiple execution branches to operate +on the same input data and combines the results in a single output table. + +**Syntax** + +```esql +FORK ( ) ( ) ... ( ) +``` + +**Description** + +The `FORK` processing command creates multiple execution branches to operate +on the same input data and combines the results in a single output table. A discriminator column (`_fork`) is added to identify which branch each row came from. + +**Branch identification:** +- The `_fork` column identifies each branch with values like `fork1`, `fork2`, `fork3` +- Values correspond to the order branches are defined +- `fork1` always indicates the first branch + +**Column handling:** +- `FORK` branches can output different columns +- Columns with the same name must have the same data type across all branches +- Missing columns are filled with `null` values + +**Row ordering:** +- `FORK` preserves row order within each branch +- Rows from different branches may be interleaved +- Use `SORT _fork` to group results by branch + +::::{note} +`FORK` branches default to `LIMIT 1000` if no `LIMIT` is provided. +:::: + +**Limitations** + +- `FORK` supports at most 8 execution branches. +- Using remote cluster references and `FORK` is not supported. +- Using more than one `FORK` command in a query is not supported. + +**Examples** + +In the following example, each `FORK` branch returns one row. +Notice how `FORK` adds a `_fork` column that indicates which row the branch originates from: + +:::{include} ../examples/fork.csv-spec/simpleFork.md + +The next example, returns total number of rows that match the query along with +the top five rows sorted by score. + +:::{include} ../examples/fork.csv-spec/simpleForkWithStats.md diff --git a/docs/reference/query-languages/esql/_snippets/lists/processing-commands.md b/docs/reference/query-languages/esql/_snippets/lists/processing-commands.md index a9bf1e276b95d..70bb3fc7e1775 100644 --- a/docs/reference/query-languages/esql/_snippets/lists/processing-commands.md +++ b/docs/reference/query-languages/esql/_snippets/lists/processing-commands.md @@ -4,6 +4,7 @@ * [`ENRICH`](../../commands/processing-commands.md#esql-enrich) * [`EVAL`](../../commands/processing-commands.md#esql-eval) * [`GROK`](../../commands/processing-commands.md#esql-grok) +* [preview] [`FORK`](../../commands/processing-commands.md#esql-fork) * [`KEEP`](../../commands/processing-commands.md#esql-keep) * [`LIMIT`](../../commands/processing-commands.md#esql-limit) * [`LOOKUP JOIN`](../../commands/processing-commands.md#esql-lookup-join) diff --git a/docs/reference/query-languages/esql/commands/processing-commands.md b/docs/reference/query-languages/esql/commands/processing-commands.md index 57084779d6d7a..6d00259e49f73 100644 --- a/docs/reference/query-languages/esql/commands/processing-commands.md +++ b/docs/reference/query-languages/esql/commands/processing-commands.md @@ -32,6 +32,9 @@ mapped_pages: :::{include} ../_snippets/commands/layout/eval.md ::: +:::{include} ../_snippets/commands/layout/fork.md +::: + :::{include} ../_snippets/commands/layout/grok.md ::: diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/fork.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/fork.csv-spec index 1cd9f60d01581..2c5b8a650a64a 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/fork.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/fork.csv-spec @@ -5,16 +5,44 @@ simpleFork required_capability: fork_v9 +// tag::simpleFork[] FROM employees | FORK ( WHERE emp_no == 10001 ) ( WHERE emp_no == 10002 ) | KEEP emp_no, _fork | SORT emp_no +// end::simpleFork[] ; +// tag::simpleFork-result-[] emp_no:integer | _fork:keyword 10001 | fork1 10002 | fork2 +// end::simpleFork-result[] +; + +simpleForkWithStats +required_capability: fork_v9 + +// tag::simpleForkWithStats[] +FROM books METADATA _score +| WHERE author:"Faulkner" +| EVAL score = round(_score, 2) +| FORK (SORT score DESC, author | LIMIT 5 | KEEP author, score) + (STATS total = COUNT(*)) +| SORT _fork, score DESC, author +// end::simpleForkWithStats[] +; + +// tag::simpleForkWithStats-result[] +author:text | score:double | _fork:keyword | total:long +William Faulkner | 2.39 | fork1 | null +William Faulkner | 2.39 | fork1 | null +Colleen Faulkner | 1.59 | fork1 | null +Danny Faulkner | 1.59 | fork1 | null +Keith Faulkner | 1.59 | fork1 | null +null | null | fork2 | 18 +// end::simpleForkWithStats-result[] ; forkWithWhereSortAndLimit