瀏覽代碼

[8.x] Esql Enable Date Nanos (#117080) (#117161)

* Esql Enable Date Nanos (#117080)

This enables date nanos support as tech preview. Basic operations, like reading values, binary comparisons, and functions that don't care about type should work, but some functions are not yet supported. Most notably, Bucket is not yet supported, although Date_Trunc is and can be used for grouping. See the docs for the full list of limitations.

relates to #109352

* Skip CATEGORIZE tests outside snapshot

---------

Co-authored-by: Nik Everett <nik9000@gmail.com>
Mark Tozzi 10 月之前
父節點
當前提交
cafa440771
共有 78 個文件被更改,包括 719 次插入40 次删除
  1. 5 0
      docs/changelog/117080.yaml
  2. 3 1
      docs/reference/esql/esql-limitations.asciidoc
  3. 42 0
      docs/reference/esql/functions/kibana/definition/case.json
  4. 18 0
      docs/reference/esql/functions/kibana/definition/coalesce.json
  5. 1 1
      docs/reference/esql/functions/kibana/definition/count.json
  6. 66 0
      docs/reference/esql/functions/kibana/definition/count_distinct.json
  7. 36 0
      docs/reference/esql/functions/kibana/definition/date_trunc.json
  8. 18 0
      docs/reference/esql/functions/kibana/definition/equals.json
  9. 18 0
      docs/reference/esql/functions/kibana/definition/greater_than.json
  10. 18 0
      docs/reference/esql/functions/kibana/definition/greater_than_or_equal.json
  11. 18 0
      docs/reference/esql/functions/kibana/definition/greatest.json
  12. 18 0
      docs/reference/esql/functions/kibana/definition/least.json
  13. 18 0
      docs/reference/esql/functions/kibana/definition/less_than.json
  14. 18 0
      docs/reference/esql/functions/kibana/definition/less_than_or_equal.json
  15. 1 1
      docs/reference/esql/functions/kibana/definition/match.json
  16. 12 0
      docs/reference/esql/functions/kibana/definition/max.json
  17. 12 0
      docs/reference/esql/functions/kibana/definition/min.json
  18. 12 0
      docs/reference/esql/functions/kibana/definition/mv_count.json
  19. 12 0
      docs/reference/esql/functions/kibana/definition/mv_dedupe.json
  20. 12 0
      docs/reference/esql/functions/kibana/definition/mv_first.json
  21. 12 0
      docs/reference/esql/functions/kibana/definition/mv_last.json
  22. 12 0
      docs/reference/esql/functions/kibana/definition/mv_max.json
  23. 12 0
      docs/reference/esql/functions/kibana/definition/mv_min.json
  24. 24 0
      docs/reference/esql/functions/kibana/definition/mv_slice.json
  25. 18 0
      docs/reference/esql/functions/kibana/definition/mv_sort.json
  26. 18 0
      docs/reference/esql/functions/kibana/definition/not_equals.json
  27. 1 1
      docs/reference/esql/functions/kibana/definition/qstr.json
  28. 86 1
      docs/reference/esql/functions/kibana/definition/to_date_nanos.json
  29. 12 0
      docs/reference/esql/functions/kibana/definition/to_datetime.json
  30. 12 0
      docs/reference/esql/functions/kibana/definition/to_long.json
  31. 12 0
      docs/reference/esql/functions/kibana/definition/to_string.json
  32. 12 0
      docs/reference/esql/functions/kibana/definition/values.json
  33. 5 5
      docs/reference/esql/functions/kibana/docs/match.md
  34. 5 5
      docs/reference/esql/functions/kibana/docs/qstr.md
  35. 2 0
      docs/reference/esql/functions/types/case.asciidoc
  36. 1 0
      docs/reference/esql/functions/types/coalesce.asciidoc
  37. 4 0
      docs/reference/esql/functions/types/count_distinct.asciidoc
  38. 2 0
      docs/reference/esql/functions/types/date_trunc.asciidoc
  39. 1 0
      docs/reference/esql/functions/types/equals.asciidoc
  40. 1 0
      docs/reference/esql/functions/types/greater_than.asciidoc
  41. 1 0
      docs/reference/esql/functions/types/greater_than_or_equal.asciidoc
  42. 1 0
      docs/reference/esql/functions/types/greatest.asciidoc
  43. 1 0
      docs/reference/esql/functions/types/least.asciidoc
  44. 1 0
      docs/reference/esql/functions/types/less_than.asciidoc
  45. 1 0
      docs/reference/esql/functions/types/less_than_or_equal.asciidoc
  46. 1 0
      docs/reference/esql/functions/types/max.asciidoc
  47. 1 0
      docs/reference/esql/functions/types/min.asciidoc
  48. 1 0
      docs/reference/esql/functions/types/mv_count.asciidoc
  49. 1 0
      docs/reference/esql/functions/types/mv_dedupe.asciidoc
  50. 1 0
      docs/reference/esql/functions/types/mv_first.asciidoc
  51. 1 0
      docs/reference/esql/functions/types/mv_last.asciidoc
  52. 1 0
      docs/reference/esql/functions/types/mv_max.asciidoc
  53. 1 0
      docs/reference/esql/functions/types/mv_min.asciidoc
  54. 1 0
      docs/reference/esql/functions/types/mv_slice.asciidoc
  55. 1 0
      docs/reference/esql/functions/types/mv_sort.asciidoc
  56. 1 0
      docs/reference/esql/functions/types/not_equals.asciidoc
  57. 7 1
      docs/reference/esql/functions/types/to_date_nanos.asciidoc
  58. 1 0
      docs/reference/esql/functions/types/to_datetime.asciidoc
  59. 1 0
      docs/reference/esql/functions/types/to_long.asciidoc
  60. 1 0
      docs/reference/esql/functions/types/to_string.asciidoc
  61. 1 0
      docs/reference/esql/functions/types/values.asciidoc
  62. 0 1
      x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/plugin/EsqlCorePlugin.java
  63. 0 1
      x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java
  64. 6 6
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java
  65. 2 0
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java
  66. 2 2
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Max.java
  67. 2 2
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Min.java
  68. 5 2
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Values.java
  69. 2 2
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/date/DateTrunc.java
  70. 2 2
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/LessThan.java
  71. 3 0
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java
  72. 36 0
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/MultiRowTestCaseSupplier.java
  73. 1 0
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/CountDistinctTests.java
  74. 9 0
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/MaxTests.java
  75. 9 0
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/MinTests.java
  76. 1 0
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/ValuesTests.java
  77. 0 4
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/AbstractMultivalueFunctionTestCase.java
  78. 2 2
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/LessThanTests.java

+ 5 - 0
docs/changelog/117080.yaml

@@ -0,0 +1,5 @@
+pr: 117080
+summary: Esql Enable Date Nanos (tech preview)
+area: ES|QL
+type: enhancement
+issues: []

+ 3 - 1
docs/reference/esql/esql-limitations.asciidoc

@@ -25,6 +25,9 @@ include::processing-commands/limit.asciidoc[tag=limitation]
 * `alias`
 * `boolean`
 * `date`
+* `date_nanos` (Tech Preview)
+** The following functions don't yet support date nanos: `bucket`, `date_format`, `date_parse`, `date_diff`, `date_extract`
+** You can use `to_datetime` to cast to millisecond dates to use unsupported functions
 * `double` (`float`, `half_float`, `scaled_float` are represented as `double`)
 * `ip`
 * `keyword` family including `keyword`, `constant_keyword`, and `wildcard`
@@ -50,7 +53,6 @@ include::processing-commands/limit.asciidoc[tag=limitation]
 ** `position`
 ** `aggregate_metric_double`
 * Date/time
-** `date_nanos`
 ** `date_range`
 * Other types
 ** `binary`

+ 42 - 0
docs/reference/esql/functions/kibana/definition/case.json

@@ -172,6 +172,48 @@
       "variadic" : true,
       "returnType" : "date"
     },
+    {
+      "params" : [
+        {
+          "name" : "condition",
+          "type" : "boolean",
+          "optional" : false,
+          "description" : "A condition."
+        },
+        {
+          "name" : "trueValue",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "The value that's returned when the corresponding condition is the first to evaluate to `true`. The default value is returned when no condition matches."
+        }
+      ],
+      "variadic" : true,
+      "returnType" : "date_nanos"
+    },
+    {
+      "params" : [
+        {
+          "name" : "condition",
+          "type" : "boolean",
+          "optional" : false,
+          "description" : "A condition."
+        },
+        {
+          "name" : "trueValue",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "The value that's returned when the corresponding condition is the first to evaluate to `true`. The default value is returned when no condition matches."
+        },
+        {
+          "name" : "elseValue",
+          "type" : "date_nanos",
+          "optional" : true,
+          "description" : "The value that's returned when no condition evaluates to `true`."
+        }
+      ],
+      "variadic" : true,
+      "returnType" : "date_nanos"
+    },
     {
       "params" : [
         {

+ 18 - 0
docs/reference/esql/functions/kibana/definition/coalesce.json

@@ -88,6 +88,24 @@
       "variadic" : true,
       "returnType" : "date"
     },
+    {
+      "params" : [
+        {
+          "name" : "first",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "Expression to evaluate."
+        },
+        {
+          "name" : "rest",
+          "type" : "date_nanos",
+          "optional" : true,
+          "description" : "Other expression to evaluate."
+        }
+      ],
+      "variadic" : true,
+      "returnType" : "date_nanos"
+    },
     {
       "params" : [
         {

+ 1 - 1
docs/reference/esql/functions/kibana/definition/count.json

@@ -151,7 +151,7 @@
   ],
   "examples" : [
     "FROM employees\n| STATS COUNT(height)",
-    "FROM employees \n| STATS count = COUNT(*) BY languages \n| SORT languages DESC",
+    "FROM employees\n| STATS count = COUNT(*) BY languages\n| SORT languages DESC",
     "ROW words=\"foo;bar;baz;qux;quux;foo\"\n| STATS word_count = COUNT(SPLIT(words, \";\"))",
     "ROW n=1\n| WHERE n < 0\n| STATS COUNT(n)",
     "ROW n=1\n| STATS COUNT(n > 0 OR NULL), COUNT(n < 0 OR NULL)"

+ 66 - 0
docs/reference/esql/functions/kibana/definition/count_distinct.json

@@ -136,6 +136,72 @@
       "variadic" : false,
       "returnType" : "long"
     },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "Column or literal for which to count the number of distinct values."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "long"
+    },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "Column or literal for which to count the number of distinct values."
+        },
+        {
+          "name" : "precision",
+          "type" : "integer",
+          "optional" : true,
+          "description" : "Precision threshold. Refer to <<esql-agg-count-distinct-approximate>>. The maximum supported value is 40000. Thresholds above this number will have the same effect as a threshold of 40000. The default value is 3000."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "long"
+    },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "Column or literal for which to count the number of distinct values."
+        },
+        {
+          "name" : "precision",
+          "type" : "long",
+          "optional" : true,
+          "description" : "Precision threshold. Refer to <<esql-agg-count-distinct-approximate>>. The maximum supported value is 40000. Thresholds above this number will have the same effect as a threshold of 40000. The default value is 3000."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "long"
+    },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "Column or literal for which to count the number of distinct values."
+        },
+        {
+          "name" : "precision",
+          "type" : "unsigned_long",
+          "optional" : true,
+          "description" : "Precision threshold. Refer to <<esql-agg-count-distinct-approximate>>. The maximum supported value is 40000. Thresholds above this number will have the same effect as a threshold of 40000. The default value is 3000."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "long"
+    },
     {
       "params" : [
         {

+ 36 - 0
docs/reference/esql/functions/kibana/definition/date_trunc.json

@@ -22,6 +22,24 @@
       "variadic" : false,
       "returnType" : "date"
     },
+    {
+      "params" : [
+        {
+          "name" : "interval",
+          "type" : "date_period",
+          "optional" : false,
+          "description" : "Interval; expressed using the timespan literal syntax."
+        },
+        {
+          "name" : "date",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "Date expression"
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "date_nanos"
+    },
     {
       "params" : [
         {
@@ -39,6 +57,24 @@
       ],
       "variadic" : false,
       "returnType" : "date"
+    },
+    {
+      "params" : [
+        {
+          "name" : "interval",
+          "type" : "time_duration",
+          "optional" : false,
+          "description" : "Interval; expressed using the timespan literal syntax."
+        },
+        {
+          "name" : "date",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "Date expression"
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "date_nanos"
     }
   ],
   "examples" : [

+ 18 - 0
docs/reference/esql/functions/kibana/definition/equals.json

@@ -77,6 +77,24 @@
       "variadic" : false,
       "returnType" : "boolean"
     },
+    {
+      "params" : [
+        {
+          "name" : "lhs",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "An expression."
+        },
+        {
+          "name" : "rhs",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "An expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "boolean"
+    },
     {
       "params" : [
         {

+ 18 - 0
docs/reference/esql/functions/kibana/definition/greater_than.json

@@ -23,6 +23,24 @@
       "variadic" : false,
       "returnType" : "boolean"
     },
+    {
+      "params" : [
+        {
+          "name" : "lhs",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "An expression."
+        },
+        {
+          "name" : "rhs",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "An expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "boolean"
+    },
     {
       "params" : [
         {

+ 18 - 0
docs/reference/esql/functions/kibana/definition/greater_than_or_equal.json

@@ -23,6 +23,24 @@
       "variadic" : false,
       "returnType" : "boolean"
     },
+    {
+      "params" : [
+        {
+          "name" : "lhs",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "An expression."
+        },
+        {
+          "name" : "rhs",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "An expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "boolean"
+    },
     {
       "params" : [
         {

+ 18 - 0
docs/reference/esql/functions/kibana/definition/greatest.json

@@ -53,6 +53,24 @@
       "variadic" : true,
       "returnType" : "date"
     },
+    {
+      "params" : [
+        {
+          "name" : "first",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "First of the columns to evaluate."
+        },
+        {
+          "name" : "rest",
+          "type" : "date_nanos",
+          "optional" : true,
+          "description" : "The rest of the columns to evaluate."
+        }
+      ],
+      "variadic" : true,
+      "returnType" : "date_nanos"
+    },
     {
       "params" : [
         {

+ 18 - 0
docs/reference/esql/functions/kibana/definition/least.json

@@ -52,6 +52,24 @@
       "variadic" : true,
       "returnType" : "date"
     },
+    {
+      "params" : [
+        {
+          "name" : "first",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "First of the columns to evaluate."
+        },
+        {
+          "name" : "rest",
+          "type" : "date_nanos",
+          "optional" : true,
+          "description" : "The rest of the columns to evaluate."
+        }
+      ],
+      "variadic" : true,
+      "returnType" : "date_nanos"
+    },
     {
       "params" : [
         {

+ 18 - 0
docs/reference/esql/functions/kibana/definition/less_than.json

@@ -23,6 +23,24 @@
       "variadic" : false,
       "returnType" : "boolean"
     },
+    {
+      "params" : [
+        {
+          "name" : "lhs",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "An expression."
+        },
+        {
+          "name" : "rhs",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "An expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "boolean"
+    },
     {
       "params" : [
         {

+ 18 - 0
docs/reference/esql/functions/kibana/definition/less_than_or_equal.json

@@ -23,6 +23,24 @@
       "variadic" : false,
       "returnType" : "boolean"
     },
+    {
+      "params" : [
+        {
+          "name" : "lhs",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "An expression."
+        },
+        {
+          "name" : "rhs",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "An expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "boolean"
+    },
     {
       "params" : [
         {

+ 1 - 1
docs/reference/esql/functions/kibana/definition/match.json

@@ -78,7 +78,7 @@
     }
   ],
   "examples" : [
-    "from books \n| where match(author, \"Faulkner\")\n| keep book_no, author \n| sort book_no \n| limit 5;"
+    "FROM books \n| WHERE MATCH(author, \"Faulkner\")\n| KEEP book_no, author \n| SORT book_no \n| LIMIT 5;"
   ],
   "preview" : true,
   "snapshot_only" : false

+ 12 - 0
docs/reference/esql/functions/kibana/definition/max.json

@@ -28,6 +28,18 @@
       "variadic" : false,
       "returnType" : "date"
     },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : ""
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "date_nanos"
+    },
     {
       "params" : [
         {

+ 12 - 0
docs/reference/esql/functions/kibana/definition/min.json

@@ -28,6 +28,18 @@
       "variadic" : false,
       "returnType" : "date"
     },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : ""
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "date_nanos"
+    },
     {
       "params" : [
         {

+ 12 - 0
docs/reference/esql/functions/kibana/definition/mv_count.json

@@ -52,6 +52,18 @@
       "variadic" : false,
       "returnType" : "integer"
     },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "Multivalue expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "integer"
+    },
     {
       "params" : [
         {

+ 12 - 0
docs/reference/esql/functions/kibana/definition/mv_dedupe.json

@@ -53,6 +53,18 @@
       "variadic" : false,
       "returnType" : "date"
     },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "Multivalue expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "date_nanos"
+    },
     {
       "params" : [
         {

+ 12 - 0
docs/reference/esql/functions/kibana/definition/mv_first.json

@@ -52,6 +52,18 @@
       "variadic" : false,
       "returnType" : "date"
     },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "Multivalue expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "date_nanos"
+    },
     {
       "params" : [
         {

+ 12 - 0
docs/reference/esql/functions/kibana/definition/mv_last.json

@@ -52,6 +52,18 @@
       "variadic" : false,
       "returnType" : "date"
     },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "Multivalue expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "date_nanos"
+    },
     {
       "params" : [
         {

+ 12 - 0
docs/reference/esql/functions/kibana/definition/mv_max.json

@@ -28,6 +28,18 @@
       "variadic" : false,
       "returnType" : "date"
     },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "Multivalue expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "date_nanos"
+    },
     {
       "params" : [
         {

+ 12 - 0
docs/reference/esql/functions/kibana/definition/mv_min.json

@@ -28,6 +28,18 @@
       "variadic" : false,
       "returnType" : "date"
     },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "Multivalue expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "date_nanos"
+    },
     {
       "params" : [
         {

+ 24 - 0
docs/reference/esql/functions/kibana/definition/mv_slice.json

@@ -100,6 +100,30 @@
       "variadic" : false,
       "returnType" : "date"
     },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "Multivalue expression. If `null`, the function returns `null`."
+        },
+        {
+          "name" : "start",
+          "type" : "integer",
+          "optional" : false,
+          "description" : "Start position. If `null`, the function returns `null`. The start argument can be negative. An index of -1 is used to specify the last value in the list."
+        },
+        {
+          "name" : "end",
+          "type" : "integer",
+          "optional" : true,
+          "description" : "End position(included). Optional; if omitted, the position at `start` is returned. The end argument can be negative. An index of -1 is used to specify the last value in the list."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "date_nanos"
+    },
     {
       "params" : [
         {

+ 18 - 0
docs/reference/esql/functions/kibana/definition/mv_sort.json

@@ -40,6 +40,24 @@
       "variadic" : false,
       "returnType" : "date"
     },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "Multivalue expression. If `null`, the function returns `null`."
+        },
+        {
+          "name" : "order",
+          "type" : "keyword",
+          "optional" : true,
+          "description" : "Sort order. The valid options are ASC and DESC, the default is ASC."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "date_nanos"
+    },
     {
       "params" : [
         {

+ 18 - 0
docs/reference/esql/functions/kibana/definition/not_equals.json

@@ -77,6 +77,24 @@
       "variadic" : false,
       "returnType" : "boolean"
     },
+    {
+      "params" : [
+        {
+          "name" : "lhs",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "An expression."
+        },
+        {
+          "name" : "rhs",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "An expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "boolean"
+    },
     {
       "params" : [
         {

+ 1 - 1
docs/reference/esql/functions/kibana/definition/qstr.json

@@ -30,7 +30,7 @@
     }
   ],
   "examples" : [
-    "from books \n| where qstr(\"author: Faulkner\")\n| keep book_no, author \n| sort book_no \n| limit 5;"
+    "FROM books \n| WHERE QSTR(\"author: Faulkner\")\n| KEEP book_no, author \n| SORT book_no \n| LIMIT 5;"
   ],
   "preview" : true,
   "snapshot_only" : false

+ 86 - 1
docs/reference/esql/functions/kibana/definition/to_date_nanos.json

@@ -4,7 +4,92 @@
   "name" : "to_date_nanos",
   "description" : "Converts an input to a nanosecond-resolution date value (aka date_nanos).",
   "note" : "The range for date nanos is 1970-01-01T00:00:00.000000000Z to 2262-04-11T23:47:16.854775807Z.  Additionally, integers cannot be converted into date nanos, as the range of integer nanoseconds only covers about 2 seconds after epoch.",
-  "signatures" : [ ],
+  "signatures" : [
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "date",
+          "optional" : false,
+          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "date_nanos"
+    },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "date_nanos"
+    },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "double",
+          "optional" : false,
+          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "date_nanos"
+    },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "keyword",
+          "optional" : false,
+          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "date_nanos"
+    },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "long",
+          "optional" : false,
+          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "date_nanos"
+    },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "text",
+          "optional" : false,
+          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "date_nanos"
+    },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "unsigned_long",
+          "optional" : false,
+          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "date_nanos"
+    }
+  ],
   "preview" : true,
   "snapshot_only" : false
 }

+ 12 - 0
docs/reference/esql/functions/kibana/definition/to_datetime.json

@@ -17,6 +17,18 @@
       "variadic" : false,
       "returnType" : "date"
     },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "date"
+    },
     {
       "params" : [
         {

+ 12 - 0
docs/reference/esql/functions/kibana/definition/to_long.json

@@ -52,6 +52,18 @@
       "variadic" : false,
       "returnType" : "long"
     },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "long"
+    },
     {
       "params" : [
         {

+ 12 - 0
docs/reference/esql/functions/kibana/definition/to_string.json

@@ -52,6 +52,18 @@
       "variadic" : false,
       "returnType" : "keyword"
     },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : "Input value. The input can be a single- or multi-valued column or an expression."
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "keyword"
+    },
     {
       "params" : [
         {

+ 12 - 0
docs/reference/esql/functions/kibana/definition/values.json

@@ -28,6 +28,18 @@
       "variadic" : false,
       "returnType" : "date"
     },
+    {
+      "params" : [
+        {
+          "name" : "field",
+          "type" : "date_nanos",
+          "optional" : false,
+          "description" : ""
+        }
+      ],
+      "variadic" : false,
+      "returnType" : "date_nanos"
+    },
     {
       "params" : [
         {

+ 5 - 5
docs/reference/esql/functions/kibana/docs/match.md

@@ -6,9 +6,9 @@ This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../READ
 Performs a match query on the specified field. Returns true if the provided query matches the row.
 
 ```
-from books 
-| where match(author, "Faulkner")
-| keep book_no, author 
-| sort book_no 
-| limit 5;
+FROM books 
+| WHERE MATCH(author, "Faulkner")
+| KEEP book_no, author 
+| SORT book_no 
+| LIMIT 5;
 ```

+ 5 - 5
docs/reference/esql/functions/kibana/docs/qstr.md

@@ -6,9 +6,9 @@ This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../READ
 Performs a query string query. Returns true if the provided query string matches the row.
 
 ```
-from books 
-| where qstr("author: Faulkner")
-| keep book_no, author 
-| sort book_no 
-| limit 5;
+FROM books 
+| WHERE QSTR("author: Faulkner")
+| KEEP book_no, author 
+| SORT book_no 
+| LIMIT 5;
 ```

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

@@ -13,6 +13,8 @@ boolean | cartesian_shape | cartesian_shape | cartesian_shape
 boolean | cartesian_shape | | cartesian_shape
 boolean | date | date | date
 boolean | date | | date
+boolean | date_nanos | date_nanos | date_nanos
+boolean | date_nanos | | date_nanos
 boolean | double | double | double
 boolean | double | | double
 boolean | geo_point | geo_point | geo_point

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

@@ -10,6 +10,7 @@ boolean | | boolean
 cartesian_point | cartesian_point | cartesian_point
 cartesian_shape | cartesian_shape | cartesian_shape
 date | date | date
+date_nanos | date_nanos | date_nanos
 geo_point | geo_point | geo_point
 geo_shape | geo_shape | geo_shape
 integer | integer | integer

+ 4 - 0
docs/reference/esql/functions/types/count_distinct.asciidoc

@@ -13,6 +13,10 @@ date | integer | long
 date | long | long
 date | unsigned_long | long
 date | | long
+date_nanos | integer | long
+date_nanos | long | long
+date_nanos | unsigned_long | long
+date_nanos | | long
 double | integer | long
 double | long | long
 double | unsigned_long | long

+ 2 - 0
docs/reference/esql/functions/types/date_trunc.asciidoc

@@ -6,5 +6,7 @@
 |===
 interval | date | result
 date_period | date | date
+date_period | date_nanos | date_nanos
 time_duration | date | date
+time_duration | date_nanos | date_nanos
 |===

+ 1 - 0
docs/reference/esql/functions/types/equals.asciidoc

@@ -9,6 +9,7 @@ boolean | boolean | boolean
 cartesian_point | cartesian_point | boolean
 cartesian_shape | cartesian_shape | boolean
 date | date | boolean
+date_nanos | date_nanos | boolean
 double | double | boolean
 double | integer | boolean
 double | long | boolean

+ 1 - 0
docs/reference/esql/functions/types/greater_than.asciidoc

@@ -6,6 +6,7 @@
 |===
 lhs | rhs | result
 date | date | boolean
+date_nanos | date_nanos | boolean
 double | double | boolean
 double | integer | boolean
 double | long | boolean

+ 1 - 0
docs/reference/esql/functions/types/greater_than_or_equal.asciidoc

@@ -6,6 +6,7 @@
 |===
 lhs | rhs | result
 date | date | boolean
+date_nanos | date_nanos | boolean
 double | double | boolean
 double | integer | boolean
 double | long | boolean

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

@@ -8,6 +8,7 @@ first | rest | result
 boolean | boolean | boolean
 boolean | | boolean
 date | date | date
+date_nanos | date_nanos | date_nanos
 double | double | double
 integer | integer | integer
 integer | | integer

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

@@ -8,6 +8,7 @@ first | rest | result
 boolean | boolean | boolean
 boolean | | boolean
 date | date | date
+date_nanos | date_nanos | date_nanos
 double | double | double
 integer | integer | integer
 integer | | integer

+ 1 - 0
docs/reference/esql/functions/types/less_than.asciidoc

@@ -6,6 +6,7 @@
 |===
 lhs | rhs | result
 date | date | boolean
+date_nanos | date_nanos | boolean
 double | double | boolean
 double | integer | boolean
 double | long | boolean

+ 1 - 0
docs/reference/esql/functions/types/less_than_or_equal.asciidoc

@@ -6,6 +6,7 @@
 |===
 lhs | rhs | result
 date | date | boolean
+date_nanos | date_nanos | boolean
 double | double | boolean
 double | integer | boolean
 double | long | boolean

+ 1 - 0
docs/reference/esql/functions/types/max.asciidoc

@@ -7,6 +7,7 @@
 field | result
 boolean | boolean
 date | date
+date_nanos | date_nanos
 double | double
 integer | integer
 ip | ip

+ 1 - 0
docs/reference/esql/functions/types/min.asciidoc

@@ -7,6 +7,7 @@
 field | result
 boolean | boolean
 date | date
+date_nanos | date_nanos
 double | double
 integer | integer
 ip | ip

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

@@ -9,6 +9,7 @@ boolean | integer
 cartesian_point | integer
 cartesian_shape | integer
 date | integer
+date_nanos | integer
 double | integer
 geo_point | integer
 geo_shape | integer

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

@@ -9,6 +9,7 @@ boolean | boolean
 cartesian_point | cartesian_point
 cartesian_shape | cartesian_shape
 date | date
+date_nanos | date_nanos
 double | double
 geo_point | geo_point
 geo_shape | geo_shape

+ 1 - 0
docs/reference/esql/functions/types/mv_first.asciidoc

@@ -9,6 +9,7 @@ boolean | boolean
 cartesian_point | cartesian_point
 cartesian_shape | cartesian_shape
 date | date
+date_nanos | date_nanos
 double | double
 geo_point | geo_point
 geo_shape | geo_shape

+ 1 - 0
docs/reference/esql/functions/types/mv_last.asciidoc

@@ -9,6 +9,7 @@ boolean | boolean
 cartesian_point | cartesian_point
 cartesian_shape | cartesian_shape
 date | date
+date_nanos | date_nanos
 double | double
 geo_point | geo_point
 geo_shape | geo_shape

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

@@ -7,6 +7,7 @@
 field | result
 boolean | boolean
 date | date
+date_nanos | date_nanos
 double | double
 integer | integer
 ip | ip

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

@@ -7,6 +7,7 @@
 field | result
 boolean | boolean
 date | date
+date_nanos | date_nanos
 double | double
 integer | integer
 ip | ip

+ 1 - 0
docs/reference/esql/functions/types/mv_slice.asciidoc

@@ -9,6 +9,7 @@ boolean | integer | integer | boolean
 cartesian_point | integer | integer | cartesian_point
 cartesian_shape | integer | integer | cartesian_shape
 date | integer | integer | date
+date_nanos | integer | integer | date_nanos
 double | integer | integer | double
 geo_point | integer | integer | geo_point
 geo_shape | integer | integer | geo_shape

+ 1 - 0
docs/reference/esql/functions/types/mv_sort.asciidoc

@@ -7,6 +7,7 @@
 field | order | result
 boolean | keyword | boolean
 date | keyword | date
+date_nanos | keyword | date_nanos
 double | keyword | double
 integer | keyword | integer
 ip | keyword | ip

+ 1 - 0
docs/reference/esql/functions/types/not_equals.asciidoc

@@ -9,6 +9,7 @@ boolean | boolean | boolean
 cartesian_point | cartesian_point | boolean
 cartesian_shape | cartesian_shape | boolean
 date | date | boolean
+date_nanos | date_nanos | boolean
 double | double | boolean
 double | integer | boolean
 double | long | boolean

+ 7 - 1
docs/reference/esql/functions/types/to_date_nanos.asciidoc

@@ -5,5 +5,11 @@
 [%header.monospaced.styled,format=dsv,separator=|]
 |===
 field | result
-date_nanos
+date | date_nanos
+date_nanos | date_nanos
+double | date_nanos
+keyword | date_nanos
+long | date_nanos
+text | date_nanos
+unsigned_long | date_nanos
 |===

+ 1 - 0
docs/reference/esql/functions/types/to_datetime.asciidoc

@@ -6,6 +6,7 @@
 |===
 field | result
 date | date
+date_nanos | date
 double | date
 integer | date
 keyword | date

+ 1 - 0
docs/reference/esql/functions/types/to_long.asciidoc

@@ -9,6 +9,7 @@ boolean | long
 counter_integer | long
 counter_long | long
 date | long
+date_nanos | long
 double | long
 integer | long
 keyword | long

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

@@ -9,6 +9,7 @@ boolean | keyword
 cartesian_point | keyword
 cartesian_shape | keyword
 date | keyword
+date_nanos | keyword
 double | keyword
 geo_point | keyword
 geo_shape | keyword

+ 1 - 0
docs/reference/esql/functions/types/values.asciidoc

@@ -7,6 +7,7 @@
 field | result
 boolean | boolean
 date | date
+date_nanos | date_nanos
 double | double
 integer | integer
 ip | ip

+ 0 - 1
x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/plugin/EsqlCorePlugin.java

@@ -12,7 +12,6 @@ import org.elasticsearch.plugins.ExtensiblePlugin;
 import org.elasticsearch.plugins.Plugin;
 
 public class EsqlCorePlugin extends Plugin implements ExtensiblePlugin {
-    public static final FeatureFlag DATE_NANOS_FEATURE_FLAG = new FeatureFlag("esql_date_nanos");
 
     public static final FeatureFlag SEMANTIC_TEXT_FEATURE_FLAG = new FeatureFlag("esql_semantic_text");
 }

+ 0 - 1
x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java

@@ -209,7 +209,6 @@ public enum DataType {
      * check that sending them to a function produces a sane error message.
      */
     public static final Map<DataType, FeatureFlag> UNDER_CONSTRUCTION = Map.ofEntries(
-        Map.entry(DATE_NANOS, EsqlCorePlugin.DATE_NANOS_FEATURE_FLAG),
         Map.entry(SEMANTIC_TEXT, EsqlCorePlugin.SEMANTIC_TEXT_FEATURE_FLAG)
     );
 

+ 6 - 6
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java

@@ -321,32 +321,32 @@ public class EsqlCapabilities {
         /**
          * Support for nanosecond dates as a data type
          */
-        DATE_NANOS_TYPE(EsqlCorePlugin.DATE_NANOS_FEATURE_FLAG),
+        DATE_NANOS_TYPE(),
 
         /**
          * Support for to_date_nanos function
          */
-        TO_DATE_NANOS(EsqlCorePlugin.DATE_NANOS_FEATURE_FLAG),
+        TO_DATE_NANOS(),
 
         /**
          * Support for date nanos type in binary comparisons
          */
-        DATE_NANOS_BINARY_COMPARISON(EsqlCorePlugin.DATE_NANOS_FEATURE_FLAG),
+        DATE_NANOS_BINARY_COMPARISON(),
 
         /**
          * Support Least and Greatest functions on Date Nanos type
          */
-        LEAST_GREATEST_FOR_DATENANOS(EsqlCorePlugin.DATE_NANOS_FEATURE_FLAG),
+        LEAST_GREATEST_FOR_DATENANOS(),
 
         /**
          * Support for date_trunc function on date nanos type
          */
-        DATE_TRUNC_DATE_NANOS(EsqlCorePlugin.DATE_NANOS_FEATURE_FLAG),
+        DATE_TRUNC_DATE_NANOS(),
 
         /**
          * support aggregations on date nanos
          */
-        DATE_NANOS_AGGREGATIONS(EsqlCorePlugin.DATE_NANOS_FEATURE_FLAG),
+        DATE_NANOS_AGGREGATIONS(),
 
         /**
          * Support for datetime in least and greatest functions

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

@@ -501,7 +501,9 @@ public class EsqlFunctionRegistry {
                 types.add(type);
             }
         }
+
         return types.stream()
+            .filter(DATA_TYPE_CASTING_PRIORITY::containsKey)
             .min((dt1, dt2) -> DATA_TYPE_CASTING_PRIORITY.get(dt1).compareTo(DATA_TYPE_CASTING_PRIORITY.get(dt2)))
             .orElse(UNSUPPORTED);
     }

+ 2 - 2
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Max.java

@@ -55,7 +55,7 @@ public class Max extends AggregateFunction implements ToAggregator, SurrogateExp
     );
 
     @FunctionInfo(
-        returnType = { "boolean", "double", "integer", "long", "date", "ip", "keyword", "long", "version" },
+        returnType = { "boolean", "double", "integer", "long", "date", "date_nanos", "ip", "keyword", "long", "version" },
         description = "The maximum value of a field.",
         isAggregation = true,
         examples = {
@@ -72,7 +72,7 @@ public class Max extends AggregateFunction implements ToAggregator, SurrogateExp
         Source source,
         @Param(
             name = "field",
-            type = { "boolean", "double", "integer", "long", "date", "ip", "keyword", "text", "long", "version" }
+            type = { "boolean", "double", "integer", "long", "date", "date_nanos", "ip", "keyword", "text", "long", "version" }
         ) Expression field
     ) {
         this(source, field, Literal.TRUE);

+ 2 - 2
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Min.java

@@ -55,7 +55,7 @@ public class Min extends AggregateFunction implements ToAggregator, SurrogateExp
     );
 
     @FunctionInfo(
-        returnType = { "boolean", "double", "integer", "long", "date", "ip", "keyword", "long", "version" },
+        returnType = { "boolean", "double", "integer", "long", "date", "date_nanos", "ip", "keyword", "long", "version" },
         description = "The minimum value of a field.",
         isAggregation = true,
         examples = {
@@ -72,7 +72,7 @@ public class Min extends AggregateFunction implements ToAggregator, SurrogateExp
         Source source,
         @Param(
             name = "field",
-            type = { "boolean", "double", "integer", "long", "date", "ip", "keyword", "text", "long", "version" }
+            type = { "boolean", "double", "integer", "long", "date", "date_nanos", "ip", "keyword", "text", "long", "version" }
         ) Expression field
     ) {
         this(source, field, Literal.TRUE);

+ 5 - 2
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Values.java

@@ -52,7 +52,7 @@ public class Values extends AggregateFunction implements ToAggregator {
     );
 
     @FunctionInfo(
-        returnType = { "boolean", "date", "double", "integer", "ip", "keyword", "long", "version" },
+        returnType = { "boolean", "date", "date_nanos", "double", "integer", "ip", "keyword", "long", "version" },
         preview = true,
         description = "Returns all values in a group as a multivalued field. The order of the returned values isn't guaranteed. "
             + "If you need the values returned in order use <<esql-mv_sort>>.",
@@ -70,7 +70,10 @@ public class Values extends AggregateFunction implements ToAggregator {
     )
     public Values(
         Source source,
-        @Param(name = "field", type = { "boolean", "date", "double", "integer", "ip", "keyword", "long", "text", "version" }) Expression v
+        @Param(
+            name = "field",
+            type = { "boolean", "date", "date_nanos", "double", "integer", "ip", "keyword", "long", "text", "version" }
+        ) Expression v
     ) {
         this(source, v, Literal.TRUE);
     }

+ 2 - 2
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/date/DateTrunc.java

@@ -62,7 +62,7 @@ public class DateTrunc extends EsqlScalarFunction {
     protected static final ZoneId DEFAULT_TZ = ZoneOffset.UTC;
 
     @FunctionInfo(
-        returnType = "date",
+        returnType = { "date", "date_nanos" },
         description = "Rounds down a date to the closest interval.",
         examples = {
             @Example(file = "date", tag = "docsDateTrunc"),
@@ -83,7 +83,7 @@ public class DateTrunc extends EsqlScalarFunction {
             type = { "date_period", "time_duration" },
             description = "Interval; expressed using the timespan literal syntax."
         ) Expression interval,
-        @Param(name = "date", type = { "date" }, description = "Date expression") Expression field
+        @Param(name = "date", type = { "date", "date_nanos" }, description = "Date expression") Expression field
     ) {
         super(source, List.of(interval, field));
         this.interval = interval;

+ 2 - 2
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/LessThan.java

@@ -53,12 +53,12 @@ public class LessThan extends EsqlBinaryComparison implements Negatable<EsqlBina
         Source source,
         @Param(
             name = "lhs",
-            type = { "boolean", "date", "double", "integer", "ip", "keyword", "long", "text", "unsigned_long", "version" },
+            type = { "boolean", "date_nanos", "date", "double", "integer", "ip", "keyword", "long", "text", "unsigned_long", "version" },
             description = "An expression."
         ) Expression left,
         @Param(
             name = "rhs",
-            type = { "boolean", "date", "double", "integer", "ip", "keyword", "long", "text", "unsigned_long", "version" },
+            type = { "boolean", "date_nanos", "date", "double", "integer", "ip", "keyword", "long", "text", "unsigned_long", "version" },
             description = "An expression."
         ) Expression right
     ) {

+ 3 - 0
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java

@@ -1738,6 +1738,7 @@ public class VerifierTests extends ESTestCase {
     }
 
     public void testCategorizeSingleGrouping() {
+        assumeTrue("requires snapshot builds", Build.current().isSnapshot());
         query("from test | STATS COUNT(*) BY CATEGORIZE(first_name)");
         query("from test | STATS COUNT(*) BY cat = CATEGORIZE(first_name)");
 
@@ -1765,6 +1766,7 @@ public class VerifierTests extends ESTestCase {
     }
 
     public void testCategorizeNestedGrouping() {
+        assumeTrue("requires snapshot builds", Build.current().isSnapshot());
         query("from test | STATS COUNT(*) BY CATEGORIZE(LENGTH(first_name)::string)");
 
         assertEquals(
@@ -1778,6 +1780,7 @@ public class VerifierTests extends ESTestCase {
     }
 
     public void testCategorizeWithinAggregations() {
+        assumeTrue("requires snapshot builds", Build.current().isSnapshot());
         query("from test | STATS MV_COUNT(cat), COUNT(*) BY cat = CATEGORIZE(first_name)");
 
         assertEquals(

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

@@ -262,6 +262,42 @@ public final class MultiRowTestCaseSupplier {
         return cases;
     }
 
+    /**
+     *
+     * Generate cases for {@link DataType#DATE_NANOS}.
+     *
+     */
+    public static List<TypedDataSupplier> dateNanosCases(int minRows, int maxRows) {
+        List<TypedDataSupplier> cases = new ArrayList<>();
+        addSuppliers(cases, minRows, maxRows, "<1970-01-01T00:00:00.000000000Z>", DataType.DATE_NANOS, () -> 0L);
+        addSuppliers(
+            cases,
+            minRows,
+            maxRows,
+            "<date nanos>",
+            DataType.DATE_NANOS,
+            () -> ESTestCase.randomLongBetween(0, 10 * (long) 10e11)
+        );
+        addSuppliers(
+            cases,
+            minRows,
+            maxRows,
+            "<far future date nanos>",
+            DataType.DATE_NANOS,
+            () -> ESTestCase.randomLongBetween(10 * (long) 10e11, Long.MAX_VALUE)
+        );
+        addSuppliers(
+            cases,
+            minRows,
+            maxRows,
+            "<nanos near the end of time>",
+            DataType.DATE_NANOS,
+            () -> ESTestCase.randomLongBetween(Long.MAX_VALUE / 100 * 99, Long.MAX_VALUE)
+        );
+
+        return cases;
+    }
+
     public static List<TypedDataSupplier> booleanCases(int minRows, int maxRows) {
         List<TypedDataSupplier> cases = new ArrayList<>();
 

+ 1 - 0
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/CountDistinctTests.java

@@ -52,6 +52,7 @@ public class CountDistinctTests extends AbstractAggregationTestCase {
             MultiRowTestCaseSupplier.longCases(1, 1000, Long.MIN_VALUE, Long.MAX_VALUE, true),
             MultiRowTestCaseSupplier.doubleCases(1, 1000, -Double.MAX_VALUE, Double.MAX_VALUE, true),
             MultiRowTestCaseSupplier.dateCases(1, 1000),
+            MultiRowTestCaseSupplier.dateNanosCases(1, 1000),
             MultiRowTestCaseSupplier.booleanCases(1, 1000),
             MultiRowTestCaseSupplier.ipCases(1, 1000),
             MultiRowTestCaseSupplier.versionCases(1, 1000),

+ 9 - 0
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/MaxTests.java

@@ -90,6 +90,15 @@ public class MaxTests extends AbstractAggregationTestCase {
                         equalTo(200L)
                     )
                 ),
+                new TestCaseSupplier(
+                    List.of(DataType.DATE_NANOS),
+                    () -> new TestCaseSupplier.TestCase(
+                        List.of(TestCaseSupplier.TypedData.multiRow(List.of(200L), DataType.DATE_NANOS, "field")),
+                        "Max[field=Attribute[channel=0]]",
+                        DataType.DATE_NANOS,
+                        equalTo(200L)
+                    )
+                ),
                 new TestCaseSupplier(
                     List.of(DataType.BOOLEAN),
                     () -> new TestCaseSupplier.TestCase(

+ 9 - 0
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/MinTests.java

@@ -90,6 +90,15 @@ public class MinTests extends AbstractAggregationTestCase {
                         equalTo(200L)
                     )
                 ),
+                new TestCaseSupplier(
+                    List.of(DataType.DATE_NANOS),
+                    () -> new TestCaseSupplier.TestCase(
+                        List.of(TestCaseSupplier.TypedData.multiRow(List.of(200L), DataType.DATE_NANOS, "field")),
+                        "Min[field=Attribute[channel=0]]",
+                        DataType.DATE_NANOS,
+                        equalTo(200L)
+                    )
+                ),
                 new TestCaseSupplier(
                     List.of(DataType.BOOLEAN),
                     () -> new TestCaseSupplier.TestCase(

+ 1 - 0
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/ValuesTests.java

@@ -45,6 +45,7 @@ public class ValuesTests extends AbstractAggregationTestCase {
             MultiRowTestCaseSupplier.longCases(1, 1000, Long.MIN_VALUE, Long.MAX_VALUE, true),
             MultiRowTestCaseSupplier.doubleCases(1, 1000, -Double.MAX_VALUE, Double.MAX_VALUE, true),
             MultiRowTestCaseSupplier.dateCases(1, 1000),
+            MultiRowTestCaseSupplier.dateNanosCases(1, 1000),
             MultiRowTestCaseSupplier.booleanCases(1, 1000),
             MultiRowTestCaseSupplier.ipCases(1, 1000),
             MultiRowTestCaseSupplier.versionCases(1, 1000),

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

@@ -14,7 +14,6 @@ import org.elasticsearch.geo.ShapeTestUtils;
 import org.elasticsearch.geometry.Geometry;
 import org.elasticsearch.test.ESTestCase;
 import org.elasticsearch.xpack.esql.core.expression.Expression;
-import org.elasticsearch.xpack.esql.core.plugin.EsqlCorePlugin;
 import org.elasticsearch.xpack.esql.core.tree.Source;
 import org.elasticsearch.xpack.esql.core.type.DataType;
 import org.elasticsearch.xpack.esql.core.util.NumericUtils;
@@ -397,9 +396,6 @@ public abstract class AbstractMultivalueFunctionTestCase extends AbstractScalarF
         DataType expectedDataType,
         BiFunction<Integer, LongStream, Matcher<Object>> matcher
     ) {
-        if (EsqlCorePlugin.DATE_NANOS_FEATURE_FLAG.isEnabled() == false) {
-            return;
-        }
         cases.add(
             new TestCaseSupplier(
                 name + "(epoch nanos)",

+ 2 - 2
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/LessThanTests.java

@@ -113,8 +113,8 @@ public class LessThanTests extends AbstractScalarFunctionTestCase {
                 "rhs",
                 (l, r) -> ((Number) l).longValue() < ((Number) r).longValue(),
                 DataType.BOOLEAN,
-                TestCaseSupplier.dateCases(),
-                TestCaseSupplier.dateCases(),
+                TestCaseSupplier.dateNanosCases(),
+                TestCaseSupplier.dateNanosCases(),
                 List.of(),
                 false
             )