Browse Source

ESQL: Improve docs for the floating points is_xxx() funtions (#103691)

Improve the docs for is_nan, is_finite, is_infinite functions.
This also adjusts the CamelCase to snake_case conversion, to not
consider the last capital letter (like in `IsNaN`).
Bogdan Pintea 1 year ago
parent
commit
4e2389fb2c

+ 19 - 0
docs/reference/esql/functions/is_finite.asciidoc

@@ -1,8 +1,27 @@
 [discrete]
 [[esql-is_finite]]
 === `IS_FINITE`
+
+*Syntax*
+
+[.text-center]
+image::esql/functions/signature/is_finite.svg[Embedded,opts=inline]
+
+*Parameters*
+
+`n`::
+Numeric expression. If `null`, the function returns `null`.
+
+*Description*
+
 Returns a boolean that indicates whether its input is a finite number.
 
+*Supported types*
+
+include::types/is_finite.asciidoc[]
+
+*Example*
+
 [source,esql]
 ----
 ROW d = 1.0

+ 20 - 1
docs/reference/esql/functions/is_infinite.asciidoc

@@ -1,7 +1,26 @@
 [discrete]
 [[esql-is_infinite]]
 === `IS_INFINITE`
-Returns a boolean that indicates whether its input is infinite.
+
+*Syntax*
+
+[.text-center]
+image::esql/functions/signature/is_infinite.svg[Embedded,opts=inline]
+
+*Parameters*
+
+`n`::
+Numeric expression. If `null`, the function returns `null`.
+
+*Description*
+
+Returns a boolean that indicates whether its input is an infinite number.
+
+*Supported types*
+
+include::types/is_infinite.asciidoc[]
+
+*Example*
 
 [source,esql]
 ----

+ 20 - 1
docs/reference/esql/functions/is_nan.asciidoc

@@ -1,7 +1,26 @@
 [discrete]
 [[esql-is_nan]]
 === `IS_NAN`
-Returns a boolean that indicates whether its input is not a number.
+
+*Syntax*
+
+[.text-center]
+image::esql/functions/signature/is_nan.svg[Embedded,opts=inline]
+
+*Parameters*
+
+`n`::
+Numeric expression. If `null`, the function returns `null`.
+
+*Description*
+
+Returns a boolean that indicates whether its input is {wikipedia}/NaN[Not-a-Number] (NaN).
+
+*Supported types*
+
+include::types/is_nan.asciidoc[]
+
+*Example*
 
 [source,esql]
 ----

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

@@ -1 +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>
+<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">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="32" height="36" rx="7"/><text class="k" x="195" y="31">n</text><rect class="s" x="227" y="5" width="32" height="36" rx="7"/><text class="syn" x="237" y="31">)</text></svg>

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

@@ -1 +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>
+<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 31h5m152 0h10m32 0h10m32 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="32" height="36" rx="7"/><text class="k" x="219" y="31">n</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/is_nan.svg

@@ -0,0 +1 @@
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="228" height="46" viewbox="0 0 228 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 0h10m32 0h10m32 0h5"/><rect class="s" x="5" y="5" width="92" height="36"/><text class="k" x="15" y="31">IS_NAN</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="32" height="36" rx="7"/><text class="k" x="159" y="31">n</text><rect class="s" x="191" y="5" width="32" height="36" rx="7"/><text class="syn" x="201" y="31">)</text></svg>

+ 1 - 1
docs/reference/esql/functions/types/is_finite.asciidoc

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

+ 1 - 1
docs/reference/esql/functions/types/is_infinite.asciidoc

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

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

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

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

@@ -34,9 +34,9 @@ e                        |? e()
 ends_with                |? ends_with(arg1:?, arg2:?)                             |[arg1, arg2]             |[?, ?]            |["", ""]                                            |?                    | ""                      | [false, false]       | false
 floor                    |"? floor(n:integer|long|double|unsigned_long)"    |n                        |"integer|long|double|unsigned_long"    | ""                                                 |?                    | ""                      | false                | false
 greatest                 |"? greatest(first:integer|long|double|boolean|keyword|text|ip|version, rest...:integer|long|double|boolean|keyword|text|ip|version)"        |[first, rest]            |["integer|long|double|boolean|keyword|text|ip|version", "integer|long|double|boolean|keyword|text|ip|version"]            |["", ""]                                            |?                    | ""                      | [false, false]       | true
-is_finite                |? is_finite(arg1:?)                                     |arg1                     |?                 | ""                                                 |?                    | ""                      | false                | false
-is_infinite              |? is_infinite(arg1:?)                                   |arg1                     |?                 | ""                                                 |?                    | ""                      | false                | false
-is_nan                   |? is_nan(arg1:?)                                        |arg1                     |?                 | ""                                                 |?                    | ""                      | false                | false
+is_finite                |boolean is_finite(n:double)                             |n                        |double            | "A floating-point value"                                                 |boolean              | "Returns true if the argument is a finite floating-point value."                      | false                | false
+is_infinite              |boolean is_infinite(n:double)                           |n                        |double            | "A floating-point value"                                                 |boolean             | "Returns true if the specified floating-point value is infinitely large in magnitude."                      | false                | false
+is_nan                   |boolean is_nan(n:double)                                |n                        |double            | "A floating-point value"                                                 |boolean              | "Returns true if the argument is a Not-a-Number (NaN) value."                      | false                | false
 least                    |"? least(first:integer|long|double|boolean|keyword|text|ip|version, rest...:integer|long|double|boolean|keyword|text|ip|version)"        |[first, rest]            |["integer|long|double|boolean|keyword|text|ip|version", "integer|long|double|boolean|keyword|text|ip|version"]            |["", ""]                                            |?                    | ""                      | [false, false]       | true
 left                     |"? left(string:keyword, length:integer)"                |[string, length]         |["keyword", "integer"]            |["", ""]                                            |?                    | ""                      | [false, false]       | false
 length                   |? length(arg1:?)                                        |arg1                     |?                 | ""                                                 |?                    | ""                      | false                | false
@@ -125,9 +125,9 @@ synopsis:keyword
 ? ends_with(arg1:?, arg2:?)
 "? floor(n:integer|long|double|unsigned_long)"
 "? greatest(first:integer|long|double|boolean|keyword|text|ip|version, rest...:integer|long|double|boolean|keyword|text|ip|version)"
-? is_finite(arg1:?)
-? is_infinite(arg1:?)
-? is_nan(arg1:?)
+boolean is_finite(n:double)
+boolean is_infinite(n:double)
+boolean is_nan(n:double)
 "? least(first:integer|long|double|boolean|keyword|text|ip|version, rest...:integer|long|double|boolean|keyword|text|ip|version)"
 ? left(string:keyword, length:integer)
 ? length(arg1:?)
@@ -188,7 +188,7 @@ synopsis:keyword
 ;
 
 
-showFunctionsFiltered
+showFunctionsFiltered#[skip:-8.12.99]
 // tag::showFunctionsFiltered[]
 SHOW functions 
 | WHERE STARTS_WITH(name, "is_")
@@ -197,9 +197,9 @@ SHOW functions
 
 // tag::showFunctionsFiltered-result[]
        name:keyword      |                        synopsis:keyword                |       argNames:keyword  | argTypes:keyword |             argDescriptions:keyword                |  returnType:keyword   |  description:keyword  |   optionalArgs:boolean |  variadic:boolean
-is_finite                |? is_finite(arg1:?)                                     |arg1                     |?                 |  ""                                                  |?              | ""                      | false                | false
-is_infinite              |? is_infinite(arg1:?)                                   |arg1                     |?                 |  ""                                                  |?              | ""                      | false                | false
-is_nan                   |? is_nan(arg1:?)                                        |arg1                     |?                 |  ""                                                  |?              | ""                      | false                | false
+is_finite                |boolean is_finite(n:double)                             |n                        |double            |  "A floating-point value"                                                  |boolean        | "Returns true if the argument is a finite floating-point value."                      | false                | false
+is_infinite              |boolean is_infinite(n:double)                           |n                        |double            |  "A floating-point value"                                                  |boolean        | "Returns true if the specified floating-point value is infinitely large in magnitude."                      | false                | false
+is_nan                   |boolean is_nan(n:double)                                |n                        |double            |  "A floating-point value"                                                  |boolean        | "Returns true if the argument is a Not-a-Number (NaN) value."                      | false                | false
 // end::showFunctionsFiltered-result[]
 ;
 

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

@@ -9,6 +9,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.math;
 
 import org.elasticsearch.compute.ann.Evaluator;
 import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator;
+import org.elasticsearch.xpack.esql.expression.function.FunctionInfo;
+import org.elasticsearch.xpack.esql.expression.function.Param;
 import org.elasticsearch.xpack.ql.expression.Expression;
 import org.elasticsearch.xpack.ql.tree.NodeInfo;
 import org.elasticsearch.xpack.ql.tree.Source;
@@ -17,7 +19,9 @@ import java.util.List;
 import java.util.function.Function;
 
 public class IsFinite extends RationalUnaryPredicate {
-    public IsFinite(Source source, Expression field) {
+
+    @FunctionInfo(returnType = "boolean", description = "Returns true if the argument is a finite floating-point value.")
+    public IsFinite(Source source, @Param(name = "n", type = { "double" }, description = "A floating-point value") Expression field) {
         super(source, field);
     }
 

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

@@ -9,6 +9,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.math;
 
 import org.elasticsearch.compute.ann.Evaluator;
 import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator;
+import org.elasticsearch.xpack.esql.expression.function.FunctionInfo;
+import org.elasticsearch.xpack.esql.expression.function.Param;
 import org.elasticsearch.xpack.ql.expression.Expression;
 import org.elasticsearch.xpack.ql.tree.NodeInfo;
 import org.elasticsearch.xpack.ql.tree.Source;
@@ -17,7 +19,12 @@ import java.util.List;
 import java.util.function.Function;
 
 public class IsInfinite extends RationalUnaryPredicate {
-    public IsInfinite(Source source, Expression field) {
+
+    @FunctionInfo(
+        returnType = "boolean",
+        description = "Returns true if the specified floating-point value is infinitely large in magnitude."
+    )
+    public IsInfinite(Source source, @Param(name = "n", type = { "double" }, description = "A floating-point value") Expression field) {
         super(source, field);
     }
 

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

@@ -9,6 +9,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.math;
 
 import org.elasticsearch.compute.ann.Evaluator;
 import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator;
+import org.elasticsearch.xpack.esql.expression.function.FunctionInfo;
+import org.elasticsearch.xpack.esql.expression.function.Param;
 import org.elasticsearch.xpack.ql.expression.Expression;
 import org.elasticsearch.xpack.ql.tree.NodeInfo;
 import org.elasticsearch.xpack.ql.tree.Source;
@@ -17,7 +19,9 @@ import java.util.List;
 import java.util.function.Function;
 
 public class IsNaN extends RationalUnaryPredicate {
-    public IsNaN(Source source, Expression field) {
+
+    @FunctionInfo(returnType = "boolean", description = "Returns true if the argument is a Not-a-Number (NaN) value.")
+    public IsNaN(Source source, @Param(name = "n", type = { "double" }, description = "A floating-point value") Expression field) {
         super(source, field);
     }
 

+ 3 - 2
x-pack/plugin/ql/src/main/java/org/elasticsearch/xpack/ql/util/StringUtils.java

@@ -44,7 +44,7 @@ public final class StringUtils {
 
     private static final String INVALID_REGEX_SEQUENCE = "Invalid sequence - escape character is not followed by special wildcard char";
 
-    // CamelCase to camel_case
+    // CamelCase to camel_case (and isNaN to is_nan)
     public static String camelCaseToUnderscore(String string) {
         if (Strings.hasText(string) == false) {
             return EMPTY;
@@ -57,7 +57,8 @@ public final class StringUtils {
             char ch = s.charAt(i);
             if (Character.isAlphabetic(ch)) {
                 if (Character.isUpperCase(ch)) {
-                    if (i > 0 && previousCharWasUp == false) {
+                    // append `_` when encountering a capital after a small letter, but only if not the last letter.
+                    if (i > 0 && i < s.length() - 1 && previousCharWasUp == false) {
                         sb.append("_");
                     }
                     previousCharWasUp = true;