Selaa lähdekoodia

ESQL: Add counters to signature for `IS NULL` (#129670)

This adds `counter_long` and `counter_double` to the signatures of
supported fields for `IS NULL` and `IS NOT NULL`. We hadn't been
generating those signatures since the docs v3 migration, so this had to
plug those in. In addition, it changes the wording on a few things and
adds a note that if a field is only in some documents then the ones
missing the field will have `NULL` - which is important information for
`IS NULL` and `IS NOT NULL`.
Nik Everett 3 kuukautta sitten
vanhempi
commit
59a10bdd7b

+ 6 - 0
docs/reference/query-languages/esql/_snippets/operators/detailedDescription/is_not_null.md

@@ -0,0 +1,6 @@
+
+::::{note}
+If a field is only in some documents it will be `NULL` in the documents that did not contain it.
+::::
+
+

+ 6 - 0
docs/reference/query-languages/esql/_snippets/operators/detailedDescription/is_null.md

@@ -0,0 +1,6 @@
+
+::::{note}
+If a field is only in some documents it will be `NULL` in the documents that did not contain it.
+::::
+
+

+ 3 - 0
docs/reference/query-languages/esql/_snippets/operators/types/is_not_null.md

@@ -7,6 +7,9 @@
 | boolean | boolean |
 | cartesian_point | boolean |
 | cartesian_shape | boolean |
+| counter_double | boolean |
+| counter_integer | boolean |
+| counter_long | boolean |
 | date | boolean |
 | date_nanos | boolean |
 | double | boolean |

+ 3 - 0
docs/reference/query-languages/esql/_snippets/operators/types/is_null.md

@@ -7,6 +7,9 @@
 | boolean | boolean |
 | cartesian_point | boolean |
 | cartesian_shape | boolean |
+| counter_double | boolean |
+| counter_integer | boolean |
+| counter_long | boolean |
 | date | boolean |
 | date_nanos | boolean |
 | double | boolean |

+ 53 - 19
docs/reference/query-languages/esql/kibana/definition/operators/is_not_null.json

@@ -3,7 +3,8 @@
   "type" : "operator",
   "operator" : "IS NOT NULL",
   "name" : "is_not_null",
-  "description" : "Use `IS NOT NULL` to filter data based on whether the field exists or not.",
+  "description" : "Returns `false` if the value is `NULL`, `true` otherwise.",
+  "note" : "If a field is only in some documents it will be `NULL` in the documents that did not contain it.",
   "signatures" : [
     {
       "params" : [
@@ -11,7 +12,7 @@
           "name" : "field",
           "type" : "boolean",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -23,7 +24,7 @@
           "name" : "field",
           "type" : "cartesian_point",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -35,7 +36,43 @@
           "name" : "field",
           "type" : "cartesian_shape",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "boolean"
+    },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "counter_double",
+          "optional" : false,
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "boolean"
+    },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "counter_integer",
+          "optional" : false,
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "boolean"
+    },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "counter_long",
+          "optional" : false,
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -47,7 +84,7 @@
           "name" : "field",
           "type" : "date",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -59,7 +96,7 @@
           "name" : "field",
           "type" : "date_nanos",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -71,7 +108,7 @@
           "name" : "field",
           "type" : "double",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -83,7 +120,7 @@
           "name" : "field",
           "type" : "geo_point",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -95,7 +132,7 @@
           "name" : "field",
           "type" : "geo_shape",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -107,7 +144,7 @@
           "name" : "field",
           "type" : "integer",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -119,7 +156,7 @@
           "name" : "field",
           "type" : "ip",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -131,7 +168,7 @@
           "name" : "field",
           "type" : "keyword",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -143,7 +180,7 @@
           "name" : "field",
           "type" : "long",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -155,7 +192,7 @@
           "name" : "field",
           "type" : "text",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -167,7 +204,7 @@
           "name" : "field",
           "type" : "unsigned_long",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -179,16 +216,13 @@
           "name" : "field",
           "type" : "version",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
       "returnType" : "boolean"
     }
   ],
-  "examples" : [
-    "FROM employees\n| WHERE is_rehired IS NOT NULL\n| STATS COUNT(emp_no)"
-  ],
   "preview" : false,
   "snapshot_only" : false
 }

+ 53 - 19
docs/reference/query-languages/esql/kibana/definition/operators/is_null.json

@@ -3,7 +3,8 @@
   "type" : "operator",
   "operator" : "IS NULL",
   "name" : "is_null",
-  "description" : "Use `IS NULL` to filter data based on whether the field exists or not.",
+  "description" : "Returns `true` if the value is `NULL`, `false` otherwise.",
+  "note" : "If a field is only in some documents it will be `NULL` in the documents that did not contain it.",
   "signatures" : [
     {
       "params" : [
@@ -11,7 +12,7 @@
           "name" : "field",
           "type" : "boolean",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -23,7 +24,7 @@
           "name" : "field",
           "type" : "cartesian_point",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -35,7 +36,43 @@
           "name" : "field",
           "type" : "cartesian_shape",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "boolean"
+    },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "counter_double",
+          "optional" : false,
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "boolean"
+    },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "counter_integer",
+          "optional" : false,
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "boolean"
+    },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "counter_long",
+          "optional" : false,
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -47,7 +84,7 @@
           "name" : "field",
           "type" : "date",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -59,7 +96,7 @@
           "name" : "field",
           "type" : "date_nanos",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -71,7 +108,7 @@
           "name" : "field",
           "type" : "double",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -83,7 +120,7 @@
           "name" : "field",
           "type" : "geo_point",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -95,7 +132,7 @@
           "name" : "field",
           "type" : "geo_shape",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -107,7 +144,7 @@
           "name" : "field",
           "type" : "integer",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -119,7 +156,7 @@
           "name" : "field",
           "type" : "ip",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -131,7 +168,7 @@
           "name" : "field",
           "type" : "keyword",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -143,7 +180,7 @@
           "name" : "field",
           "type" : "long",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -155,7 +192,7 @@
           "name" : "field",
           "type" : "text",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -167,7 +204,7 @@
           "name" : "field",
           "type" : "unsigned_long",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
@@ -179,16 +216,13 @@
           "name" : "field",
           "type" : "version",
           "optional" : false,
-          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+          "description" : "Value to check. It can be a single- or multi-valued column or an expression."
         }
       ],
       "variadic" : false,
       "returnType" : "boolean"
     }
   ],
-  "examples" : [
-    "FROM employees\n| WHERE birth_date IS NULL"
-  ],
   "preview" : false,
   "snapshot_only" : false
 }

+ 2 - 6
docs/reference/query-languages/esql/kibana/docs/operators/is_not_null.md

@@ -1,10 +1,6 @@
 % This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it.
 
 ### IS NOT NULL
-Use `IS NOT NULL` to filter data based on whether the field exists or not.
+Returns `false` if the value is `NULL`, `true` otherwise.
 
-```esql
-FROM employees
-| WHERE is_rehired IS NOT NULL
-| STATS COUNT(emp_no)
-```
+Note: If a field is only in some documents it will be `NULL` in the documents that did not contain it.

+ 2 - 5
docs/reference/query-languages/esql/kibana/docs/operators/is_null.md

@@ -1,9 +1,6 @@
 % This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it.
 
 ### IS NULL
-Use `IS NULL` to filter data based on whether the field exists or not.
+Returns `true` if the value is `NULL`, `false` otherwise.
 
-```esql
-FROM employees
-| WHERE birth_date IS NULL
-```
+Note: If a field is only in some documents it will be `NULL` in the documents that did not contain it.

+ 38 - 1
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/nulls/IsNotNull.java

@@ -25,6 +25,8 @@ import org.elasticsearch.xpack.esql.core.tree.NodeInfo;
 import org.elasticsearch.xpack.esql.core.tree.Source;
 import org.elasticsearch.xpack.esql.core.type.DataType;
 import org.elasticsearch.xpack.esql.evaluator.mapper.EvaluatorMapper;
+import org.elasticsearch.xpack.esql.expression.function.FunctionInfo;
+import org.elasticsearch.xpack.esql.expression.function.Param;
 import org.elasticsearch.xpack.esql.optimizer.rules.physical.local.LucenePushdownPredicates;
 import org.elasticsearch.xpack.esql.planner.TranslatorHandler;
 
@@ -37,7 +39,42 @@ public class IsNotNull extends UnaryScalarFunction implements EvaluatorMapper, N
         IsNotNull::new
     );
 
-    public IsNotNull(Source source, Expression field) {
+    @FunctionInfo(
+        description = "Returns `false` if the value is `NULL`, `true` otherwise.",
+        note = "If a field is only in some documents it will be `NULL` in the documents that did not contain it.",
+        operator = "IS NOT NULL",
+        returnType = {
+            "double",
+            "integer",
+            "long",
+            "date_nanos",
+            "date_period",
+            "datetime",
+            "time_duration",
+            "unsigned_long",
+            "counter_long",
+            "counter_integer",
+            "counter_double" }
+    )
+    public IsNotNull(
+        Source source,
+        @Param(
+            name = "field",
+            description = "Value to check. It can be a single- or multi-valued column or an expression.",
+            type = {
+                "double",
+                "integer",
+                "long",
+                "date_nanos",
+                "date_period",
+                "datetime",
+                "time_duration",
+                "unsigned_long",
+                "counter_long",
+                "counter_integer",
+                "counter_double" }
+        ) Expression field
+    ) {
         super(source, field);
     }
 

+ 38 - 1
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/nulls/IsNull.java

@@ -26,6 +26,8 @@ import org.elasticsearch.xpack.esql.core.tree.NodeInfo;
 import org.elasticsearch.xpack.esql.core.tree.Source;
 import org.elasticsearch.xpack.esql.core.type.DataType;
 import org.elasticsearch.xpack.esql.evaluator.mapper.EvaluatorMapper;
+import org.elasticsearch.xpack.esql.expression.function.FunctionInfo;
+import org.elasticsearch.xpack.esql.expression.function.Param;
 import org.elasticsearch.xpack.esql.optimizer.rules.physical.local.LucenePushdownPredicates;
 import org.elasticsearch.xpack.esql.planner.TranslatorHandler;
 
@@ -34,7 +36,42 @@ import java.io.IOException;
 public class IsNull extends UnaryScalarFunction implements EvaluatorMapper, Negatable<UnaryScalarFunction>, TranslationAware {
     public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "IsNull", IsNull::new);
 
-    public IsNull(Source source, Expression field) {
+    @FunctionInfo(
+        description = "Returns `true` if the value is `NULL`, `false` otherwise.",
+        note = "If a field is only in some documents it will be `NULL` in the documents that did not contain it.",
+        operator = "IS NULL",
+        returnType = {
+            "double",
+            "integer",
+            "long",
+            "date_nanos",
+            "date_period",
+            "datetime",
+            "time_duration",
+            "unsigned_long",
+            "counter_long",
+            "counter_integer",
+            "counter_double" }
+    )
+    public IsNull(
+        Source source,
+        @Param(
+            name = "field",
+            description = "Value to check. It can be a single- or multi-valued column or an expression.",
+            type = {
+                "double",
+                "integer",
+                "long",
+                "date_nanos",
+                "date_period",
+                "datetime",
+                "time_duration",
+                "unsigned_long",
+                "counter_long",
+                "counter_integer",
+                "counter_double" }
+        ) Expression field
+    ) {
         super(source, field);
     }
 

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

@@ -34,7 +34,7 @@ public class IsNotNullTests extends AbstractScalarFunctionTestCase {
     public static Iterable<Object[]> parameters() {
         List<TestCaseSupplier> suppliers = new ArrayList<>();
         for (DataType type : DataType.types()) {
-            if (false == DataType.isRepresentable(type)) {
+            if (false == type.isCounter() && false == DataType.isRepresentable(type)) {
                 continue;
             }
             if (type != DataType.NULL) {

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

@@ -34,7 +34,7 @@ public class IsNullTests extends AbstractScalarFunctionTestCase {
     public static Iterable<Object[]> parameters() {
         List<TestCaseSupplier> suppliers = new ArrayList<>();
         for (DataType type : DataType.types()) {
-            if (false == DataType.isRepresentable(type)) {
+            if (false == type.isCounter() && false == DataType.isRepresentable(type)) {
                 continue;
             }
             if (type != DataType.NULL) {