Browse Source

ESQL: Yet more function tests and docs (#99009)

This adds tests, supported types, and a signature image for `to_string`
and `to_version`. It also fixes the resolution of functions who's names
contain an `_`

Finally, it updates the docs for `ceil` to render the image more nicely.
Nik Everett 2 years ago
parent
commit
936e69ddd5
83 changed files with 545 additions and 54 deletions
  1. 1 1
      docs/reference/esql/functions/ceil.asciidoc
  2. 1 0
      docs/reference/esql/functions/signature/auto_bucket.svg
  3. 1 0
      docs/reference/esql/functions/signature/date_extract.svg
  4. 1 0
      docs/reference/esql/functions/signature/date_parse.svg
  5. 1 0
      docs/reference/esql/functions/signature/is_finite.svg
  6. 1 0
      docs/reference/esql/functions/signature/is_infinite.svg
  7. 1 0
      docs/reference/esql/functions/signature/mv_avg.svg
  8. 1 0
      docs/reference/esql/functions/signature/mv_concat.svg
  9. 1 0
      docs/reference/esql/functions/signature/mv_count.svg
  10. 1 0
      docs/reference/esql/functions/signature/mv_dedupe.svg
  11. 1 0
      docs/reference/esql/functions/signature/mv_max.svg
  12. 1 0
      docs/reference/esql/functions/signature/mv_median.svg
  13. 1 0
      docs/reference/esql/functions/signature/mv_min.svg
  14. 1 0
      docs/reference/esql/functions/signature/mv_sum.svg
  15. 1 0
      docs/reference/esql/functions/signature/starts_with.svg
  16. 1 0
      docs/reference/esql/functions/signature/to_string.svg
  17. 1 0
      docs/reference/esql/functions/signature/to_version.svg
  18. 7 0
      docs/reference/esql/functions/to_string.asciidoc
  19. 7 0
      docs/reference/esql/functions/to_version.asciidoc
  20. 5 0
      docs/reference/esql/functions/types/auto_bucket.asciidoc
  21. 5 0
      docs/reference/esql/functions/types/date_extract.asciidoc
  22. 5 0
      docs/reference/esql/functions/types/date_parse.asciidoc
  23. 5 0
      docs/reference/esql/functions/types/is_finite.asciidoc
  24. 5 0
      docs/reference/esql/functions/types/is_infinite.asciidoc
  25. 8 0
      docs/reference/esql/functions/types/mv_avg.asciidoc
  26. 5 0
      docs/reference/esql/functions/types/mv_concat.asciidoc
  27. 10 0
      docs/reference/esql/functions/types/mv_count.asciidoc
  28. 9 0
      docs/reference/esql/functions/types/mv_dedupe.asciidoc
  29. 10 0
      docs/reference/esql/functions/types/mv_max.asciidoc
  30. 8 0
      docs/reference/esql/functions/types/mv_median.asciidoc
  31. 10 0
      docs/reference/esql/functions/types/mv_min.asciidoc
  32. 5 0
      docs/reference/esql/functions/types/mv_sum.asciidoc
  33. 5 0
      docs/reference/esql/functions/types/starts_with.asciidoc
  34. 14 0
      docs/reference/esql/functions/types/to_string.asciidoc
  35. 7 0
      docs/reference/esql/functions/types/to_version.asciidoc
  36. 1 1
      test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java
  37. 3 1
      x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/ConvertEvaluatorImplementer.java
  38. 4 4
      x-pack/plugin/esql/qa/testFixtures/src/main/resources/show.csv-spec
  39. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBooleanFromDoubleEvaluator.java
  40. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBooleanFromIntEvaluator.java
  41. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBooleanFromLongEvaluator.java
  42. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBooleanFromStringEvaluator.java
  43. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBooleanFromUnsignedLongEvaluator.java
  44. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDatetimeFromStringEvaluator.java
  45. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDoubleFromBooleanEvaluator.java
  46. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDoubleFromIntEvaluator.java
  47. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDoubleFromLongEvaluator.java
  48. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDoubleFromStringEvaluator.java
  49. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDoubleFromUnsignedLongEvaluator.java
  50. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIPFromStringEvaluator.java
  51. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIntegerFromBooleanEvaluator.java
  52. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIntegerFromDoubleEvaluator.java
  53. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIntegerFromLongEvaluator.java
  54. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIntegerFromStringEvaluator.java
  55. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIntegerFromUnsignedLongEvaluator.java
  56. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongFromBooleanEvaluator.java
  57. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongFromDoubleEvaluator.java
  58. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongFromIntEvaluator.java
  59. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongFromStringEvaluator.java
  60. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongFromUnsignedLongEvaluator.java
  61. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringFromBooleanEvaluator.java
  62. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringFromDatetimeEvaluator.java
  63. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringFromDoubleEvaluator.java
  64. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringFromIPEvaluator.java
  65. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringFromIntEvaluator.java
  66. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringFromLongEvaluator.java
  67. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringFromUnsignedLongEvaluator.java
  68. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringFromVersionEvaluator.java
  69. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToUnsignedLongFromBooleanEvaluator.java
  70. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToUnsignedLongFromDoubleEvaluator.java
  71. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToUnsignedLongFromIntEvaluator.java
  72. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToUnsignedLongFromLongEvaluator.java
  73. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToUnsignedLongFromStringEvaluator.java
  74. 1 1
      x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToVersionFromStringEvaluator.java
  75. 1 1
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/AbstractConvertFunction.java
  76. 6 2
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToString.java
  77. 9 3
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToVersion.java
  78. 1 1
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java
  79. 4 2
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractFunctionTestCase.java
  80. 157 1
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/TestCaseSupplier.java
  81. 103 0
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringTests.java
  82. 72 0
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToVersionTests.java
  83. 1 1
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/AbstractMultivalueFunctionTestCase.java

+ 1 - 1
docs/reference/esql/functions/ceil.asciidoc

@@ -1,7 +1,7 @@
 [[esql-ceil]]
 === `CEIL`
 [.text-center]
-image::esql/functions/signature/floor.svg[Embedded,opts=inline]
+image::esql/functions/signature/ceil.svg[Embedded,opts=inline]
 
 Round a number up to the nearest integer.
 

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

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="684" height="46" viewbox="0 0 684 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m152 0h10m32 0h10m68 0h10m32 0h10m68 0h10m32 0h10m68 0h10m32 0h10m68 0h10m32 0h5"/><rect class="s" x="5" y="5" width="152" height="36"/><text class="k" x="15" y="31">AUTO_BUCKET</text><rect class="s" x="167" y="5" width="32" height="36" rx="7"/><text class="syn" x="177" y="31">(</text><rect class="s" x="209" y="5" width="68" height="36" rx="7"/><text class="k" x="219" y="31">arg1</text><rect class="s" x="287" y="5" width="32" height="36" rx="7"/><text class="syn" x="297" y="31">,</text><rect class="s" x="329" y="5" width="68" height="36" rx="7"/><text class="k" x="339" y="31">arg2</text><rect class="s" x="407" y="5" width="32" height="36" rx="7"/><text class="syn" x="417" y="31">,</text><rect class="s" x="449" y="5" width="68" height="36" rx="7"/><text class="k" x="459" y="31">arg3</text><rect class="s" x="527" y="5" width="32" height="36" rx="7"/><text class="syn" x="537" y="31">,</text><rect class="s" x="569" y="5" width="68" height="36" rx="7"/><text class="k" x="579" y="31">arg4</text><rect class="s" x="647" y="5" width="32" height="36" rx="7"/><text class="syn" x="657" y="31">)</text></svg>

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

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="456" height="46" viewbox="0 0 456 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m164 0h10m32 0h10m68 0h10m32 0h10m68 0h10m32 0h5"/><rect class="s" x="5" y="5" width="164" height="36"/><text class="k" x="15" y="31">DATE_EXTRACT</text><rect class="s" x="179" y="5" width="32" height="36" rx="7"/><text class="syn" x="189" y="31">(</text><rect class="s" x="221" y="5" width="68" height="36" rx="7"/><text class="k" x="231" y="31">arg1</text><rect class="s" x="299" y="5" width="32" height="36" rx="7"/><text class="syn" x="309" y="31">,</text><rect class="s" x="341" y="5" width="68" height="36" rx="7"/><text class="k" x="351" y="31">arg2</text><rect class="s" x="419" y="5" width="32" height="36" rx="7"/><text class="syn" x="429" y="31">)</text></svg>

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

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="432" height="46" viewbox="0 0 432 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m140 0h10m32 0h10m68 0h10m32 0h10m68 0h10m32 0h5"/><rect class="s" x="5" y="5" width="140" height="36"/><text class="k" x="15" y="31">DATE_PARSE</text><rect class="s" x="155" y="5" width="32" height="36" rx="7"/><text class="syn" x="165" y="31">(</text><rect class="s" x="197" y="5" width="68" height="36" rx="7"/><text class="k" x="207" y="31">arg1</text><rect class="s" x="275" y="5" width="32" height="36" rx="7"/><text class="syn" x="285" y="31">,</text><rect class="s" x="317" y="5" width="68" height="36" rx="7"/><text class="k" x="327" y="31">arg2</text><rect class="s" x="395" y="5" width="32" height="36" rx="7"/><text class="syn" x="405" y="31">)</text></svg>

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

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="300" height="46" viewbox="0 0 300 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m128 0h10m32 0h10m68 0h10m32 0h5"/><rect class="s" x="5" y="5" width="128" height="36"/><text class="k" x="15" y="31">IS_FINITE</text><rect class="s" x="143" y="5" width="32" height="36" rx="7"/><text class="syn" x="153" y="31">(</text><rect class="s" x="185" y="5" width="68" height="36" rx="7"/><text class="k" x="195" y="31">arg1</text><rect class="s" x="263" y="5" width="32" height="36" rx="7"/><text class="syn" x="273" y="31">)</text></svg>

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

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="324" height="46" viewbox="0 0 324 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m152 0h10m32 0h10m68 0h10m32 0h5"/><rect class="s" x="5" y="5" width="152" height="36"/><text class="k" x="15" y="31">IS_INFINITE</text><rect class="s" x="167" y="5" width="32" height="36" rx="7"/><text class="syn" x="177" y="31">(</text><rect class="s" x="209" y="5" width="68" height="36" rx="7"/><text class="k" x="219" y="31">arg1</text><rect class="s" x="287" y="5" width="32" height="36" rx="7"/><text class="syn" x="297" y="31">)</text></svg>

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

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="264" height="46" viewbox="0 0 264 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m92 0h10m32 0h10m68 0h10m32 0h5"/><rect class="s" x="5" y="5" width="92" height="36"/><text class="k" x="15" y="31">MV_AVG</text><rect class="s" x="107" y="5" width="32" height="36" rx="7"/><text class="syn" x="117" y="31">(</text><rect class="s" x="149" y="5" width="68" height="36" rx="7"/><text class="k" x="159" y="31">arg1</text><rect class="s" x="227" y="5" width="32" height="36" rx="7"/><text class="syn" x="237" y="31">)</text></svg>

+ 1 - 0
docs/reference/esql/functions/signature/mv_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="420" height="46" viewbox="0 0 420 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m128 0h10m32 0h10m68 0h10m32 0h10m68 0h10m32 0h5"/><rect class="s" x="5" y="5" width="128" height="36"/><text class="k" x="15" y="31">MV_CONCAT</text><rect class="s" x="143" y="5" width="32" height="36" rx="7"/><text class="syn" x="153" y="31">(</text><rect class="s" x="185" y="5" width="68" height="36" rx="7"/><text class="k" x="195" y="31">arg1</text><rect class="s" x="263" y="5" width="32" height="36" rx="7"/><text class="syn" x="273" y="31">,</text><rect class="s" x="305" y="5" width="68" height="36" rx="7"/><text class="k" x="315" y="31">arg2</text><rect class="s" x="383" y="5" width="32" height="36" rx="7"/><text class="syn" x="393" y="31">)</text></svg>

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

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="288" height="46" viewbox="0 0 288 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m116 0h10m32 0h10m68 0h10m32 0h5"/><rect class="s" x="5" y="5" width="116" height="36"/><text class="k" x="15" y="31">MV_COUNT</text><rect class="s" x="131" y="5" width="32" height="36" rx="7"/><text class="syn" x="141" y="31">(</text><rect class="s" x="173" y="5" width="68" height="36" rx="7"/><text class="k" x="183" y="31">arg1</text><rect class="s" x="251" y="5" width="32" height="36" rx="7"/><text class="syn" x="261" y="31">)</text></svg>

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

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="300" height="46" viewbox="0 0 300 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m128 0h10m32 0h10m68 0h10m32 0h5"/><rect class="s" x="5" y="5" width="128" height="36"/><text class="k" x="15" y="31">MV_DEDUPE</text><rect class="s" x="143" y="5" width="32" height="36" rx="7"/><text class="syn" x="153" y="31">(</text><rect class="s" x="185" y="5" width="68" height="36" rx="7"/><text class="k" x="195" y="31">arg1</text><rect class="s" x="263" y="5" width="32" height="36" rx="7"/><text class="syn" x="273" y="31">)</text></svg>

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

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="264" height="46" viewbox="0 0 264 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m92 0h10m32 0h10m68 0h10m32 0h5"/><rect class="s" x="5" y="5" width="92" height="36"/><text class="k" x="15" y="31">MV_MAX</text><rect class="s" x="107" y="5" width="32" height="36" rx="7"/><text class="syn" x="117" y="31">(</text><rect class="s" x="149" y="5" width="68" height="36" rx="7"/><text class="k" x="159" y="31">arg1</text><rect class="s" x="227" y="5" width="32" height="36" rx="7"/><text class="syn" x="237" y="31">)</text></svg>

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

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="300" height="46" viewbox="0 0 300 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m128 0h10m32 0h10m68 0h10m32 0h5"/><rect class="s" x="5" y="5" width="128" height="36"/><text class="k" x="15" y="31">MV_MEDIAN</text><rect class="s" x="143" y="5" width="32" height="36" rx="7"/><text class="syn" x="153" y="31">(</text><rect class="s" x="185" y="5" width="68" height="36" rx="7"/><text class="k" x="195" y="31">arg1</text><rect class="s" x="263" y="5" width="32" height="36" rx="7"/><text class="syn" x="273" y="31">)</text></svg>

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

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="264" height="46" viewbox="0 0 264 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m92 0h10m32 0h10m68 0h10m32 0h5"/><rect class="s" x="5" y="5" width="92" height="36"/><text class="k" x="15" y="31">MV_MIN</text><rect class="s" x="107" y="5" width="32" height="36" rx="7"/><text class="syn" x="117" y="31">(</text><rect class="s" x="149" y="5" width="68" height="36" rx="7"/><text class="k" x="159" y="31">arg1</text><rect class="s" x="227" y="5" width="32" height="36" rx="7"/><text class="syn" x="237" y="31">)</text></svg>

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

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="264" height="46" viewbox="0 0 264 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m92 0h10m32 0h10m68 0h10m32 0h5"/><rect class="s" x="5" y="5" width="92" height="36"/><text class="k" x="15" y="31">MV_SUM</text><rect class="s" x="107" y="5" width="32" height="36" rx="7"/><text class="syn" x="117" y="31">(</text><rect class="s" x="149" y="5" width="68" height="36" rx="7"/><text class="k" x="159" y="31">arg1</text><rect class="s" x="227" y="5" width="32" height="36" rx="7"/><text class="syn" x="237" y="31">)</text></svg>

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

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="444" height="46" viewbox="0 0 444 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m152 0h10m32 0h10m68 0h10m32 0h10m68 0h10m32 0h5"/><rect class="s" x="5" y="5" width="152" height="36"/><text class="k" x="15" y="31">STARTS_WITH</text><rect class="s" x="167" y="5" width="32" height="36" rx="7"/><text class="syn" x="177" y="31">(</text><rect class="s" x="209" y="5" width="68" height="36" rx="7"/><text class="k" x="219" y="31">arg1</text><rect class="s" x="287" y="5" width="32" height="36" rx="7"/><text class="syn" x="297" y="31">,</text><rect class="s" x="329" y="5" width="68" height="36" rx="7"/><text class="k" x="339" y="31">arg2</text><rect class="s" x="407" y="5" width="32" height="36" rx="7"/><text class="syn" x="417" y="31">)</text></svg>

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

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="264" height="46" viewbox="0 0 264 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m128 0h10m32 0h10m32 0h10m32 0h5"/><rect class="s" x="5" y="5" width="128" height="36"/><text class="k" x="15" y="31">TO_STRING</text><rect class="s" x="143" y="5" width="32" height="36" rx="7"/><text class="syn" x="153" y="31">(</text><rect class="s" x="185" y="5" width="32" height="36" rx="7"/><text class="k" x="195" y="31">v</text><rect class="s" x="227" y="5" width="32" height="36" rx="7"/><text class="syn" x="237" y="31">)</text></svg>

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

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="276" height="46" viewbox="0 0 276 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m140 0h10m32 0h10m32 0h10m32 0h5"/><rect class="s" x="5" y="5" width="140" height="36"/><text class="k" x="15" y="31">TO_VERSION</text><rect class="s" x="155" y="5" width="32" height="36" rx="7"/><text class="syn" x="165" y="31">(</text><rect class="s" x="197" y="5" width="32" height="36" rx="7"/><text class="k" x="207" y="31">v</text><rect class="s" x="239" y="5" width="32" height="36" rx="7"/><text class="syn" x="249" y="31">)</text></svg>

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

@@ -1,5 +1,8 @@
 [[esql-to_string]]
 === `TO_STRING`
+[.text-center]
+image::esql/functions/signature/to_string.svg[Embedded,opts=inline]
+
 Converts a field into a string. For example:
 
 [source.merge.styled,esql]
@@ -23,3 +26,7 @@ include::{esql-specs}/string.csv-spec[tag=to_string_multivalue-result]
 |===
 
 Alias: TO_STR
+
+Supported types:
+
+include::types/to_string.asciidoc[]

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

@@ -1,5 +1,8 @@
 [[esql-to_version]]
 === `TO_VERSION`
+[.text-center]
+image::esql/functions/signature/to_version.svg[Embedded,opts=inline]
+
 Converts an input string to a version value. For example:
 
 [source.merge.styled,esql]
@@ -14,3 +17,7 @@ include::{esql-specs}/version.csv-spec[tag=to_version-result]
 The input can be a single- or multi-valued field or an expression.
 
 Alias: TO_VER
+
+Supported types:
+
+include::types/to_version.asciidoc[]

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

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

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

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

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

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

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

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

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

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

+ 8 - 0
docs/reference/esql/functions/types/mv_avg.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/mv_concat.asciidoc

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

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

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

+ 9 - 0
docs/reference/esql/functions/types/mv_dedupe.asciidoc

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

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

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

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

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

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

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

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

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

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

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

+ 14 - 0
docs/reference/esql/functions/types/to_string.asciidoc

@@ -0,0 +1,14 @@
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+v | result
+boolean | keyword
+datetime | keyword
+double | keyword
+integer | keyword
+ip | keyword
+keyword | keyword
+long | keyword
+text | keyword
+unsigned_long | keyword
+version | keyword
+|===

+ 7 - 0
docs/reference/esql/functions/types/to_version.asciidoc

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

+ 1 - 1
test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java

@@ -1849,7 +1849,7 @@ public abstract class ESTestCase extends LuceneTestCase {
         return MIN_PRIVATE_PORT + PORTS_PER_WORKER + effectiveWorkerId * PORTS_PER_WORKER;
     }
 
-    protected static InetAddress randomIp(boolean v4) {
+    public static InetAddress randomIp(boolean v4) {
         try {
             if (v4) {
                 byte[] ipv4 = new byte[4];

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

@@ -40,6 +40,7 @@ public class ConvertEvaluatorImplementer {
 
     private final TypeElement declarationType;
     private final ExecutableElement processFunction;
+    private final String extraName;
     private final ClassName implementation;
     private final TypeName argumentType;
     private final TypeName resultType;
@@ -50,6 +51,7 @@ public class ConvertEvaluatorImplementer {
         if (processFunction.getParameters().size() != 1) {
             throw new IllegalArgumentException("processing function should have exactly one parameter");
         }
+        this.extraName = extraName;
         this.argumentType = TypeName.get(processFunction.getParameters().get(0).asType());
         this.resultType = TypeName.get(processFunction.getReturnType());
 
@@ -96,7 +98,7 @@ public class ConvertEvaluatorImplementer {
     private MethodSpec name() {
         MethodSpec.Builder builder = MethodSpec.methodBuilder("name").addModifiers(Modifier.PUBLIC);
         builder.addAnnotation(Override.class).returns(String.class);
-        builder.addStatement("return $S", declarationType.getSimpleName());
+        builder.addStatement("return $S", declarationType.getSimpleName() + extraName);
         return builder.build();
     }
 

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

@@ -81,13 +81,13 @@ to_integer               |to_integer(arg1)
 to_ip                    |to_ip(arg1)
 to_long                  |to_long(arg1)
 to_radians               |to_radians(arg1)
-to_str                   |to_str(arg1)
-to_string                |to_string(arg1)
+to_str                   |to_str(v)
+to_string                |to_string(v)
 to_ul                    |to_ul(arg1)
 to_ulong                 |to_ulong(arg1)
 to_unsigned_long         |to_unsigned_long(arg1)
-to_ver                   |to_ver(arg1)
-to_version               |to_version(arg1)
+to_ver                   |to_ver(v)
+to_version               |to_version(v)
 trim                     |trim(arg1)
 ;
 

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBooleanFromDoubleEvaluator.java

@@ -29,7 +29,7 @@ public final class ToBooleanFromDoubleEvaluator extends AbstractConvertFunction.
 
   @Override
   public String name() {
-    return "ToBoolean";
+    return "ToBooleanFromDouble";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBooleanFromIntEvaluator.java

@@ -29,7 +29,7 @@ public final class ToBooleanFromIntEvaluator extends AbstractConvertFunction.Abs
 
   @Override
   public String name() {
-    return "ToBoolean";
+    return "ToBooleanFromInt";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBooleanFromLongEvaluator.java

@@ -29,7 +29,7 @@ public final class ToBooleanFromLongEvaluator extends AbstractConvertFunction.Ab
 
   @Override
   public String name() {
-    return "ToBoolean";
+    return "ToBooleanFromLong";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBooleanFromStringEvaluator.java

@@ -30,7 +30,7 @@ public final class ToBooleanFromStringEvaluator extends AbstractConvertFunction.
 
   @Override
   public String name() {
-    return "ToBoolean";
+    return "ToBooleanFromString";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBooleanFromUnsignedLongEvaluator.java

@@ -29,7 +29,7 @@ public final class ToBooleanFromUnsignedLongEvaluator extends AbstractConvertFun
 
   @Override
   public String name() {
-    return "ToBoolean";
+    return "ToBooleanFromUnsignedLong";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDatetimeFromStringEvaluator.java

@@ -30,7 +30,7 @@ public final class ToDatetimeFromStringEvaluator extends AbstractConvertFunction
 
   @Override
   public String name() {
-    return "ToDatetime";
+    return "ToDatetimeFromString";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDoubleFromBooleanEvaluator.java

@@ -29,7 +29,7 @@ public final class ToDoubleFromBooleanEvaluator extends AbstractConvertFunction.
 
   @Override
   public String name() {
-    return "ToDouble";
+    return "ToDoubleFromBoolean";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDoubleFromIntEvaluator.java

@@ -29,7 +29,7 @@ public final class ToDoubleFromIntEvaluator extends AbstractConvertFunction.Abst
 
   @Override
   public String name() {
-    return "ToDouble";
+    return "ToDoubleFromInt";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDoubleFromLongEvaluator.java

@@ -29,7 +29,7 @@ public final class ToDoubleFromLongEvaluator extends AbstractConvertFunction.Abs
 
   @Override
   public String name() {
-    return "ToDouble";
+    return "ToDoubleFromLong";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDoubleFromStringEvaluator.java

@@ -30,7 +30,7 @@ public final class ToDoubleFromStringEvaluator extends AbstractConvertFunction.A
 
   @Override
   public String name() {
-    return "ToDouble";
+    return "ToDoubleFromString";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDoubleFromUnsignedLongEvaluator.java

@@ -29,7 +29,7 @@ public final class ToDoubleFromUnsignedLongEvaluator extends AbstractConvertFunc
 
   @Override
   public String name() {
-    return "ToDouble";
+    return "ToDoubleFromUnsignedLong";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIPFromStringEvaluator.java

@@ -31,7 +31,7 @@ public final class ToIPFromStringEvaluator extends AbstractConvertFunction.Abstr
 
   @Override
   public String name() {
-    return "ToIP";
+    return "ToIPFromString";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIntegerFromBooleanEvaluator.java

@@ -29,7 +29,7 @@ public final class ToIntegerFromBooleanEvaluator extends AbstractConvertFunction
 
   @Override
   public String name() {
-    return "ToInteger";
+    return "ToIntegerFromBoolean";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIntegerFromDoubleEvaluator.java

@@ -29,7 +29,7 @@ public final class ToIntegerFromDoubleEvaluator extends AbstractConvertFunction.
 
   @Override
   public String name() {
-    return "ToInteger";
+    return "ToIntegerFromDouble";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIntegerFromLongEvaluator.java

@@ -29,7 +29,7 @@ public final class ToIntegerFromLongEvaluator extends AbstractConvertFunction.Ab
 
   @Override
   public String name() {
-    return "ToInteger";
+    return "ToIntegerFromLong";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIntegerFromStringEvaluator.java

@@ -30,7 +30,7 @@ public final class ToIntegerFromStringEvaluator extends AbstractConvertFunction.
 
   @Override
   public String name() {
-    return "ToInteger";
+    return "ToIntegerFromString";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIntegerFromUnsignedLongEvaluator.java

@@ -29,7 +29,7 @@ public final class ToIntegerFromUnsignedLongEvaluator extends AbstractConvertFun
 
   @Override
   public String name() {
-    return "ToInteger";
+    return "ToIntegerFromUnsignedLong";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongFromBooleanEvaluator.java

@@ -29,7 +29,7 @@ public final class ToLongFromBooleanEvaluator extends AbstractConvertFunction.Ab
 
   @Override
   public String name() {
-    return "ToLong";
+    return "ToLongFromBoolean";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongFromDoubleEvaluator.java

@@ -29,7 +29,7 @@ public final class ToLongFromDoubleEvaluator extends AbstractConvertFunction.Abs
 
   @Override
   public String name() {
-    return "ToLong";
+    return "ToLongFromDouble";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongFromIntEvaluator.java

@@ -29,7 +29,7 @@ public final class ToLongFromIntEvaluator extends AbstractConvertFunction.Abstra
 
   @Override
   public String name() {
-    return "ToLong";
+    return "ToLongFromInt";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongFromStringEvaluator.java

@@ -30,7 +30,7 @@ public final class ToLongFromStringEvaluator extends AbstractConvertFunction.Abs
 
   @Override
   public String name() {
-    return "ToLong";
+    return "ToLongFromString";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongFromUnsignedLongEvaluator.java

@@ -28,7 +28,7 @@ public final class ToLongFromUnsignedLongEvaluator extends AbstractConvertFuncti
 
   @Override
   public String name() {
-    return "ToLong";
+    return "ToLongFromUnsignedLong";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringFromBooleanEvaluator.java

@@ -32,7 +32,7 @@ public final class ToStringFromBooleanEvaluator extends AbstractConvertFunction.
 
   @Override
   public String name() {
-    return "ToString";
+    return "ToStringFromBoolean";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringFromDatetimeEvaluator.java

@@ -32,7 +32,7 @@ public final class ToStringFromDatetimeEvaluator extends AbstractConvertFunction
 
   @Override
   public String name() {
-    return "ToString";
+    return "ToStringFromDatetime";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringFromDoubleEvaluator.java

@@ -32,7 +32,7 @@ public final class ToStringFromDoubleEvaluator extends AbstractConvertFunction.A
 
   @Override
   public String name() {
-    return "ToString";
+    return "ToStringFromDouble";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringFromIPEvaluator.java

@@ -31,7 +31,7 @@ public final class ToStringFromIPEvaluator extends AbstractConvertFunction.Abstr
 
   @Override
   public String name() {
-    return "ToString";
+    return "ToStringFromIP";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringFromIntEvaluator.java

@@ -32,7 +32,7 @@ public final class ToStringFromIntEvaluator extends AbstractConvertFunction.Abst
 
   @Override
   public String name() {
-    return "ToString";
+    return "ToStringFromInt";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringFromLongEvaluator.java

@@ -32,7 +32,7 @@ public final class ToStringFromLongEvaluator extends AbstractConvertFunction.Abs
 
   @Override
   public String name() {
-    return "ToString";
+    return "ToStringFromLong";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringFromUnsignedLongEvaluator.java

@@ -32,7 +32,7 @@ public final class ToStringFromUnsignedLongEvaluator extends AbstractConvertFunc
 
   @Override
   public String name() {
-    return "ToString";
+    return "ToStringFromUnsignedLong";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringFromVersionEvaluator.java

@@ -31,7 +31,7 @@ public final class ToStringFromVersionEvaluator extends AbstractConvertFunction.
 
   @Override
   public String name() {
-    return "ToString";
+    return "ToStringFromVersion";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToUnsignedLongFromBooleanEvaluator.java

@@ -29,7 +29,7 @@ public final class ToUnsignedLongFromBooleanEvaluator extends AbstractConvertFun
 
   @Override
   public String name() {
-    return "ToUnsignedLong";
+    return "ToUnsignedLongFromBoolean";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToUnsignedLongFromDoubleEvaluator.java

@@ -29,7 +29,7 @@ public final class ToUnsignedLongFromDoubleEvaluator extends AbstractConvertFunc
 
   @Override
   public String name() {
-    return "ToUnsignedLong";
+    return "ToUnsignedLongFromDouble";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToUnsignedLongFromIntEvaluator.java

@@ -29,7 +29,7 @@ public final class ToUnsignedLongFromIntEvaluator extends AbstractConvertFunctio
 
   @Override
   public String name() {
-    return "ToUnsignedLong";
+    return "ToUnsignedLongFromInt";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToUnsignedLongFromLongEvaluator.java

@@ -28,7 +28,7 @@ public final class ToUnsignedLongFromLongEvaluator extends AbstractConvertFuncti
 
   @Override
   public String name() {
-    return "ToUnsignedLong";
+    return "ToUnsignedLongFromLong";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToUnsignedLongFromStringEvaluator.java

@@ -30,7 +30,7 @@ public final class ToUnsignedLongFromStringEvaluator extends AbstractConvertFunc
 
   @Override
   public String name() {
-    return "ToUnsignedLong";
+    return "ToUnsignedLongFromString";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToVersionFromStringEvaluator.java

@@ -31,7 +31,7 @@ public final class ToVersionFromStringEvaluator extends AbstractConvertFunction.
 
   @Override
   public String name() {
-    return "ToVersion";
+    return "ToVersionFromString";
   }
 
   @Override

+ 1 - 1
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/AbstractConvertFunction.java

@@ -117,7 +117,7 @@ public abstract class AbstractConvertFunction extends UnaryScalarFunction implem
 
         @Override
         public final String toString() {
-            return name() + "[field=" + fieldEvaluator + "]";
+            return name() + "Evaluator[field=" + fieldEvaluator + "]";
         }
     }
 }

+ 6 - 2
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToString.java

@@ -12,6 +12,7 @@ import org.elasticsearch.compute.ann.ConvertEvaluator;
 import org.elasticsearch.compute.operator.EvalOperator;
 import org.elasticsearch.search.DocValueFormat;
 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.tree.NodeInfo;
 import org.elasticsearch.xpack.ql.tree.Source;
@@ -29,6 +30,7 @@ import static org.elasticsearch.xpack.ql.type.DataTypes.INTEGER;
 import static org.elasticsearch.xpack.ql.type.DataTypes.IP;
 import static org.elasticsearch.xpack.ql.type.DataTypes.KEYWORD;
 import static org.elasticsearch.xpack.ql.type.DataTypes.LONG;
+import static org.elasticsearch.xpack.ql.type.DataTypes.TEXT;
 import static org.elasticsearch.xpack.ql.type.DataTypes.UNSIGNED_LONG;
 import static org.elasticsearch.xpack.ql.type.DataTypes.VERSION;
 import static org.elasticsearch.xpack.ql.util.DateUtils.UTC_DATE_TIME_FORMATTER;
@@ -52,14 +54,16 @@ public class ToString extends AbstractConvertFunction implements EvaluatorMapper
             ToStringFromLongEvaluator::new,
             INTEGER,
             ToStringFromIntEvaluator::new,
+            TEXT,
+            (fieldEval, source) -> fieldEval,
             VERSION,
             ToStringFromVersionEvaluator::new,
             UNSIGNED_LONG,
             ToStringFromUnsignedLongEvaluator::new
         );
 
-    public ToString(Source source, Expression field) {
-        super(source, field);
+    public ToString(Source source, @Named("v") Expression v) {
+        super(source, v);
     }
 
     @Override

+ 9 - 3
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToVersion.java

@@ -10,6 +10,7 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.convert;
 import org.apache.lucene.util.BytesRef;
 import org.elasticsearch.compute.ann.ConvertEvaluator;
 import org.elasticsearch.compute.operator.EvalOperator;
+import org.elasticsearch.xpack.esql.expression.function.Named;
 import org.elasticsearch.xpack.ql.expression.Expression;
 import org.elasticsearch.xpack.ql.tree.NodeInfo;
 import org.elasticsearch.xpack.ql.tree.Source;
@@ -21,15 +22,20 @@ import java.util.Map;
 import java.util.function.BiFunction;
 
 import static org.elasticsearch.xpack.ql.type.DataTypes.KEYWORD;
+import static org.elasticsearch.xpack.ql.type.DataTypes.TEXT;
 import static org.elasticsearch.xpack.ql.type.DataTypes.VERSION;
 
 public class ToVersion extends AbstractConvertFunction {
 
     private static final Map<DataType, BiFunction<EvalOperator.ExpressionEvaluator, Source, EvalOperator.ExpressionEvaluator>> EVALUATORS =
-        Map.of(VERSION, (fieldEval, source) -> fieldEval, KEYWORD, ToVersionFromStringEvaluator::new);
+        Map.ofEntries(
+            Map.entry(VERSION, (fieldEval, source) -> fieldEval),
+            Map.entry(KEYWORD, ToVersionFromStringEvaluator::new),
+            Map.entry(TEXT, ToVersionFromStringEvaluator::new)
+        );
 
-    public ToVersion(Source source, Expression field) {
-        super(source, field);
+    public ToVersion(Source source, @Named("v") Expression v) {
+        super(source, v);
     }
 
     @Override

+ 1 - 1
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java

@@ -1167,7 +1167,7 @@ public class AnalyzerTests extends ESTestCase {
 
     public void testUnsupportedTypesWithToString() {
         // DATE_PERIOD and TIME_DURATION types have been added, but not really patched through the engine; i.e. supported.
-        final String supportedTypes = "boolean, datetime, double, integer, ip, keyword, long, unsigned_long or version";
+        final String supportedTypes = "boolean, datetime, double, integer, ip, keyword, long, text, unsigned_long or version";
         verifyUnsupported(
             "row period = 1 year | eval to_string(period)",
             "line 1:28: argument of [to_string(period)] must be [" + supportedTypes + "], found value [period] type [date_period]"

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

@@ -33,6 +33,7 @@ import org.elasticsearch.xpack.ql.tree.Source;
 import org.elasticsearch.xpack.ql.type.DataType;
 import org.elasticsearch.xpack.ql.type.DataTypes;
 import org.elasticsearch.xpack.ql.type.EsField;
+import org.elasticsearch.xpack.ql.util.StringUtils;
 import org.elasticsearch.xpack.versionfield.Version;
 import org.junit.After;
 import org.junit.AfterClass;
@@ -465,7 +466,8 @@ public abstract class AbstractFunctionTestCase extends ESTestCase {
     private static final Map<Set<DataType>, String> NAMED_EXPECTED_TYPES = Map.ofEntries(
         Map.entry(Set.of(DataTypes.DOUBLE, DataTypes.NULL), "double"),
         Map.entry(Set.of(DataTypes.INTEGER, DataTypes.NULL), "integer"),
-        Map.entry(Set.of(DataTypes.LONG, DataTypes.INTEGER, DataTypes.UNSIGNED_LONG, DataTypes.DOUBLE, DataTypes.NULL), "numeric")
+        Map.entry(Set.of(DataTypes.LONG, DataTypes.INTEGER, DataTypes.UNSIGNED_LONG, DataTypes.DOUBLE, DataTypes.NULL), "numeric"),
+        Map.entry(Set.of(DataTypes.KEYWORD, DataTypes.TEXT, DataTypes.VERSION, DataTypes.NULL), "keyword, text or version")
     );
 
     private static String expectedType(Set<DataType> validTypes) {
@@ -584,7 +586,7 @@ public abstract class AbstractFunctionTestCase extends ESTestCase {
     }
 
     private static String functionName() {
-        return getTestClass().getSimpleName().replace("Tests", "").toLowerCase(Locale.ROOT);
+        return StringUtils.camelCaseToUnderscore(getTestClass().getSimpleName().replace("Tests", "")).toLowerCase(Locale.ROOT);
     }
 
     /**

+ 157 - 1
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/TestCaseSupplier.java

@@ -7,6 +7,9 @@
 
 package org.elasticsearch.xpack.esql.expression.function;
 
+import org.apache.lucene.document.InetAddressPoint;
+import org.apache.lucene.util.BytesRef;
+import org.elasticsearch.common.network.InetAddresses;
 import org.elasticsearch.test.ESTestCase;
 import org.elasticsearch.xpack.esql.type.EsqlDataTypes;
 import org.elasticsearch.xpack.ql.expression.Expression;
@@ -15,9 +18,11 @@ import org.elasticsearch.xpack.ql.tree.Source;
 import org.elasticsearch.xpack.ql.type.DataType;
 import org.elasticsearch.xpack.ql.type.DataTypes;
 import org.elasticsearch.xpack.ql.util.NumericUtils;
+import org.elasticsearch.xpack.versionfield.Version;
 import org.hamcrest.Matcher;
 
 import java.math.BigInteger;
+import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -269,6 +274,89 @@ public record TestCaseSupplier(String name, List<DataType> types, Supplier<TestC
         );
     }
 
+    /**
+     * Generate positive test cases for a unary function operating on an {@link DataTypes#BOOLEAN}.
+     */
+    public static void forUnaryBoolean(
+        List<TestCaseSupplier> suppliers,
+        String expectedEvaluatorToString,
+        DataType expectedType,
+        Function<Boolean, Object> expectedValue
+    ) {
+        unary(suppliers, expectedEvaluatorToString, DataTypes.BOOLEAN, booleanCases(), expectedType, v -> expectedValue.apply((Boolean) v));
+    }
+
+    /**
+     * Generate positive test cases for a unary function operating on an {@link DataTypes#DATETIME}.
+     */
+    public static void forUnaryDatetime(
+        List<TestCaseSupplier> suppliers,
+        String expectedEvaluatorToString,
+        DataType expectedType,
+        Function<Instant, Object> expectedValue
+    ) {
+        unaryNumeric(
+            suppliers,
+            expectedEvaluatorToString,
+            DataTypes.DATETIME,
+            dateCases(),
+            expectedType,
+            n -> expectedValue.apply(Instant.ofEpochMilli(n.longValue()))
+        );
+    }
+
+    /**
+     * Generate positive test cases for a unary function operating on an {@link DataTypes#IP}.
+     */
+    public static void forUnaryIp(
+        List<TestCaseSupplier> suppliers,
+        String expectedEvaluatorToString,
+        DataType expectedType,
+        Function<BytesRef, Object> expectedValue
+    ) {
+        unary(suppliers, expectedEvaluatorToString, DataTypes.IP, ipCases(), expectedType, v -> expectedValue.apply((BytesRef) v));
+    }
+
+    /**
+     * Generate positive test cases for a unary function operating on an {@link DataTypes#KEYWORD} and {@link DataTypes#TEXT}.
+     */
+    public static void forUnaryStrings(
+        List<TestCaseSupplier> suppliers,
+        String expectedEvaluatorToString,
+        DataType expectedType,
+        Function<BytesRef, Object> expectedValue
+    ) {
+        for (DataType type : EsqlDataTypes.types().stream().filter(EsqlDataTypes::isString).toList()) {
+            unary(
+                suppliers,
+                expectedEvaluatorToString,
+                type,
+                stringCases(type.typeName()),
+                expectedType,
+                v -> expectedValue.apply((BytesRef) v)
+            );
+        }
+    }
+
+    /**
+     * Generate positive test cases for a unary function operating on an {@link DataTypes#VERSION}.
+     */
+    public static void forUnaryVersion(
+        List<TestCaseSupplier> suppliers,
+        String expectedEvaluatorToString,
+        DataType expectedType,
+        Function<Version, Object> expectedValue
+    ) {
+        unary(
+            suppliers,
+            expectedEvaluatorToString,
+            DataTypes.VERSION,
+            versionCases(""),
+            expectedType,
+            v -> expectedValue.apply(new Version((BytesRef) v))
+        );
+    }
+
     private static void unaryNumeric(
         List<TestCaseSupplier> suppliers,
         String expectedEvaluatorToString,
@@ -277,10 +365,21 @@ public record TestCaseSupplier(String name, List<DataType> types, Supplier<TestC
         DataType expectedOutputType,
         Function<Number, Object> expected,
         List<String> warnings
+    ) {
+        unary(suppliers, expectedEvaluatorToString, inputType, valueSuppliers, expectedOutputType, v -> expected.apply((Number) v));
+    }
+
+    private static void unary(
+        List<TestCaseSupplier> suppliers,
+        String expectedEvaluatorToString,
+        DataType inputType,
+        List<Map.Entry<String, Supplier<Object>>> valueSuppliers,
+        DataType expectedOutputType,
+        Function<Object, Object> expected
     ) {
         for (Map.Entry<String, Supplier<Object>> supplier : valueSuppliers) {
             suppliers.add(new TestCaseSupplier(supplier.getKey(), List.of(inputType), () -> {
-                Number value = (Number) supplier.getValue().get();
+                Object value = supplier.getValue().get();
                 TypedData typed = new TypedData(
                     // TODO there has to be a better way to handle unsigned long
                     value instanceof BigInteger b ? NumericUtils.asLongUnsigned(b) : value,
@@ -436,6 +535,63 @@ public record TestCaseSupplier(String name, List<DataType> types, Supplier<TestC
         return cases;
     }
 
+    private static List<Map.Entry<String, Supplier<Object>>> booleanCases() {
+        return List.of(Map.entry("<true>", () -> true), Map.entry("<false>", () -> false));
+    }
+
+    private static List<Map.Entry<String, Supplier<Object>>> dateCases() {
+        return List.of(
+            Map.entry("<1970-01-01T00:00:00Z>", () -> 0L),
+            Map.entry(
+                "<date>",
+                () -> ESTestCase.randomLongBetween(0, 10 * (long) 10e11) // 1970-01-01T00:00:00Z - 2286-11-20T17:46:40Z
+            ),
+            Map.entry(
+                "<far future date>",
+                // 2286-11-20T17:46:40Z - +292278994-08-17T07:12:55.807Z
+                () -> ESTestCase.randomLongBetween(10 * (long) 10e11, Long.MAX_VALUE)
+            )
+        );
+    }
+
+    private static List<Map.Entry<String, Supplier<Object>>> ipCases() {
+        return List.of(
+            Map.entry("<127.0.0.1 ip>", () -> new BytesRef(InetAddressPoint.encode(InetAddresses.forString("127.0.0.1")))),
+            Map.entry("<ipv4>", () -> new BytesRef(InetAddressPoint.encode(ESTestCase.randomIp(true)))),
+            Map.entry("<ipv6>", () -> new BytesRef(InetAddressPoint.encode(ESTestCase.randomIp(false))))
+        );
+    }
+
+    private static List<Map.Entry<String, Supplier<Object>>> stringCases(String type) {
+        List<Map.Entry<String, Supplier<Object>>> result = new ArrayList<>();
+        result.add(Map.entry("<empty " + type + ">", () -> new BytesRef("")));
+        result.add(Map.entry("<short alpha " + type + ">", () -> new BytesRef(ESTestCase.randomAlphaOfLengthBetween(1, 30))));
+        result.add(Map.entry("<long alpha " + type + ">", () -> new BytesRef(ESTestCase.randomAlphaOfLengthBetween(300, 3000))));
+        result.add(Map.entry("<short unicode " + type + ">", () -> new BytesRef(ESTestCase.randomRealisticUnicodeOfLengthBetween(1, 30))));
+        result.add(
+            Map.entry("<long unicode " + type + ">", () -> new BytesRef(ESTestCase.randomRealisticUnicodeOfLengthBetween(300, 3000)))
+        );
+        return result;
+    }
+
+    /**
+     * Supplier test case data for {@link Version} fields.
+     */
+    public static List<Map.Entry<String, Supplier<Object>>> versionCases(String prefix) {
+        return List.of(
+            Map.entry("<" + prefix + "version major>", () -> new Version(Integer.toString(ESTestCase.between(0, 100))).toBytesRef()),
+            Map.entry(
+                "<" + prefix + "version major.minor>",
+                () -> new Version(ESTestCase.between(0, 100) + "." + ESTestCase.between(0, 100)).toBytesRef()
+            ),
+            Map.entry(
+                "<" + prefix + "version major.minor.patch>",
+                () -> new Version(ESTestCase.between(0, 100) + "." + ESTestCase.between(0, 100) + "." + ESTestCase.between(0, 100))
+                    .toBytesRef()
+            )
+        );
+    }
+
     private static final Map<DataType, List<Map.Entry<String, Supplier<Object>>>> RANDOM_VALUE_SUPPLIERS = Map.ofEntries(
         Map.entry(
             DataTypes.DOUBLE,

+ 103 - 0
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringTests.java

@@ -0,0 +1,103 @@
+/*
+ * 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.scalar.convert;
+
+import com.carrotsearch.randomizedtesting.annotations.Name;
+import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
+
+import org.apache.lucene.util.BytesRef;
+import org.elasticsearch.index.mapper.DateFieldMapper;
+import org.elasticsearch.search.DocValueFormat;
+import org.elasticsearch.xpack.esql.expression.function.AbstractFunctionTestCase;
+import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier;
+import org.elasticsearch.xpack.ql.expression.Expression;
+import org.elasticsearch.xpack.ql.tree.Source;
+import org.elasticsearch.xpack.ql.type.DataTypes;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Supplier;
+
+import static org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier.MAX_UNSIGNED_LONG;
+
+public class ToStringTests extends AbstractFunctionTestCase {
+    public ToStringTests(@Name("TestCase") Supplier<TestCaseSupplier.TestCase> testCaseSupplier) {
+        this.testCase = testCaseSupplier.get();
+    }
+
+    @ParametersFactory
+    public static Iterable<Object[]> parameters() {
+        // TODO multivalue fields
+        String read = "Attribute[channel=0]";
+        List<TestCaseSupplier> suppliers = new ArrayList<>();
+        TestCaseSupplier.forUnaryInt(
+            suppliers,
+            "ToStringFromIntEvaluator[field=" + read + "]",
+            DataTypes.KEYWORD,
+            i -> new BytesRef(Integer.toString(i)),
+            Integer.MIN_VALUE,
+            Integer.MAX_VALUE
+        );
+        TestCaseSupplier.forUnaryLong(
+            suppliers,
+            "ToStringFromLongEvaluator[field=" + read + "]",
+            DataTypes.KEYWORD,
+            l -> new BytesRef(Long.toString(l)),
+            Long.MIN_VALUE,
+            Long.MAX_VALUE
+        );
+        TestCaseSupplier.forUnaryUnsignedLong(
+            suppliers,
+            "ToStringFromUnsignedLongEvaluator[field=" + read + "]",
+            DataTypes.KEYWORD,
+            ul -> new BytesRef(ul.toString()),
+            BigInteger.ZERO,
+            MAX_UNSIGNED_LONG
+        );
+        TestCaseSupplier.forUnaryDouble(
+            suppliers,
+            "ToStringFromDoubleEvaluator[field=" + read + "]",
+            DataTypes.KEYWORD,
+            d -> new BytesRef(Double.toString(d)),
+            Double.NEGATIVE_INFINITY,
+            Double.POSITIVE_INFINITY
+        );
+        TestCaseSupplier.forUnaryBoolean(
+            suppliers,
+            "ToStringFromBooleanEvaluator[field=" + read + "]",
+            DataTypes.KEYWORD,
+            b -> new BytesRef(b.toString())
+        );
+        TestCaseSupplier.forUnaryDatetime(
+            suppliers,
+            "ToStringFromDatetimeEvaluator[field=" + read + "]",
+            DataTypes.KEYWORD,
+            i -> new BytesRef(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.formatMillis(i.toEpochMilli()))
+        );
+        TestCaseSupplier.forUnaryIp(
+            suppliers,
+            "ToStringFromIPEvaluator[field=" + read + "]",
+            DataTypes.KEYWORD,
+            ip -> new BytesRef(DocValueFormat.IP.format(ip))
+        );
+        TestCaseSupplier.forUnaryStrings(suppliers, read, DataTypes.KEYWORD, bytesRef -> bytesRef);
+        TestCaseSupplier.forUnaryVersion(
+            suppliers,
+            "ToStringFromVersionEvaluator[field=" + read + "]",
+            DataTypes.KEYWORD,
+            v -> new BytesRef(v.toString())
+        );
+        return parameterSuppliersFromTypedData(errorsForCasesWithoutExamples(anyNullIsNull(true, suppliers)));
+    }
+
+    @Override
+    protected Expression build(Source source, List<Expression> args) {
+        return new ToString(source, args.get(0));
+    }
+}

+ 72 - 0
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToVersionTests.java

@@ -0,0 +1,72 @@
+/*
+ * 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.scalar.convert;
+
+import com.carrotsearch.randomizedtesting.annotations.Name;
+import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
+
+import org.apache.lucene.util.BytesRef;
+import org.elasticsearch.xpack.esql.expression.function.AbstractFunctionTestCase;
+import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier;
+import org.elasticsearch.xpack.esql.type.EsqlDataTypes;
+import org.elasticsearch.xpack.ql.expression.Expression;
+import org.elasticsearch.xpack.ql.tree.Source;
+import org.elasticsearch.xpack.ql.type.DataType;
+import org.elasticsearch.xpack.ql.type.DataTypes;
+import org.elasticsearch.xpack.versionfield.Version;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Supplier;
+
+import static org.hamcrest.Matchers.equalTo;
+
+public class ToVersionTests extends AbstractFunctionTestCase {
+    public ToVersionTests(@Name("TestCase") Supplier<TestCaseSupplier.TestCase> testCaseSupplier) {
+        this.testCase = testCaseSupplier.get();
+    }
+
+    @ParametersFactory
+    public static Iterable<Object[]> parameters() {
+        // TODO multivalue fields
+        String read = "Attribute[channel=0]";
+        String stringEvaluator = "ToVersionFromStringEvaluator[field=" + read + "]";
+        List<TestCaseSupplier> suppliers = new ArrayList<>();
+        // Converting and IP to an IP doesn't change anything. Everything should succeed.
+        TestCaseSupplier.forUnaryVersion(suppliers, read, DataTypes.VERSION, v -> v.toBytesRef());
+        // None of the random strings ever look like versions so they should all become "invalid" versions
+        // TODO should this return null with warnings? they aren't version shaped at all.
+        TestCaseSupplier.forUnaryStrings(
+            suppliers,
+            stringEvaluator,
+            DataTypes.VERSION,
+            bytesRef -> new Version(bytesRef.utf8ToString()).toBytesRef()
+        );
+        // But strings that are shaped like versions do parse to valid versions
+        for (DataType inputType : EsqlDataTypes.types().stream().filter(EsqlDataTypes::isString).toList()) {
+            for (Map.Entry<String, Supplier<Object>> versionGen : TestCaseSupplier.versionCases(inputType.typeName() + " ")) {
+                suppliers.add(new TestCaseSupplier(versionGen.getKey(), List.of(inputType), () -> {
+                    BytesRef encodedVersion = (BytesRef) versionGen.getValue().get();
+                    TestCaseSupplier.TypedData typed = new TestCaseSupplier.TypedData(
+                        new BytesRef(new Version(encodedVersion).toString()),
+                        inputType,
+                        "value"
+                    );
+                    return new TestCaseSupplier.TestCase(List.of(typed), stringEvaluator, DataTypes.VERSION, equalTo(encodedVersion));
+                }));
+            }
+        }
+        return parameterSuppliersFromTypedData(errorsForCasesWithoutExamples(anyNullIsNull(true, suppliers)));
+    }
+
+    @Override
+    protected Expression build(Source source, List<Expression> args) {
+        return new ToVersion(source, args.get(0));
+    }
+}

+ 1 - 1
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/AbstractMultivalueFunctionTestCase.java

@@ -119,7 +119,7 @@ public abstract class AbstractMultivalueFunctionTestCase extends AbstractScalarF
     ) {
         cases.add(
             new TestCaseSupplier(
-                name + "(\"\")",
+                name + "(empty string)",
                 () -> new TestCaseSupplier.TestCase(
                     List.of(new TestCaseSupplier.TypedData(List.of(new BytesRef("")), DataTypes.KEYWORD, "field")),
                     evaluatorName + "[field=Attribute[channel=0]]",