Selaa lähdekoodia

ESQL docs: generate references for functions (#98856)

This generates a "railroad diagram" svg image that can be embedded into
the docs for any function to explain it's syntax. It's basic, but it's
something we can iterate on.

It also generates a table of supported types from the list of types that
we test. It can be included in the docs for reference as well.
Nik Everett 2 vuotta sitten
vanhempi
commit
649ceb74ab
75 muutettua tiedostoa jossa 719 lisäystä ja 58 poistoa
  1. 7 0
      docs/reference/esql/functions/abs.asciidoc
  2. 7 0
      docs/reference/esql/functions/cosh.asciidoc
  3. 2 0
      docs/reference/esql/functions/greatest.asciidoc
  4. 4 29
      docs/reference/esql/functions/pow.asciidoc
  5. 1 0
      docs/reference/esql/functions/signature/abs.svg
  6. 1 0
      docs/reference/esql/functions/signature/acos.svg
  7. 1 0
      docs/reference/esql/functions/signature/asin.svg
  8. 1 0
      docs/reference/esql/functions/signature/atan.svg
  9. 1 0
      docs/reference/esql/functions/signature/atan2.svg
  10. 1 0
      docs/reference/esql/functions/signature/case.svg
  11. 1 0
      docs/reference/esql/functions/signature/coalesce.svg
  12. 1 0
      docs/reference/esql/functions/signature/concat.svg
  13. 1 0
      docs/reference/esql/functions/signature/cos.svg
  14. 1 0
      docs/reference/esql/functions/signature/cosh.svg
  15. 1 0
      docs/reference/esql/functions/signature/e.svg
  16. 1 0
      docs/reference/esql/functions/signature/floor.svg
  17. 1 0
      docs/reference/esql/functions/signature/greatest.svg
  18. 1 0
      docs/reference/esql/functions/signature/least.svg
  19. 1 0
      docs/reference/esql/functions/signature/length.svg
  20. 1 0
      docs/reference/esql/functions/signature/log10.svg
  21. 1 0
      docs/reference/esql/functions/signature/ltrim.svg
  22. 1 0
      docs/reference/esql/functions/signature/pi.svg
  23. 1 0
      docs/reference/esql/functions/signature/pow.svg
  24. 1 0
      docs/reference/esql/functions/signature/round.svg
  25. 1 0
      docs/reference/esql/functions/signature/rtrim.svg
  26. 1 0
      docs/reference/esql/functions/signature/sin.svg
  27. 1 0
      docs/reference/esql/functions/signature/sinh.svg
  28. 1 0
      docs/reference/esql/functions/signature/split.svg
  29. 1 0
      docs/reference/esql/functions/signature/sqrt.svg
  30. 1 0
      docs/reference/esql/functions/signature/substring.svg
  31. 1 0
      docs/reference/esql/functions/signature/tan.svg
  32. 1 0
      docs/reference/esql/functions/signature/tanh.svg
  33. 1 0
      docs/reference/esql/functions/signature/tau.svg
  34. 1 0
      docs/reference/esql/functions/signature/trim.svg
  35. 8 0
      docs/reference/esql/functions/types/abs.asciidoc
  36. 8 0
      docs/reference/esql/functions/types/acos.asciidoc
  37. 8 0
      docs/reference/esql/functions/types/asin.asciidoc
  38. 8 0
      docs/reference/esql/functions/types/atan.asciidoc
  39. 20 0
      docs/reference/esql/functions/types/atan2.asciidoc
  40. 5 0
      docs/reference/esql/functions/types/case.asciidoc
  41. 49 0
      docs/reference/esql/functions/types/coalesce.asciidoc
  42. 5 0
      docs/reference/esql/functions/types/concat.asciidoc
  43. 8 0
      docs/reference/esql/functions/types/cos.asciidoc
  44. 8 0
      docs/reference/esql/functions/types/cosh.asciidoc
  45. 5 0
      docs/reference/esql/functions/types/e.asciidoc
  46. 5 0
      docs/reference/esql/functions/types/floor.asciidoc
  47. 49 0
      docs/reference/esql/functions/types/greatest.asciidoc
  48. 49 0
      docs/reference/esql/functions/types/least.asciidoc
  49. 5 0
      docs/reference/esql/functions/types/length.asciidoc
  50. 5 0
      docs/reference/esql/functions/types/log10.asciidoc
  51. 6 0
      docs/reference/esql/functions/types/ltrim.asciidoc
  52. 5 0
      docs/reference/esql/functions/types/pi.asciidoc
  53. 10 0
      docs/reference/esql/functions/types/pow.asciidoc
  54. 5 0
      docs/reference/esql/functions/types/round.asciidoc
  55. 6 0
      docs/reference/esql/functions/types/rtrim.asciidoc
  56. 8 0
      docs/reference/esql/functions/types/sin.asciidoc
  57. 8 0
      docs/reference/esql/functions/types/sinh.asciidoc
  58. 5 0
      docs/reference/esql/functions/types/split.asciidoc
  59. 5 0
      docs/reference/esql/functions/types/sqrt.asciidoc
  60. 5 0
      docs/reference/esql/functions/types/substring.asciidoc
  61. 8 0
      docs/reference/esql/functions/types/tan.asciidoc
  62. 8 0
      docs/reference/esql/functions/types/tanh.asciidoc
  63. 5 0
      docs/reference/esql/functions/types/tau.asciidoc
  64. 6 0
      docs/reference/esql/functions/types/trim.asciidoc
  65. 5 0
      gradle/verification-metadata.xml
  66. 20 0
      x-pack/plugin/esql/build.gradle
  67. 6 1
      x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/ConsumeProcessor.java
  68. 3 3
      x-pack/plugin/esql/qa/testFixtures/src/main/resources/show.csv-spec
  69. 22 0
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/Named.java
  70. 2 1
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/conditional/Greatest.java
  71. 3 2
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Abs.java
  72. 2 1
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Pow.java
  73. 28 21
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/show/ShowFunctions.java
  74. 120 0
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractFunctionTestCase.java
  75. 123 0
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/RailRoadDiagram.java

+ 7 - 0
docs/reference/esql/functions/abs.asciidoc

@@ -1,5 +1,8 @@
 [[esql-abs]]
 === `ABS`
+[.text-center]
+image::signature/abs.svg[]
+
 Returns the absolute value.
 
 [source,esql]
@@ -8,3 +11,7 @@ FROM employees
 | KEEP first_name, last_name, height
 | EVAL abs_height = ABS(0.0 - height)
 ----
+
+Supported types:
+
+include::types/abs.asciidoc[]

+ 7 - 0
docs/reference/esql/functions/cosh.asciidoc

@@ -1,5 +1,8 @@
 [[esql-cosh]]
 === `COSH`
+[.text-center]
+image::signature/cosh.svg[]
+
 https://en.wikipedia.org/wiki/Hyperbolic_functions[Cosine] hyperbolic function.
 
 [source.merge.styled,esql]
@@ -10,3 +13,7 @@ include::{esql-specs}/floats.csv-spec[tag=cosh]
 |===
 include::{esql-specs}/floats.csv-spec[tag=cosh-result]
 |===
+
+Supported types:
+
+include::types/cosh.asciidoc[]

+ 2 - 0
docs/reference/esql/functions/greatest.asciidoc

@@ -1,5 +1,7 @@
 [[esql-greatest]]
 === `GREATEST`
+[.text-center]
+image::signature/greatest.svg[]
 
 Returns the maximum value from many columns. This is similar to <<esql-mv_max>>
 except it's intended to run on multiple columns at once.

+ 4 - 29
docs/reference/esql/functions/pow.asciidoc

@@ -1,5 +1,8 @@
 [[esql-pow]]
 === `POW`
+[.text-center]
+image::signature/pow.svg[]
+
 Returns the value of a base (first argument) raised to the power of an exponent (second argument).
 Both arguments must be numeric.
 
@@ -85,32 +88,4 @@ include::{esql-specs}/math.csv-spec[tag=powID-sqrt-result]
 
 For clarity, the following table describes the output result type for all combinations of numeric input types:
 
-[cols="1,1,1"]
-|===
-|Base | Exponent | Result
-
-|double/float/half_float
-|*footnote:all[All numeric types]
-|double
-
-|*footnote:all[]
-|double/float/half_float
-|double
-
-|long/unsigned long
-|*footnote:all_but_float[All except double/float/half_float]
-|long
-
-|*footnote:all_but_float[]
-|long/unsigned long
-|long
-
-|*footnote:all_but_float_and_64[All except floating point and 64-bit types]
-|*footnote:all_but_float_and_64[]
-|int
-
-|*footnote:all_but_float_and_64[]
-|*footnote:all_but_float_and_64[]
-|int
-
-|===
+include::types/pow.asciidoc[]

+ 1 - 0
docs/reference/esql/functions/signature/abs.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="184" height="44" viewbox="0 0 184 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m59 0h10m27 0h10m31 0h10m27 0h5"/><rect class="s" x="5" y="5" width="59" height="34"/><text class="k" x="15" y="29">ABS</text><rect class="s" x="74" y="5" width="27" height="34" rx="7"/><text class="syn" x="84" y="29">(</text><rect class="s" x="111" y="5" width="31" height="34" rx="7"/><text class="k" x="121" y="29">n</text><rect class="s" x="152" y="5" width="27" height="34" rx="7"/><text class="syn" x="162" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/acos.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="230" height="44" viewbox="0 0 230 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m76 0h10m27 0h10m60 0h10m27 0h5"/><rect class="s" x="5" y="5" width="76" height="34"/><text class="k" x="15" y="29">ACOS</text><rect class="s" x="91" y="5" width="27" height="34" rx="7"/><text class="syn" x="101" y="29">(</text><rect class="s" x="128" y="5" width="60" height="34" rx="7"/><text class="k" x="138" y="29">arg1</text><rect class="s" x="198" y="5" width="27" height="34" rx="7"/><text class="syn" x="208" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/asin.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="220" height="44" viewbox="0 0 220 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m66 0h10m27 0h10m60 0h10m27 0h5"/><rect class="s" x="5" y="5" width="66" height="34"/><text class="k" x="15" y="29">ASIN</text><rect class="s" x="81" y="5" width="27" height="34" rx="7"/><text class="syn" x="91" y="29">(</text><rect class="s" x="118" y="5" width="60" height="34" rx="7"/><text class="k" x="128" y="29">arg1</text><rect class="s" x="188" y="5" width="27" height="34" rx="7"/><text class="syn" x="198" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/atan.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="226" height="44" viewbox="0 0 226 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m72 0h10m27 0h10m60 0h10m27 0h5"/><rect class="s" x="5" y="5" width="72" height="34"/><text class="k" x="15" y="29">ATAN</text><rect class="s" x="87" y="5" width="27" height="34" rx="7"/><text class="syn" x="97" y="29">(</text><rect class="s" x="124" y="5" width="60" height="34" rx="7"/><text class="k" x="134" y="29">arg1</text><rect class="s" x="194" y="5" width="27" height="34" rx="7"/><text class="syn" x="204" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/atan2.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="343" height="44" viewbox="0 0 343 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m83 0h10m27 0h10m60 0h10m26 0h10m60 0h10m27 0h5"/><rect class="s" x="5" y="5" width="83" height="34"/><text class="k" x="15" y="29">ATAN2</text><rect class="s" x="98" y="5" width="27" height="34" rx="7"/><text class="syn" x="108" y="29">(</text><rect class="s" x="135" y="5" width="60" height="34" rx="7"/><text class="k" x="145" y="29">arg1</text><rect class="s" x="205" y="5" width="26" height="34" rx="7"/><text class="syn" x="215" y="29">,</text><rect class="s" x="241" y="5" width="60" height="34" rx="7"/><text class="k" x="251" y="29">arg2</text><rect class="s" x="311" y="5" width="27" height="34" rx="7"/><text class="syn" x="321" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/case.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="413" height="74" viewbox="0 0 413 74"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 44h5m73 0h10m27 0h10m60 0h50m-5 0q-5 0-5-5v-24q0-5 5-5h106q5 0 5 5v24q0 5-5 5m-75 0h10m60 0h40m-171 0q5 0 5 5v10q0 5 5 5h146q5 0 5-5v-10q0-5 5-5m5 0h10m27 0h5"/><rect class="s" x="5" y="20" width="73" height="34"/><text class="k" x="15" y="44">CASE</text><rect class="s" x="88" y="20" width="27" height="34" rx="7"/><text class="syn" x="98" y="44">(</text><rect class="s" x="125" y="20" width="60" height="34" rx="7"/><text class="k" x="135" y="44">arg1</text><rect class="s" x="235" y="20" width="26" height="34" rx="7"/><text class="syn" x="245" y="44">,</text><rect class="s" x="271" y="20" width="60" height="34" rx="7"/><text class="k" x="281" y="44">arg2</text><rect class="s" x="381" y="20" width="27" height="34" rx="7"/><text class="syn" x="391" y="44">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/coalesce.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="467" height="74" viewbox="0 0 467 74"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 44h5m127 0h10m27 0h10m60 0h50m-5 0q-5 0-5-5v-24q0-5 5-5h106q5 0 5 5v24q0 5-5 5m-75 0h10m60 0h40m-171 0q5 0 5 5v10q0 5 5 5h146q5 0 5-5v-10q0-5 5-5m5 0h10m27 0h5"/><rect class="s" x="5" y="20" width="127" height="34"/><text class="k" x="15" y="44">COALESCE</text><rect class="s" x="142" y="20" width="27" height="34" rx="7"/><text class="syn" x="152" y="44">(</text><rect class="s" x="179" y="20" width="60" height="34" rx="7"/><text class="k" x="189" y="44">arg1</text><rect class="s" x="289" y="20" width="26" height="34" rx="7"/><text class="syn" x="299" y="44">,</text><rect class="s" x="325" y="20" width="60" height="34" rx="7"/><text class="k" x="335" y="44">arg2</text><rect class="s" x="435" y="20" width="27" height="34" rx="7"/><text class="syn" x="445" y="44">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/concat.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="443" height="74" viewbox="0 0 443 74"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 44h5m103 0h10m27 0h10m60 0h50m-5 0q-5 0-5-5v-24q0-5 5-5h106q5 0 5 5v24q0 5-5 5m-75 0h10m60 0h40m-171 0q5 0 5 5v10q0 5 5 5h146q5 0 5-5v-10q0-5 5-5m5 0h10m27 0h5"/><rect class="s" x="5" y="20" width="103" height="34"/><text class="k" x="15" y="44">CONCAT</text><rect class="s" x="118" y="20" width="27" height="34" rx="7"/><text class="syn" x="128" y="44">(</text><rect class="s" x="155" y="20" width="60" height="34" rx="7"/><text class="k" x="165" y="44">arg1</text><rect class="s" x="265" y="20" width="26" height="34" rx="7"/><text class="syn" x="275" y="44">,</text><rect class="s" x="301" y="20" width="60" height="34" rx="7"/><text class="k" x="311" y="44">arg2</text><rect class="s" x="411" y="20" width="27" height="34" rx="7"/><text class="syn" x="421" y="44">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/cos.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="217" height="44" viewbox="0 0 217 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m63 0h10m27 0h10m60 0h10m27 0h5"/><rect class="s" x="5" y="5" width="63" height="34"/><text class="k" x="15" y="29">COS</text><rect class="s" x="78" y="5" width="27" height="34" rx="7"/><text class="syn" x="88" y="29">(</text><rect class="s" x="115" y="5" width="60" height="34" rx="7"/><text class="k" x="125" y="29">arg1</text><rect class="s" x="185" y="5" width="27" height="34" rx="7"/><text class="syn" x="195" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/cosh.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="231" height="44" viewbox="0 0 231 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m77 0h10m27 0h10m60 0h10m27 0h5"/><rect class="s" x="5" y="5" width="77" height="34"/><text class="k" x="15" y="29">COSH</text><rect class="s" x="92" y="5" width="27" height="34" rx="7"/><text class="syn" x="102" y="29">(</text><rect class="s" x="129" y="5" width="60" height="34" rx="7"/><text class="k" x="139" y="29">arg1</text><rect class="s" x="199" y="5" width="27" height="34" rx="7"/><text class="syn" x="209" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/e.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="117" height="44" viewbox="0 0 117 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m33 0h10m27 0h10m27 0h5"/><rect class="s" x="5" y="5" width="33" height="34"/><text class="k" x="15" y="29">E</text><rect class="s" x="48" y="5" width="27" height="34" rx="7"/><text class="syn" x="58" y="29">(</text><rect class="s" x="85" y="5" width="27" height="34" rx="7"/><text class="syn" x="95" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/floor.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="243" height="44" viewbox="0 0 243 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m89 0h10m27 0h10m60 0h10m27 0h5"/><rect class="s" x="5" y="5" width="89" height="34"/><text class="k" x="15" y="29">FLOOR</text><rect class="s" x="104" y="5" width="27" height="34" rx="7"/><text class="syn" x="114" y="29">(</text><rect class="s" x="141" y="5" width="60" height="34" rx="7"/><text class="k" x="151" y="29">arg1</text><rect class="s" x="211" y="5" width="27" height="34" rx="7"/><text class="syn" x="221" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/greatest.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="453" height="74" viewbox="0 0 453 74"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 44h5m126 0h10m27 0h10m53 0h50m-5 0q-5 0-5-5v-24q0-5 5-5h100q5 0 5 5v24q0 5-5 5m-69 0h10m54 0h40m-165 0q5 0 5 5v10q0 5 5 5h140q5 0 5-5v-10q0-5 5-5m5 0h10m27 0h5"/><rect class="s" x="5" y="20" width="126" height="34"/><text class="k" x="15" y="44">GREATEST</text><rect class="s" x="141" y="20" width="27" height="34" rx="7"/><text class="syn" x="151" y="44">(</text><rect class="s" x="178" y="20" width="53" height="34" rx="7"/><text class="k" x="188" y="44">first</text><rect class="s" x="281" y="20" width="26" height="34" rx="7"/><text class="syn" x="291" y="44">,</text><rect class="s" x="317" y="20" width="54" height="34" rx="7"/><text class="k" x="327" y="44">rest</text><rect class="s" x="421" y="20" width="27" height="34" rx="7"/><text class="syn" x="431" y="44">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/least.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="422" height="74" viewbox="0 0 422 74"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 44h5m82 0h10m27 0h10m60 0h50m-5 0q-5 0-5-5v-24q0-5 5-5h106q5 0 5 5v24q0 5-5 5m-75 0h10m60 0h40m-171 0q5 0 5 5v10q0 5 5 5h146q5 0 5-5v-10q0-5 5-5m5 0h10m27 0h5"/><rect class="s" x="5" y="20" width="82" height="34"/><text class="k" x="15" y="44">LEAST</text><rect class="s" x="97" y="20" width="27" height="34" rx="7"/><text class="syn" x="107" y="44">(</text><rect class="s" x="134" y="20" width="60" height="34" rx="7"/><text class="k" x="144" y="44">arg1</text><rect class="s" x="244" y="20" width="26" height="34" rx="7"/><text class="syn" x="254" y="44">,</text><rect class="s" x="280" y="20" width="60" height="34" rx="7"/><text class="k" x="290" y="44">arg2</text><rect class="s" x="390" y="20" width="27" height="34" rx="7"/><text class="syn" x="400" y="44">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/length.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="254" height="44" viewbox="0 0 254 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m100 0h10m27 0h10m60 0h10m27 0h5"/><rect class="s" x="5" y="5" width="100" height="34"/><text class="k" x="15" y="29">LENGTH</text><rect class="s" x="115" y="5" width="27" height="34" rx="7"/><text class="syn" x="125" y="29">(</text><rect class="s" x="152" y="5" width="60" height="34" rx="7"/><text class="k" x="162" y="29">arg1</text><rect class="s" x="222" y="5" width="27" height="34" rx="7"/><text class="syn" x="232" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/log10.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="239" height="44" viewbox="0 0 239 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m85 0h10m27 0h10m60 0h10m27 0h5"/><rect class="s" x="5" y="5" width="85" height="34"/><text class="k" x="15" y="29">LOG10</text><rect class="s" x="100" y="5" width="27" height="34" rx="7"/><text class="syn" x="110" y="29">(</text><rect class="s" x="137" y="5" width="60" height="34" rx="7"/><text class="k" x="147" y="29">arg1</text><rect class="s" x="207" y="5" width="27" height="34" rx="7"/><text class="syn" x="217" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/ltrim.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="234" height="44" viewbox="0 0 234 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m80 0h10m27 0h10m60 0h10m27 0h5"/><rect class="s" x="5" y="5" width="80" height="34"/><text class="k" x="15" y="29">LTRIM</text><rect class="s" x="95" y="5" width="27" height="34" rx="7"/><text class="syn" x="105" y="29">(</text><rect class="s" x="132" y="5" width="60" height="34" rx="7"/><text class="k" x="142" y="29">arg1</text><rect class="s" x="202" y="5" width="27" height="34" rx="7"/><text class="syn" x="212" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/pi.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="123" height="44" viewbox="0 0 123 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m39 0h10m27 0h10m27 0h5"/><rect class="s" x="5" y="5" width="39" height="34"/><text class="k" x="15" y="29">PI</text><rect class="s" x="54" y="5" width="27" height="34" rx="7"/><text class="syn" x="64" y="29">(</text><rect class="s" x="91" y="5" width="27" height="34" rx="7"/><text class="syn" x="101" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/pow.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="373" height="44" viewbox="0 0 373 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m68 0h10m27 0h10m63 0h10m26 0h10m102 0h10m27 0h5"/><rect class="s" x="5" y="5" width="68" height="34"/><text class="k" x="15" y="29">POW</text><rect class="s" x="83" y="5" width="27" height="34" rx="7"/><text class="syn" x="93" y="29">(</text><rect class="s" x="120" y="5" width="63" height="34" rx="7"/><text class="k" x="130" y="29">base</text><rect class="s" x="193" y="5" width="26" height="34" rx="7"/><text class="syn" x="203" y="29">,</text><rect class="s" x="229" y="5" width="102" height="34" rx="7"/><text class="k" x="239" y="29">exponent</text><rect class="s" x="341" y="5" width="27" height="34" rx="7"/><text class="syn" x="351" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/round.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="352" height="44" viewbox="0 0 352 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m92 0h10m27 0h10m60 0h10m26 0h10m60 0h10m27 0h5"/><rect class="s" x="5" y="5" width="92" height="34"/><text class="k" x="15" y="29">ROUND</text><rect class="s" x="107" y="5" width="27" height="34" rx="7"/><text class="syn" x="117" y="29">(</text><rect class="s" x="144" y="5" width="60" height="34" rx="7"/><text class="k" x="154" y="29">arg1</text><rect class="s" x="214" y="5" width="26" height="34" rx="7"/><text class="syn" x="224" y="29">,</text><rect class="s" x="250" y="5" width="60" height="34" rx="7"/><text class="k" x="260" y="29">arg2</text><rect class="s" x="320" y="5" width="27" height="34" rx="7"/><text class="syn" x="330" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/rtrim.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="237" height="44" viewbox="0 0 237 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m83 0h10m27 0h10m60 0h10m27 0h5"/><rect class="s" x="5" y="5" width="83" height="34"/><text class="k" x="15" y="29">RTRIM</text><rect class="s" x="98" y="5" width="27" height="34" rx="7"/><text class="syn" x="108" y="29">(</text><rect class="s" x="135" y="5" width="60" height="34" rx="7"/><text class="k" x="145" y="29">arg1</text><rect class="s" x="205" y="5" width="27" height="34" rx="7"/><text class="syn" x="215" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/sin.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="207" height="44" viewbox="0 0 207 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m53 0h10m27 0h10m60 0h10m27 0h5"/><rect class="s" x="5" y="5" width="53" height="34"/><text class="k" x="15" y="29">SIN</text><rect class="s" x="68" y="5" width="27" height="34" rx="7"/><text class="syn" x="78" y="29">(</text><rect class="s" x="105" y="5" width="60" height="34" rx="7"/><text class="k" x="115" y="29">arg1</text><rect class="s" x="175" y="5" width="27" height="34" rx="7"/><text class="syn" x="185" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/sinh.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="221" height="44" viewbox="0 0 221 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m67 0h10m27 0h10m60 0h10m27 0h5"/><rect class="s" x="5" y="5" width="67" height="34"/><text class="k" x="15" y="29">SINH</text><rect class="s" x="82" y="5" width="27" height="34" rx="7"/><text class="syn" x="92" y="29">(</text><rect class="s" x="119" y="5" width="60" height="34" rx="7"/><text class="k" x="129" y="29">arg1</text><rect class="s" x="189" y="5" width="27" height="34" rx="7"/><text class="syn" x="199" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/split.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="335" height="44" viewbox="0 0 335 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m75 0h10m27 0h10m60 0h10m26 0h10m60 0h10m27 0h5"/><rect class="s" x="5" y="5" width="75" height="34"/><text class="k" x="15" y="29">SPLIT</text><rect class="s" x="90" y="5" width="27" height="34" rx="7"/><text class="syn" x="100" y="29">(</text><rect class="s" x="127" y="5" width="60" height="34" rx="7"/><text class="k" x="137" y="29">arg1</text><rect class="s" x="197" y="5" width="26" height="34" rx="7"/><text class="syn" x="207" y="29">,</text><rect class="s" x="233" y="5" width="60" height="34" rx="7"/><text class="k" x="243" y="29">arg2</text><rect class="s" x="303" y="5" width="27" height="34" rx="7"/><text class="syn" x="313" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/sqrt.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="229" height="44" viewbox="0 0 229 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m75 0h10m27 0h10m60 0h10m27 0h5"/><rect class="s" x="5" y="5" width="75" height="34"/><text class="k" x="15" y="29">SQRT</text><rect class="s" x="90" y="5" width="27" height="34" rx="7"/><text class="syn" x="100" y="29">(</text><rect class="s" x="127" y="5" width="60" height="34" rx="7"/><text class="k" x="137" y="29">arg1</text><rect class="s" x="197" y="5" width="27" height="34" rx="7"/><text class="syn" x="207" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/substring.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="501" height="44" viewbox="0 0 501 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m135 0h10m27 0h10m60 0h10m26 0h10m60 0h10m26 0h10m60 0h10m27 0h5"/><rect class="s" x="5" y="5" width="135" height="34"/><text class="k" x="15" y="29">SUBSTRING</text><rect class="s" x="150" y="5" width="27" height="34" rx="7"/><text class="syn" x="160" y="29">(</text><rect class="s" x="187" y="5" width="60" height="34" rx="7"/><text class="k" x="197" y="29">arg1</text><rect class="s" x="257" y="5" width="26" height="34" rx="7"/><text class="syn" x="267" y="29">,</text><rect class="s" x="293" y="5" width="60" height="34" rx="7"/><text class="k" x="303" y="29">arg2</text><rect class="s" x="363" y="5" width="26" height="34" rx="7"/><text class="syn" x="373" y="29">,</text><rect class="s" x="399" y="5" width="60" height="34" rx="7"/><text class="k" x="409" y="29">arg3</text><rect class="s" x="469" y="5" width="27" height="34" rx="7"/><text class="syn" x="479" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/tan.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="213" height="44" viewbox="0 0 213 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m59 0h10m27 0h10m60 0h10m27 0h5"/><rect class="s" x="5" y="5" width="59" height="34"/><text class="k" x="15" y="29">TAN</text><rect class="s" x="74" y="5" width="27" height="34" rx="7"/><text class="syn" x="84" y="29">(</text><rect class="s" x="111" y="5" width="60" height="34" rx="7"/><text class="k" x="121" y="29">arg1</text><rect class="s" x="181" y="5" width="27" height="34" rx="7"/><text class="syn" x="191" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/tanh.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="227" height="44" viewbox="0 0 227 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m73 0h10m27 0h10m60 0h10m27 0h5"/><rect class="s" x="5" y="5" width="73" height="34"/><text class="k" x="15" y="29">TANH</text><rect class="s" x="88" y="5" width="27" height="34" rx="7"/><text class="syn" x="98" y="29">(</text><rect class="s" x="125" y="5" width="60" height="34" rx="7"/><text class="k" x="135" y="29">arg1</text><rect class="s" x="195" y="5" width="27" height="34" rx="7"/><text class="syn" x="205" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/tau.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="143" height="44" viewbox="0 0 143 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m59 0h10m27 0h10m27 0h5"/><rect class="s" x="5" y="5" width="59" height="34"/><text class="k" x="15" y="29">TAU</text><rect class="s" x="74" y="5" width="27" height="34" rx="7"/><text class="syn" x="84" y="29">(</text><rect class="s" x="111" y="5" width="27" height="34" rx="7"/><text class="syn" x="121" y="29">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/trim.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="223" height="44" viewbox="0 0 223 44"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family:Dialog,Sans-serif;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family:Dialog,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 29h5m69 0h10m27 0h10m60 0h10m27 0h5"/><rect class="s" x="5" y="5" width="69" height="34"/><text class="k" x="15" y="29">TRIM</text><rect class="s" x="84" y="5" width="27" height="34" rx="7"/><text class="syn" x="94" y="29">(</text><rect class="s" x="121" y="5" width="60" height="34" rx="7"/><text class="k" x="131" y="29">arg1</text><rect class="s" x="191" y="5" width="27" height="34" rx="7"/><text class="syn" x="201" y="29">)</text></svg>

+ 8 - 0
docs/reference/esql/functions/types/abs.asciidoc

@@ -0,0 +1,8 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+n | result
+double | double
+integer | integer
+long | long
+unsigned_long | unsigned_long
+|===

+ 8 - 0
docs/reference/esql/functions/types/acos.asciidoc

@@ -0,0 +1,8 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | result
+double | double
+integer | double
+long | double
+unsigned_long | double
+|===

+ 8 - 0
docs/reference/esql/functions/types/asin.asciidoc

@@ -0,0 +1,8 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | result
+double | double
+integer | double
+long | double
+unsigned_long | double
+|===

+ 8 - 0
docs/reference/esql/functions/types/atan.asciidoc

@@ -0,0 +1,8 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | result
+double | double
+integer | double
+long | double
+unsigned_long | double
+|===

+ 20 - 0
docs/reference/esql/functions/types/atan2.asciidoc

@@ -0,0 +1,20 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | arg2 | result
+double | double | double
+double | integer | double
+double | long | double
+double | unsigned_long | double
+integer | double | double
+integer | integer | double
+integer | long | double
+integer | unsigned_long | double
+long | double | double
+long | integer | double
+long | long | double
+long | unsigned_long | double
+unsigned_long | double | double
+unsigned_long | integer | double
+unsigned_long | long | double
+unsigned_long | unsigned_long | double
+|===

+ 5 - 0
docs/reference/esql/functions/types/case.asciidoc

@@ -0,0 +1,5 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | arg2... | result
+boolean | keyword | keyword | keyword
+|===

+ 49 - 0
docs/reference/esql/functions/types/coalesce.asciidoc

@@ -0,0 +1,49 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | arg2... | result
+boolean | boolean
+boolean | boolean | boolean
+boolean | boolean | boolean | boolean
+boolean | boolean | boolean | boolean | boolean
+boolean | boolean | boolean | boolean | boolean | boolean
+boolean | boolean | boolean | boolean | boolean | boolean | boolean
+boolean | boolean | boolean | boolean | boolean | boolean | boolean | boolean
+boolean | boolean | boolean | boolean | boolean | boolean | boolean | boolean | boolean
+boolean | boolean | boolean | boolean | boolean | boolean | boolean | boolean | boolean | boolean
+integer | integer
+integer | integer | integer
+integer | integer | integer | integer
+integer | integer | integer | integer | integer
+integer | integer | integer | integer | integer | integer
+integer | integer | integer | integer | integer | integer | integer
+integer | integer | integer | integer | integer | integer | integer | integer
+integer | integer | integer | integer | integer | integer | integer | integer | integer
+integer | integer | integer | integer | integer | integer | integer | integer | integer | integer
+keyword | keyword
+keyword | keyword | keyword
+keyword | keyword | keyword | keyword
+keyword | keyword | keyword | keyword | keyword
+keyword | keyword | keyword | keyword | keyword | keyword
+keyword | keyword | keyword | keyword | keyword | keyword | keyword
+keyword | keyword | keyword | keyword | keyword | keyword | keyword | keyword
+keyword | keyword | keyword | keyword | keyword | keyword | keyword | keyword | keyword
+keyword | keyword | keyword | keyword | keyword | keyword | keyword | keyword | keyword | keyword
+long | long
+long | long | long
+long | long | long | long
+long | long | long | long | long
+long | long | long | long | long | long
+long | long | long | long | long | long | long
+long | long | long | long | long | long | long | long
+long | long | long | long | long | long | long | long | long
+long | long | long | long | long | long | long | long | long | long
+text | text
+text | text | text
+text | text | text | text
+text | text | text | text | text
+text | text | text | text | text | text
+text | text | text | text | text | text | text
+text | text | text | text | text | text | text | text
+text | text | text | text | text | text | text | text | text
+text | text | text | text | text | text | text | text | text | text
+|===

+ 5 - 0
docs/reference/esql/functions/types/concat.asciidoc

@@ -0,0 +1,5 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | arg2... | result
+keyword | keyword | keyword
+|===

+ 8 - 0
docs/reference/esql/functions/types/cos.asciidoc

@@ -0,0 +1,8 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | result
+double | double
+integer | double
+long | double
+unsigned_long | double
+|===

+ 8 - 0
docs/reference/esql/functions/types/cosh.asciidoc

@@ -0,0 +1,8 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | result
+double | double
+integer | double
+long | double
+unsigned_long | double
+|===

+ 5 - 0
docs/reference/esql/functions/types/e.asciidoc

@@ -0,0 +1,5 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+result
+integer | double
+|===

+ 5 - 0
docs/reference/esql/functions/types/floor.asciidoc

@@ -0,0 +1,5 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | result
+double | double
+|===

+ 49 - 0
docs/reference/esql/functions/types/greatest.asciidoc

@@ -0,0 +1,49 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+first | rest... | result
+boolean | boolean
+boolean | boolean | boolean
+boolean | boolean | boolean | boolean
+boolean | boolean | boolean | boolean | boolean
+boolean | boolean | boolean | boolean | boolean | boolean
+boolean | boolean | boolean | boolean | boolean | boolean | boolean
+boolean | boolean | boolean | boolean | boolean | boolean | boolean | boolean
+boolean | boolean | boolean | boolean | boolean | boolean | boolean | boolean | boolean
+boolean | boolean | boolean | boolean | boolean | boolean | boolean | boolean | boolean | boolean
+integer | integer
+integer | integer | integer
+integer | integer | integer | integer
+integer | integer | integer | integer | integer
+integer | integer | integer | integer | integer | integer
+integer | integer | integer | integer | integer | integer | integer
+integer | integer | integer | integer | integer | integer | integer | integer
+integer | integer | integer | integer | integer | integer | integer | integer | integer
+integer | integer | integer | integer | integer | integer | integer | integer | integer | integer
+keyword | keyword
+keyword | keyword | keyword
+keyword | keyword | keyword | keyword
+keyword | keyword | keyword | keyword | keyword
+keyword | keyword | keyword | keyword | keyword | keyword
+keyword | keyword | keyword | keyword | keyword | keyword | keyword
+keyword | keyword | keyword | keyword | keyword | keyword | keyword | keyword
+keyword | keyword | keyword | keyword | keyword | keyword | keyword | keyword | keyword
+keyword | keyword | keyword | keyword | keyword | keyword | keyword | keyword | keyword | keyword
+long | long
+long | long | long
+long | long | long | long
+long | long | long | long | long
+long | long | long | long | long | long
+long | long | long | long | long | long | long
+long | long | long | long | long | long | long | long
+long | long | long | long | long | long | long | long | long
+long | long | long | long | long | long | long | long | long | long
+text | text
+text | text | text
+text | text | text | text
+text | text | text | text | text
+text | text | text | text | text | text
+text | text | text | text | text | text | text
+text | text | text | text | text | text | text | text
+text | text | text | text | text | text | text | text | text
+text | text | text | text | text | text | text | text | text | text
+|===

+ 49 - 0
docs/reference/esql/functions/types/least.asciidoc

@@ -0,0 +1,49 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | arg2... | result
+boolean | boolean
+boolean | boolean | boolean
+boolean | boolean | boolean | boolean
+boolean | boolean | boolean | boolean | boolean
+boolean | boolean | boolean | boolean | boolean | boolean
+boolean | boolean | boolean | boolean | boolean | boolean | boolean
+boolean | boolean | boolean | boolean | boolean | boolean | boolean | boolean
+boolean | boolean | boolean | boolean | boolean | boolean | boolean | boolean | boolean
+boolean | boolean | boolean | boolean | boolean | boolean | boolean | boolean | boolean | boolean
+integer | integer
+integer | integer | integer
+integer | integer | integer | integer
+integer | integer | integer | integer | integer
+integer | integer | integer | integer | integer | integer
+integer | integer | integer | integer | integer | integer | integer
+integer | integer | integer | integer | integer | integer | integer | integer
+integer | integer | integer | integer | integer | integer | integer | integer | integer
+integer | integer | integer | integer | integer | integer | integer | integer | integer | integer
+keyword | keyword
+keyword | keyword | keyword
+keyword | keyword | keyword | keyword
+keyword | keyword | keyword | keyword | keyword
+keyword | keyword | keyword | keyword | keyword | keyword
+keyword | keyword | keyword | keyword | keyword | keyword | keyword
+keyword | keyword | keyword | keyword | keyword | keyword | keyword | keyword
+keyword | keyword | keyword | keyword | keyword | keyword | keyword | keyword | keyword
+keyword | keyword | keyword | keyword | keyword | keyword | keyword | keyword | keyword | keyword
+long | long
+long | long | long
+long | long | long | long
+long | long | long | long | long
+long | long | long | long | long | long
+long | long | long | long | long | long | long
+long | long | long | long | long | long | long | long
+long | long | long | long | long | long | long | long | long
+long | long | long | long | long | long | long | long | long | long
+text | text
+text | text | text
+text | text | text | text
+text | text | text | text | text
+text | text | text | text | text | text
+text | text | text | text | text | text | text
+text | text | text | text | text | text | text | text
+text | text | text | text | text | text | text | text | text
+text | text | text | text | text | text | text | text | text | text
+|===

+ 5 - 0
docs/reference/esql/functions/types/length.asciidoc

@@ -0,0 +1,5 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | result
+keyword | integer
+|===

+ 5 - 0
docs/reference/esql/functions/types/log10.asciidoc

@@ -0,0 +1,5 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | result
+double | double
+|===

+ 6 - 0
docs/reference/esql/functions/types/ltrim.asciidoc

@@ -0,0 +1,6 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | result
+keyword | keyword
+text | text
+|===

+ 5 - 0
docs/reference/esql/functions/types/pi.asciidoc

@@ -0,0 +1,5 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+result
+integer | double
+|===

+ 10 - 0
docs/reference/esql/functions/types/pow.asciidoc

@@ -0,0 +1,10 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+base | exponent | result
+double | double | double
+double | integer | double
+integer | double | double
+integer | integer | integer
+long | double | double
+long | integer | long
+|===

+ 5 - 0
docs/reference/esql/functions/types/round.asciidoc

@@ -0,0 +1,5 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | arg2 | result
+double | integer | double
+|===

+ 6 - 0
docs/reference/esql/functions/types/rtrim.asciidoc

@@ -0,0 +1,6 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | result
+keyword | keyword
+text | text
+|===

+ 8 - 0
docs/reference/esql/functions/types/sin.asciidoc

@@ -0,0 +1,8 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | result
+double | double
+integer | double
+long | double
+unsigned_long | double
+|===

+ 8 - 0
docs/reference/esql/functions/types/sinh.asciidoc

@@ -0,0 +1,8 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | result
+double | double
+integer | double
+long | double
+unsigned_long | double
+|===

+ 5 - 0
docs/reference/esql/functions/types/split.asciidoc

@@ -0,0 +1,5 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | arg2 | result
+keyword | keyword | keyword
+|===

+ 5 - 0
docs/reference/esql/functions/types/sqrt.asciidoc

@@ -0,0 +1,5 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | result
+double | double
+|===

+ 5 - 0
docs/reference/esql/functions/types/substring.asciidoc

@@ -0,0 +1,5 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | arg2 | arg3 | result
+keyword | integer | integer | keyword
+|===

+ 8 - 0
docs/reference/esql/functions/types/tan.asciidoc

@@ -0,0 +1,8 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | result
+double | double
+integer | double
+long | double
+unsigned_long | double
+|===

+ 8 - 0
docs/reference/esql/functions/types/tanh.asciidoc

@@ -0,0 +1,8 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | result
+double | double
+integer | double
+long | double
+unsigned_long | double
+|===

+ 5 - 0
docs/reference/esql/functions/types/tau.asciidoc

@@ -0,0 +1,5 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+result
+integer | double
+|===

+ 6 - 0
docs/reference/esql/functions/types/trim.asciidoc

@@ -0,0 +1,6 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+arg1 | result
+keyword | keyword
+text | text
+|===

+ 5 - 0
gradle/verification-metadata.xml

@@ -1529,6 +1529,11 @@
             <sha256 value="64072f56d9dff5040b2acec477c5d5e6bcebfc88c508f12acb26072d07942146" origin="Generated by Gradle"/>
          </artifact>
       </component>
+      <component group="net.nextencia" name="rrdiagram" version="0.9.4">
+         <artifact name="rrdiagram-0.9.4.jar">
+            <sha256 value="8f0855addca5320cfadedbf7d3d46b681f3f308b6e87d5d82f32637ba72256b6" origin="Generated by Gradle"/>
+         </artifact>
+      </component>
       <component group="net.sf.ehcache" name="ehcache" version="2.10.4">
          <artifact name="ehcache-2.10.4.jar">
             <sha256 value="32efe00173a887743c614aa625588247fa40edaa56ed8a36ca7d0231cad82468" origin="Generated by Gradle"/>

+ 20 - 0
x-pack/plugin/esql/build.gradle

@@ -30,6 +30,7 @@ dependencies {
   testImplementation project(path: ':modules:reindex')
   testImplementation project(path: ':modules:parent-join')
   testImplementation project(path: ':modules:analysis-common')
+  testImplementation('net.nextencia:rrdiagram:0.9.4')
 
   internalClusterTestImplementation project(":client:rest-high-level")
 }
@@ -53,6 +54,25 @@ sourceSets.main.java {
   exclude 'generated/**'
 }
 
+tasks.getByName('test') {
+  dependsOn 'cleanGeneratedDocs'
+  finalizedBy 'copyGeneratedDocs'
+}
+
+tasks.register('cleanGeneratedDocs', Delete) {
+  delete "${projectDir}/build/testrun/test/temp/esql/functions"
+}
+
+tasks.register('copyGeneratedDocs', Sync) {
+  dependsOn 'test'
+  from "${projectDir}/build/testrun/test/temp/esql/functions"
+  into "${rootDir}/docs/reference/esql/functions"
+  include '**/*.asciidoc', '**/*.svg'
+  preserve {
+    include '/*.asciidoc'
+  }
+}
+
 /****************************************************************
  *  Enable QA/rest integration tests for snapshot builds only   *
  *  TODO: Enable for all builds upon this feature release       *

+ 6 - 1
x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/ConsumeProcessor.java

@@ -34,7 +34,12 @@ public class ConsumeProcessor implements Processor {
 
     @Override
     public Set<String> getSupportedAnnotationTypes() {
-        return Set.of("org.elasticsearch.core.Nullable", "org.elasticsearch.common.inject.Inject", Fixed.class.getName());
+        return Set.of(
+            "org.elasticsearch.core.Nullable",
+            "org.elasticsearch.common.inject.Inject",
+            "org.elasticsearch.xpack.esql.expression.function.Named",
+            Fixed.class.getName()
+        );
     }
 
     @Override

+ 3 - 3
x-pack/plugin/esql/qa/testFixtures/src/main/resources/show.csv-spec

@@ -9,7 +9,7 @@ showFunctions
 show functions;
 
   name:keyword           |           synopsis:keyword
-abs                      |abs(arg1)
+abs                      |abs(n)
 acos                     |acos(arg1)
 asin                     |asin(arg1)
 atan                     |atan(arg1)
@@ -30,7 +30,7 @@ date_parse               |date_parse(arg1, arg2)
 date_trunc               |date_trunc(arg1, arg2)
 e                        |e()
 floor                    |floor(arg1)
-greatest                 |greatest(arg1, arg2...)
+greatest                 |greatest(first, rest...)
 is_finite                |is_finite(arg1)
 is_infinite              |is_infinite(arg1)
 is_nan                   |is_nan(arg1)
@@ -53,7 +53,7 @@ mv_sum                   |mv_sum(arg1)
 now                      |now()
 percentile               |percentile(arg1, arg2)
 pi                       |pi()
-pow                      |pow(arg1, arg2)
+pow                      |pow(base, exponent)
 round                    |round(arg1, arg2)
 rtrim                    |rtrim(arg1)
 sin                      |sin(arg1)

+ 22 - 0
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/Named.java

@@ -0,0 +1,22 @@
+/*
+ * 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.esql.expression.function;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Names function parameters.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.PARAMETER)
+public @interface Named {
+    String value();
+}

+ 2 - 1
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/conditional/Greatest.java

@@ -12,6 +12,7 @@ import org.elasticsearch.compute.ann.Evaluator;
 import org.elasticsearch.compute.operator.EvalOperator;
 import org.elasticsearch.xpack.esql.EsqlIllegalArgumentException;
 import org.elasticsearch.xpack.esql.evaluator.mapper.EvaluatorMapper;
+import org.elasticsearch.xpack.esql.expression.function.Named;
 import org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.MvMaxBooleanEvaluator;
 import org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.MvMaxBytesRefEvaluator;
 import org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.MvMaxDoubleEvaluator;
@@ -41,7 +42,7 @@ import static org.elasticsearch.xpack.ql.type.DataTypes.NULL;
 public class Greatest extends ScalarFunction implements EvaluatorMapper, OptionalArgument {
     private DataType dataType;
 
-    public Greatest(Source source, Expression first, List<Expression> rest) {
+    public Greatest(Source source, @Named("first") Expression first, @Named("rest") List<Expression> rest) {
         super(source, Stream.concat(Stream.of(first), rest.stream()).toList());
     }
 

+ 3 - 2
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Abs.java

@@ -11,6 +11,7 @@ import org.elasticsearch.compute.ann.Evaluator;
 import org.elasticsearch.compute.operator.EvalOperator;
 import org.elasticsearch.xpack.esql.EsqlUnsupportedOperationException;
 import org.elasticsearch.xpack.esql.evaluator.mapper.EvaluatorMapper;
+import org.elasticsearch.xpack.esql.expression.function.Named;
 import org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction;
 import org.elasticsearch.xpack.ql.expression.Expression;
 import org.elasticsearch.xpack.ql.tree.NodeInfo;
@@ -22,8 +23,8 @@ import java.util.function.Function;
 import java.util.function.Supplier;
 
 public class Abs extends UnaryScalarFunction implements EvaluatorMapper {
-    public Abs(Source source, Expression field) {
-        super(source, field);
+    public Abs(Source source, @Named("n") Expression n) {
+        super(source, n);
     }
 
     @Override

+ 2 - 1
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Pow.java

@@ -11,6 +11,7 @@ import org.elasticsearch.compute.ann.Evaluator;
 import org.elasticsearch.compute.operator.EvalOperator;
 import org.elasticsearch.xpack.esql.EsqlUnsupportedOperationException;
 import org.elasticsearch.xpack.esql.evaluator.mapper.EvaluatorMapper;
+import org.elasticsearch.xpack.esql.expression.function.Named;
 import org.elasticsearch.xpack.ql.expression.Expression;
 import org.elasticsearch.xpack.ql.expression.function.OptionalArgument;
 import org.elasticsearch.xpack.ql.expression.function.scalar.ScalarFunction;
@@ -36,7 +37,7 @@ public class Pow extends ScalarFunction implements OptionalArgument, EvaluatorMa
     private final Expression base, exponent;
     private final DataType dataType;
 
-    public Pow(Source source, Expression base, Expression exponent) {
+    public Pow(Source source, @Named("base") Expression base, @Named("exponent") Expression exponent) {
         super(source, Arrays.asList(base, exponent));
         this.base = base;
         this.exponent = exponent;

+ 28 - 21
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/show/ShowFunctions.java

@@ -9,8 +9,10 @@ package org.elasticsearch.xpack.esql.plan.logical.show;
 
 import org.apache.lucene.util.BytesRef;
 import org.elasticsearch.common.Strings;
+import org.elasticsearch.xpack.esql.expression.function.Named;
 import org.elasticsearch.xpack.ql.expression.Attribute;
 import org.elasticsearch.xpack.ql.expression.ReferenceAttribute;
+import org.elasticsearch.xpack.ql.expression.function.FunctionDefinition;
 import org.elasticsearch.xpack.ql.expression.function.FunctionRegistry;
 import org.elasticsearch.xpack.ql.plan.logical.LeafPlan;
 import org.elasticsearch.xpack.ql.plan.logical.LogicalPlan;
@@ -21,6 +23,7 @@ import org.elasticsearch.xpack.ql.tree.Source;
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import static org.elasticsearch.xpack.ql.type.DataTypes.KEYWORD;
 
@@ -47,33 +50,37 @@ public class ShowFunctions extends LeafPlan {
         for (var def : functionRegistry.listFunctions(null)) {
             List<Object> row = new ArrayList<>();
             row.add(asBytesRefOrNull(def.name()));
-
-            var constructors = def.clazz().getConstructors();
-            StringBuilder sb = new StringBuilder(def.name());
-            sb.append('(');
-            if (constructors.length > 0) {
-                var params = constructors[0].getParameters(); // no multiple c'tors supported
-                for (int i = 1; i < params.length; i++) { // skipping 1st argument, the source
-                    if (Configuration.class.isAssignableFrom(params[i].getType()) == false) {
-                        if (i > 1) {
-                            sb.append(", ");
-                        }
-                        sb.append(params[i].getName());
-                        if (List.class.isAssignableFrom(params[i].getType())) {
-                            sb.append("...");
-                        }
-                    }
-                }
-            }
-            sb.append(')');
-            row.add(asBytesRefOrNull(sb.toString()));
-
+            row.add(new BytesRef(def.name() + "(" + signature(def).stream().collect(Collectors.joining(", ")) + ")"));
             rows.add(row);
         }
         rows.sort(Comparator.comparing(x -> ((BytesRef) x.get(0))));
         return rows;
     }
 
+    /**
+     * Render the function's signature to a string.
+     */
+    public static List<String> signature(FunctionDefinition def) {
+        var constructors = def.clazz().getConstructors();
+        if (constructors.length == 0) {
+            return List.of();
+        }
+        var params = constructors[0].getParameters(); // no multiple c'tors supported
+        List<String> args = new ArrayList<>(params.length);
+        for (int i = 1; i < params.length; i++) { // skipping 1st argument, the source
+            if (Configuration.class.isAssignableFrom(params[i].getType()) == false) {
+                Named namedAnn = params[i].getAnnotation(Named.class);
+                String name = namedAnn == null ? params[i].getName() : namedAnn.value();
+
+                if (List.class.isAssignableFrom(params[i].getType())) {
+                    name = name + "...";
+                }
+                args.add(name);
+            }
+        }
+        return args;
+    }
+
     private static BytesRef asBytesRefOrNull(String string) {
         return Strings.hasText(string) ? new BytesRef(string) : null;
     }

+ 120 - 0
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractFunctionTestCase.java

@@ -14,17 +14,21 @@ import org.elasticsearch.compute.data.Block;
 import org.elasticsearch.compute.data.BlockUtils;
 import org.elasticsearch.compute.data.Page;
 import org.elasticsearch.compute.operator.EvalOperator;
+import org.elasticsearch.core.PathUtils;
+import org.elasticsearch.logging.LogManager;
 import org.elasticsearch.test.ESTestCase;
 import org.elasticsearch.xpack.esql.evaluator.EvalMapper;
 import org.elasticsearch.xpack.esql.expression.function.scalar.conditional.Greatest;
 import org.elasticsearch.xpack.esql.expression.function.scalar.nulls.Coalesce;
 import org.elasticsearch.xpack.esql.optimizer.FoldNull;
+import org.elasticsearch.xpack.esql.plan.logical.show.ShowFunctions;
 import org.elasticsearch.xpack.esql.planner.Layout;
 import org.elasticsearch.xpack.esql.type.EsqlDataTypes;
 import org.elasticsearch.xpack.ql.expression.Expression;
 import org.elasticsearch.xpack.ql.expression.FieldAttribute;
 import org.elasticsearch.xpack.ql.expression.Literal;
 import org.elasticsearch.xpack.ql.expression.TypeResolutions;
+import org.elasticsearch.xpack.ql.expression.function.FunctionDefinition;
 import org.elasticsearch.xpack.ql.tree.Source;
 import org.elasticsearch.xpack.ql.type.DataType;
 import org.elasticsearch.xpack.ql.type.DataTypes;
@@ -32,12 +36,20 @@ import org.elasticsearch.xpack.ql.type.EsField;
 import org.elasticsearch.xpack.ql.util.NumericUtils;
 import org.elasticsearch.xpack.versionfield.Version;
 import org.hamcrest.Matcher;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 
+import java.io.IOException;
 import java.math.BigInteger;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.time.Duration;
 import java.time.Period;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
@@ -624,6 +636,7 @@ public abstract class AbstractFunctionTestCase extends ESTestCase {
         }
 
         return suppliers;
+
     }
 
     /**
@@ -754,4 +767,111 @@ public abstract class AbstractFunctionTestCase extends ESTestCase {
     private static Stream<DataType> representable() {
         return EsqlDataTypes.types().stream().filter(EsqlDataTypes::isRepresentable);
     }
+
+    @AfterClass
+    public static void renderSignature() throws IOException {
+        FunctionDefinition definition = definition();
+        if (definition == null) {
+            LogManager.getLogger(getTestClass()).info("Skipping rendering signature because the function isn't registered");
+            return;
+        }
+
+        String rendered = RailRoadDiagram.functionSignature(definition);
+        LogManager.getLogger(getTestClass()).info("Writing function signature");
+        writeToTempDir("signature", rendered, "svg");
+    }
+
+    /**
+     * Unique signatures encountered by this test.
+     * <p>
+     *     We clear this at the beginning of the test class with
+     *     {@link #clearSignatures} out of paranoia. It <strong>is</strong>
+     *     shared by many tests, after all.
+     * </p>
+     * <p>
+     *     After each test method we add the signature it operated on via
+     *     {@link #trackSignature}. Once the test class is done we render
+     *     all the unique signatures to a temp file with {@link #renderTypesTable}.
+     *     We use a temp file because that's all we're allowed to write to.
+     *     Gradle will move the files into the docs after this is done.
+     * </p>
+     */
+    private static final Map<List<DataType>, DataType> signatures = new HashMap<>();
+
+    @BeforeClass
+    public static void clearSignatures() {
+        signatures.clear();
+    }
+
+    @After
+    public void trackSignature() {
+        if (testCase.expectedTypeError != null) {
+            return;
+        }
+        if (testCase.getData().stream().anyMatch(t -> t.type == DataTypes.NULL)) {
+            return;
+        }
+        signatures.putIfAbsent(testCase.getData().stream().map(TypedData::type).toList(), testCase.expectedType);
+    }
+
+    @AfterClass
+    public static void renderTypesTable() throws IOException {
+        FunctionDefinition definition = definition();
+        if (definition == null) {
+            LogManager.getLogger(getTestClass()).info("Skipping rendering types because the function isn't registered");
+            return;
+        }
+
+        StringBuilder header = new StringBuilder();
+        for (String arg : ShowFunctions.signature(definition)) {
+            header.append(arg).append(" | ");
+        }
+        header.append("result");
+
+        List<String> table = new ArrayList<>();
+        for (Map.Entry<List<DataType>, DataType> sig : signatures.entrySet()) {
+            StringBuilder b = new StringBuilder();
+            for (DataType arg : sig.getKey()) {
+                b.append(arg.typeName()).append(" | ");
+            }
+            b.append(sig.getValue().typeName());
+            table.add(b.toString());
+        }
+        Collections.sort(table);
+
+        String rendered = """
+            [%header.monospaced.styled,format=dsv,separator=|]
+            |===
+            """ + header + "\n" + table.stream().collect(Collectors.joining("\n")) + "\n|===\n";
+        LogManager.getLogger(getTestClass()).info("Writing function types:\n{}", rendered);
+        writeToTempDir("types", rendered, "asciidoc");
+    }
+
+    private static FunctionDefinition definition() {
+        String name = functionName();
+        EsqlFunctionRegistry registry = new EsqlFunctionRegistry();
+        if (registry.functionExists(name)) {
+            return registry.resolveFunction(name);
+        }
+        return null;
+    }
+
+    private static String functionName() {
+        return getTestClass().getSimpleName().replace("Tests", "").toLowerCase(Locale.ROOT);
+    }
+
+    /**
+     * Write some text to a tempdir so we can copy it to the docs later.
+     * <p>
+     *     We need to write to a tempdir instead of the docs because the tests
+     *     don't have write permission to the docs.
+     * </p>
+     */
+    private static void writeToTempDir(String subdir, String str, String extension) throws IOException {
+        // We have to write to a tempdir because it's all test are allowed to write to. Gradle can move them.
+        Path dir = PathUtils.get(System.getProperty("java.io.tmpdir")).resolve("esql").resolve("functions").resolve(subdir);
+        Files.createDirectories(dir);
+        Path file = dir.resolve(functionName() + "." + extension);
+        Files.writeString(file, str);
+    }
 }

+ 123 - 0
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/RailRoadDiagram.java

@@ -0,0 +1,123 @@
+/*
+ * 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.esql.expression.function;
+
+import net.nextencia.rrdiagram.grammar.model.Expression;
+import net.nextencia.rrdiagram.grammar.model.GrammarToRRDiagram;
+import net.nextencia.rrdiagram.grammar.model.Literal;
+import net.nextencia.rrdiagram.grammar.model.Repetition;
+import net.nextencia.rrdiagram.grammar.model.Rule;
+import net.nextencia.rrdiagram.grammar.model.Sequence;
+import net.nextencia.rrdiagram.grammar.model.SpecialSequence;
+import net.nextencia.rrdiagram.grammar.rrdiagram.RRDiagram;
+import net.nextencia.rrdiagram.grammar.rrdiagram.RRDiagramToSVG;
+import net.nextencia.rrdiagram.grammar.rrdiagram.RRElement;
+import net.nextencia.rrdiagram.grammar.rrdiagram.RRText;
+
+import org.elasticsearch.xpack.esql.plan.logical.show.ShowFunctions;
+import org.elasticsearch.xpack.ql.expression.function.FunctionDefinition;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Generates <a href="https://en.wikipedia.org/wiki/Syntax_diagram">railroad diagrams</a> for docs.
+ */
+public class RailRoadDiagram {
+    static String functionSignature(FunctionDefinition definition) {
+        List<Expression> expressions = new ArrayList<>();
+        expressions.add(new SpecialSequence(definition.name().toUpperCase(Locale.ROOT)));
+        expressions.add(new Syntax("("));
+        boolean first = true;
+        List<String> args = ShowFunctions.signature(definition);
+        for (String arg : args) {
+            if (arg.endsWith("...")) {
+                expressions.add(new Repetition(new Sequence(new Syntax(","), new Literal(arg.substring(0, arg.length() - 3))), 0, null));
+            } else {
+                if (first) {
+                    first = false;
+                } else {
+                    expressions.add(new Syntax(","));
+                }
+                expressions.add(new Literal(arg));
+            }
+        }
+        expressions.add(new Syntax(")"));
+        net.nextencia.rrdiagram.grammar.model.Expression rr = new Sequence(
+            expressions.toArray(net.nextencia.rrdiagram.grammar.model.Expression[]::new)
+        );
+        RRDiagram rrDiagram = new GrammarToRRDiagram().convert(new Rule("test", rr));
+        RRDiagramToSVG toSvg = new RRDiagramToSVG();
+        toSvg.setSpecialSequenceShape(RRDiagramToSVG.BoxShape.RECTANGLE);
+        toSvg.setLiteralFillColor(toSvg.getSpecialSequenceFillColor());
+        toSvg.setLiteralFont(toSvg.getLiteralFont().deriveFont(20.0F));
+        toSvg.setSpecialSequenceFont(toSvg.getSpecialSequenceFont().deriveFont(20.0F));
+        toSvg.setRuleFont(toSvg.getRuleFont().deriveFont(20.0F));
+        return toSvg.convert(rrDiagram);
+    }
+
+    /**
+     * Like a literal but with light grey text for a more muted appearance for syntax.
+     */
+    private static class Syntax extends Literal {
+        private static final String LITERAL_TEXT_CLASS = "j";
+        private static final String SYNTAX_TEXT_CLASS = "syn";
+        private static final String SYNTAX_GREY = "8D8D8D";
+
+        private final String text;
+
+        private Syntax(String text) {
+            super(text);
+            this.text = text;
+        }
+
+        @Override
+        protected RRElement toRRElement(GrammarToRRDiagram grammarToRRDiagram) {
+            // This performs a monumentally rude hack to replace the text color of this element.
+            return new RRText(RRText.Type.LITERAL, text, null) {
+                @Override
+                protected void toSVG(RRDiagramToSVG rrDiagramToSVG, int xOffset, int yOffset, RRDiagram.SvgContent svgContent) {
+                    super.toSVG(rrDiagramToSVG, xOffset, yOffset, new RRDiagram.SvgContent() {
+                        @Override
+                        public String getDefinedCSSClass(String style) {
+                            if (style.equals(LITERAL_TEXT_CLASS)) {
+                                return svgContent.getDefinedCSSClass(SYNTAX_TEXT_CLASS);
+                            }
+                            return svgContent.getDefinedCSSClass(style);
+                        }
+
+                        @Override
+                        public String setCSSClass(String cssClass, String definition) {
+                            if (false == cssClass.equals(LITERAL_TEXT_CLASS)) {
+                                return svgContent.setCSSClass(cssClass, definition);
+                            }
+                            svgContent.setCSSClass(cssClass, definition);
+                            return svgContent.setCSSClass(SYNTAX_TEXT_CLASS, definition.replace("fill:#000000", "fill:#" + SYNTAX_GREY));
+                        }
+
+                        @Override
+                        public void addPathConnector(int x1, int y1, String path, int x2, int y2) {
+                            svgContent.addPathConnector(x1, y1, path, x2, y2);
+                        }
+
+                        @Override
+                        public void addLineConnector(int x1, int y1, int x2, int y2) {
+                            svgContent.addLineConnector(x1, y1, x2, y2);
+                        }
+
+                        @Override
+                        public void addElement(String element) {
+                            svgContent.addElement(element);
+                        }
+                    });
+                }
+            };
+        }
+    }
+}