diff --git a/docs/changelog/116591.yaml b/docs/changelog/116591.yaml
new file mode 100644
index 0000000000000..60ef241e197b3
--- /dev/null
+++ b/docs/changelog/116591.yaml
@@ -0,0 +1,5 @@
+pr: 116591
+summary: "Add support for `BYTE_LENGTH` scalar function"
+area: ES|QL
+type: feature
+issues: []
diff --git a/docs/reference/esql/functions/description/bit_length.asciidoc b/docs/reference/esql/functions/description/bit_length.asciidoc
index 1aad47488802d..3a3dd80d2bb0f 100644
--- a/docs/reference/esql/functions/description/bit_length.asciidoc
+++ b/docs/reference/esql/functions/description/bit_length.asciidoc
@@ -3,3 +3,5 @@
*Description*
Returns the bit length of a string.
+
+NOTE: All strings are in UTF-8, so a single character can use multiple bytes.
diff --git a/docs/reference/esql/functions/description/byte_length.asciidoc b/docs/reference/esql/functions/description/byte_length.asciidoc
new file mode 100644
index 0000000000000..c2150806e09ac
--- /dev/null
+++ b/docs/reference/esql/functions/description/byte_length.asciidoc
@@ -0,0 +1,7 @@
+// This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.
+
+*Description*
+
+Returns the byte length of a string.
+
+NOTE: All strings are in UTF-8, so a single character can use multiple bytes.
diff --git a/docs/reference/esql/functions/description/length.asciidoc b/docs/reference/esql/functions/description/length.asciidoc
index bf976e3d6e507..91525fda0c086 100644
--- a/docs/reference/esql/functions/description/length.asciidoc
+++ b/docs/reference/esql/functions/description/length.asciidoc
@@ -3,3 +3,5 @@
*Description*
Returns the character length of a string.
+
+NOTE: All strings are in UTF-8, so a single character can use multiple bytes.
diff --git a/docs/reference/esql/functions/examples/byte_length.asciidoc b/docs/reference/esql/functions/examples/byte_length.asciidoc
new file mode 100644
index 0000000000000..d6b557fcd2e76
--- /dev/null
+++ b/docs/reference/esql/functions/examples/byte_length.asciidoc
@@ -0,0 +1,13 @@
+// This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.
+
+*Example*
+
+[source.merge.styled,esql]
+----
+include::{esql-specs}/eval.csv-spec[tag=byteLength]
+----
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+include::{esql-specs}/eval.csv-spec[tag=byteLength-result]
+|===
+
diff --git a/docs/reference/esql/functions/kibana/definition/bit_length.json b/docs/reference/esql/functions/kibana/definition/bit_length.json
new file mode 100644
index 0000000000000..156a063984e4d
--- /dev/null
+++ b/docs/reference/esql/functions/kibana/definition/bit_length.json
@@ -0,0 +1,38 @@
+{
+ "comment" : "This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.",
+ "type" : "eval",
+ "name" : "bit_length",
+ "description" : "Returns the bit length of a string.",
+ "note" : "All strings are in UTF-8, so a single character can use multiple bytes.",
+ "signatures" : [
+ {
+ "params" : [
+ {
+ "name" : "string",
+ "type" : "keyword",
+ "optional" : false,
+ "description" : "String expression. If `null`, the function returns `null`."
+ }
+ ],
+ "variadic" : false,
+ "returnType" : "integer"
+ },
+ {
+ "params" : [
+ {
+ "name" : "string",
+ "type" : "text",
+ "optional" : false,
+ "description" : "String expression. If `null`, the function returns `null`."
+ }
+ ],
+ "variadic" : false,
+ "returnType" : "integer"
+ }
+ ],
+ "examples" : [
+ "FROM airports\n| WHERE country == \"India\"\n| KEEP city\n| EVAL fn_length=LENGTH(city), fn_bit_length = BIT_LENGTH(city)"
+ ],
+ "preview" : false,
+ "snapshot_only" : false
+}
diff --git a/docs/reference/esql/functions/kibana/definition/byte_length.json b/docs/reference/esql/functions/kibana/definition/byte_length.json
new file mode 100644
index 0000000000000..c8280a572fc62
--- /dev/null
+++ b/docs/reference/esql/functions/kibana/definition/byte_length.json
@@ -0,0 +1,38 @@
+{
+ "comment" : "This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.",
+ "type" : "eval",
+ "name" : "byte_length",
+ "description" : "Returns the byte length of a string.",
+ "note" : "All strings are in UTF-8, so a single character can use multiple bytes.",
+ "signatures" : [
+ {
+ "params" : [
+ {
+ "name" : "string",
+ "type" : "keyword",
+ "optional" : false,
+ "description" : "String expression. If `null`, the function returns `null`."
+ }
+ ],
+ "variadic" : false,
+ "returnType" : "integer"
+ },
+ {
+ "params" : [
+ {
+ "name" : "string",
+ "type" : "text",
+ "optional" : false,
+ "description" : "String expression. If `null`, the function returns `null`."
+ }
+ ],
+ "variadic" : false,
+ "returnType" : "integer"
+ }
+ ],
+ "examples" : [
+ "FROM airports\n| WHERE country == \"India\"\n| KEEP city\n| EVAL fn_length=LENGTH(city), fn_byte_length = BYTE_LENGTH(city)"
+ ],
+ "preview" : false,
+ "snapshot_only" : false
+}
diff --git a/docs/reference/esql/functions/kibana/definition/length.json b/docs/reference/esql/functions/kibana/definition/length.json
index 0da505cf5ffa7..9ea340ebf7420 100644
--- a/docs/reference/esql/functions/kibana/definition/length.json
+++ b/docs/reference/esql/functions/kibana/definition/length.json
@@ -3,6 +3,7 @@
"type" : "eval",
"name" : "length",
"description" : "Returns the character length of a string.",
+ "note" : "All strings are in UTF-8, so a single character can use multiple bytes.",
"signatures" : [
{
"params" : [
@@ -30,7 +31,7 @@
}
],
"examples" : [
- "FROM employees\n| KEEP first_name, last_name\n| EVAL fn_length = LENGTH(first_name)"
+ "FROM airports\n| KEEP city\n| EVAL fn_length = LENGTH(first_name)"
],
"preview" : false,
"snapshot_only" : false
diff --git a/docs/reference/esql/functions/kibana/docs/bit_length.md b/docs/reference/esql/functions/kibana/docs/bit_length.md
index 22280febd7876..253b2cdb6a7c6 100644
--- a/docs/reference/esql/functions/kibana/docs/bit_length.md
+++ b/docs/reference/esql/functions/kibana/docs/bit_length.md
@@ -6,7 +6,9 @@ This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../READ
Returns the bit length of a string.
```
-FROM employees
-| KEEP first_name, last_name
-| EVAL fn_bit_length = BIT_LENGTH(first_name)
+FROM airports
+| WHERE country == "India"
+| KEEP city
+| EVAL fn_length=LENGTH(city), fn_bit_length = BIT_LENGTH(city)
```
+Note: All strings are in UTF-8, so a single character can use multiple bytes.
diff --git a/docs/reference/esql/functions/kibana/docs/byte_length.md b/docs/reference/esql/functions/kibana/docs/byte_length.md
new file mode 100644
index 0000000000000..20d96ce38400d
--- /dev/null
+++ b/docs/reference/esql/functions/kibana/docs/byte_length.md
@@ -0,0 +1,14 @@
+
+
+### BYTE_LENGTH
+Returns the byte length of a string.
+
+```
+FROM airports
+| WHERE country == "India"
+| KEEP city
+| EVAL fn_length=LENGTH(city), fn_byte_length = BYTE_LENGTH(city)
+```
+Note: All strings are in UTF-8, so a single character can use multiple bytes.
diff --git a/docs/reference/esql/functions/kibana/docs/length.md b/docs/reference/esql/functions/kibana/docs/length.md
index 19e3533e0ddfb..ce7726d092bae 100644
--- a/docs/reference/esql/functions/kibana/docs/length.md
+++ b/docs/reference/esql/functions/kibana/docs/length.md
@@ -6,7 +6,8 @@ This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../READ
Returns the character length of a string.
```
-FROM employees
-| KEEP first_name, last_name
+FROM airports
+| KEEP city
| EVAL fn_length = LENGTH(first_name)
```
+Note: All strings are in UTF-8, so a single character can use multiple bytes.
diff --git a/docs/reference/esql/functions/layout/byte_length.asciidoc b/docs/reference/esql/functions/layout/byte_length.asciidoc
new file mode 100644
index 0000000000000..56dc341264e0f
--- /dev/null
+++ b/docs/reference/esql/functions/layout/byte_length.asciidoc
@@ -0,0 +1,15 @@
+// This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.
+
+[discrete]
+[[esql-byte_length]]
+=== `BYTE_LENGTH`
+
+*Syntax*
+
+[.text-center]
+image::esql/functions/signature/byte_length.svg[Embedded,opts=inline]
+
+include::../parameters/byte_length.asciidoc[]
+include::../description/byte_length.asciidoc[]
+include::../types/byte_length.asciidoc[]
+include::../examples/byte_length.asciidoc[]
diff --git a/docs/reference/esql/functions/parameters/byte_length.asciidoc b/docs/reference/esql/functions/parameters/byte_length.asciidoc
new file mode 100644
index 0000000000000..7bb8c080ce4a1
--- /dev/null
+++ b/docs/reference/esql/functions/parameters/byte_length.asciidoc
@@ -0,0 +1,6 @@
+// This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.
+
+*Parameters*
+
+`string`::
+String expression. If `null`, the function returns `null`.
diff --git a/docs/reference/esql/functions/signature/byte_length.svg b/docs/reference/esql/functions/signature/byte_length.svg
new file mode 100644
index 0000000000000..d88821e46e926
--- /dev/null
+++ b/docs/reference/esql/functions/signature/byte_length.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/docs/reference/esql/functions/string-functions.asciidoc b/docs/reference/esql/functions/string-functions.asciidoc
index 422860f0a7a1d..ce9636f5c5a3a 100644
--- a/docs/reference/esql/functions/string-functions.asciidoc
+++ b/docs/reference/esql/functions/string-functions.asciidoc
@@ -9,6 +9,7 @@
// tag::string_list[]
* <>
+* <>
* <>
* <>
* <>
@@ -32,6 +33,7 @@
// end::string_list[]
include::layout/bit_length.asciidoc[]
+include::layout/byte_length.asciidoc[]
include::layout/concat.asciidoc[]
include::layout/ends_with.asciidoc[]
include::layout/from_base64.asciidoc[]
diff --git a/docs/reference/esql/functions/types/byte_length.asciidoc b/docs/reference/esql/functions/types/byte_length.asciidoc
new file mode 100644
index 0000000000000..db5a48c7c4390
--- /dev/null
+++ b/docs/reference/esql/functions/types/byte_length.asciidoc
@@ -0,0 +1,10 @@
+// This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.
+
+*Supported types*
+
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+string | result
+keyword | integer
+text | integer
+|===
diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/docs.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/docs.csv-spec
index 14d811535aafd..a53777cff7c71 100644
--- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/docs.csv-spec
+++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/docs.csv-spec
@@ -4,7 +4,7 @@
// the comments in whatever file the test already lives in. If you have to
// write a new test to make an example in the docs then put it in whatever
// file matches its "theme" best. Put it next to similar tests. Not here.
-
+
// Also! When Nik originally extracted examples from the docs to make them
// testable he didn't spend a lot of time putting the docs into appropriate
// files. He just made this one. He didn't put his toys away. We'd be better
@@ -352,18 +352,18 @@ FROM employees
// tag::case-result[]
emp_no:integer | languages:integer| type:keyword
-10001 | 2 |bilingual
-10002 | 5 |polyglot
-10003 | 4 |polyglot
-10004 | 5 |polyglot
-10005 | 1 |monolingual
+10001 | 2 |bilingual
+10002 | 5 |polyglot
+10003 | 4 |polyglot
+10004 | 5 |polyglot
+10005 | 1 |monolingual
// end::case-result[]
;
docsCountAll
// tag::countAll[]
-FROM employees
-| STATS count = COUNT(*) BY languages
+FROM employees
+| STATS count = COUNT(*) BY languages
| SORT languages DESC
// end::countAll[]
;
@@ -371,7 +371,7 @@ FROM employees
// tag::countAll-result[]
count:long | languages:integer
10 |null
-21 |5
+21 |5
18 |4
17 |3
19 |2
@@ -381,8 +381,8 @@ count:long | languages:integer
basicGrok
// tag::basicGrok[]
-ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 some.email@foo.com 42"
-| GROK a """%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num}"""
+ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 some.email@foo.com 42"
+| GROK a """%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num}"""
| KEEP date, ip, email, num
// end::basicGrok[]
;
@@ -395,8 +395,8 @@ date:keyword | ip:keyword | email:keyword | num:keyword
grokWithConversionSuffix
// tag::grokWithConversionSuffix[]
-ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 some.email@foo.com 42"
-| GROK a """%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num:int}"""
+ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 some.email@foo.com 42"
+| GROK a """%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num:int}"""
| KEEP date, ip, email, num
// end::grokWithConversionSuffix[]
;
@@ -409,8 +409,8 @@ date:keyword | ip:keyword | email:keyword | num:integer
grokWithToDatetime
// tag::grokWithToDatetime[]
-ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 some.email@foo.com 42"
-| GROK a """%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num:int}"""
+ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 some.email@foo.com 42"
+| GROK a """%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num:int}"""
| KEEP date, ip, email, num
| EVAL date = TO_DATETIME(date)
// end::grokWithToDatetime[]
@@ -471,7 +471,7 @@ Tokyo | 100-7014 | null
basicDissect
// tag::basicDissect[]
-ROW a = "2023-01-23T12:15:00.000Z - some text - 127.0.0.1"
+ROW a = "2023-01-23T12:15:00.000Z - some text - 127.0.0.1"
| DISSECT a """%{date} - %{msg} - %{ip}"""
| KEEP date, msg, ip
// end::basicDissect[]
@@ -485,8 +485,8 @@ date:keyword | msg:keyword | ip:keyword
dissectWithToDatetime
// tag::dissectWithToDatetime[]
-ROW a = "2023-01-23T12:15:00.000Z - some text - 127.0.0.1"
-| DISSECT a """%{date} - %{msg} - %{ip}"""
+ROW a = "2023-01-23T12:15:00.000Z - some text - 127.0.0.1"
+| DISSECT a """%{date} - %{msg} - %{ip}"""
| KEEP date, msg, ip
| EVAL date = TO_DATETIME(date)
// end::dissectWithToDatetime[]
@@ -574,8 +574,8 @@ FROM employees
// tag::like-result[]
first_name:keyword | last_name:keyword
-Ebbe |Callaway
-Eberhardt |Terkki
+Ebbe |Callaway
+Eberhardt |Terkki
// end::like-result[]
;
@@ -589,7 +589,7 @@ FROM employees
// tag::rlike-result[]
first_name:keyword | last_name:keyword
-Alejandro |McAlpine
+Alejandro |McAlpine
// end::rlike-result[]
;
@@ -660,18 +660,19 @@ FROM sample_data
docsBitLength
required_capability: fn_bit_length
// tag::bitLength[]
-FROM employees
-| KEEP first_name, last_name
-| EVAL fn_bit_length = BIT_LENGTH(first_name)
+FROM airports
+| WHERE country == "India"
+| KEEP city
+| EVAL fn_length=LENGTH(city), fn_bit_length = BIT_LENGTH(city)
// end::bitLength[]
-| SORT first_name
+| SORT city
| LIMIT 3
;
// tag::bitLength-result[]
-first_name:keyword | last_name:keyword | fn_bit_length:integer
-Alejandro |McAlpine |72
-Amabile |Gomatam |56
-Anneke |Preusig |48
+city:keyword | fn_length:integer | fn_bit_length:integer
+Agwār | 5 | 48
+Ahmedabad | 9 | 72
+Bangalore | 9 | 72
// end::bitLength-result[]
;
diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/eval.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/eval.csv-spec
index 61a0ccd4af0c5..fc2350491db91 100644
--- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/eval.csv-spec
+++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/eval.csv-spec
@@ -22,7 +22,7 @@ FROM addresses
| SORT city.name
;
-city.country.name:keyword | city.name:keyword | city.country.continent.planet.name:keyword
+city.country.name:keyword | city.name:keyword | city.country.continent.planet.name:keyword
Netherlands | Amsterdam | EARTH
United States of America | San Francisco | EARTH
Japan | Tokyo | EARTH
@@ -138,39 +138,39 @@ a:integer | b:integer | c:integer | d:integer | e:integer
multipleDuplicateInterleaved1
row a = 1 | eval b = a, c = 1, c = 3, d = b + 1, b = c * 2, c = 2, c = d * c + b | keep a, b, c, d;
-a:integer | b:integer | c:integer | d:integer
-1 | 6 | 10 | 2
+a:integer | b:integer | c:integer | d:integer
+1 | 6 | 10 | 2
;
multipleDuplicateInterleaved2
row a = 1 | eval b = a, c = 1 | eval c = 3, d = b + 1 | eval b = c * 2, c = 2 | eval c = d * c + b | keep a, b, c, d;
-a:integer | b:integer | c:integer | d:integer
-1 | 6 | 10 | 2
+a:integer | b:integer | c:integer | d:integer
+1 | 6 | 10 | 2
;
multipleDuplicateInterleaved3
row a = 1 | eval b = a, c = 1, c = 3 | eval d = b + 1 | eval b = c * 2, c = 2, c = d * c + b | keep a, b, c, d;
-a:integer | b:integer | c:integer | d:integer
-1 | 6 | 10 | 2
+a:integer | b:integer | c:integer | d:integer
+1 | 6 | 10 | 2
;
multipleDuplicateInterleaved4
row a = 1 | eval b = a | eval c = 1 | eval c = 3 | eval d = b + 1 | eval b = c * 2 | eval c = 2 | eval c = d * c + b | keep a, b, c, d;
-a:integer | b:integer | c:integer | d:integer
-1 | 6 | 10 | 2
+a:integer | b:integer | c:integer | d:integer
+1 | 6 | 10 | 2
;
projectEval
row x = 1 | keep x | eval a1 = x + 1, a2 = x + 1, a3 = a1 + a2, a1 = a1 + a2;
-x:integer | a2:integer | a3:integer | a1:integer
-1 | 2 | 4 | 4
+x:integer | a2:integer | a3:integer | a1:integer
+1 | 2 | 4 | 4
;
evalNullSort
@@ -195,76 +195,76 @@ Uri
evalWithIsNullIsNotNull
from employees | eval true_bool = null is null, false_bool = null is not null, negated_true = not(null is null), negated_false = not(null is not null) | sort emp_no | limit 1 | keep *true*, *false*, first_name, last_name;
-true_bool:boolean | negated_true:boolean | false_bool:boolean | negated_false:boolean | first_name:keyword | last_name:keyword
+true_bool:boolean | negated_true:boolean | false_bool:boolean | negated_false:boolean | first_name:keyword | last_name:keyword
true | false | false | true | Georgi | Facello
;
repetitiveEval
-from employees | sort emp_no | keep emp_no | eval sum = emp_no + 1
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
-| limit 3
+from employees | sort emp_no | keep emp_no | eval sum = emp_no + 1
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no | eval sum = sum + emp_no
+| limit 3
;
emp_no:i | sum:i
10001 | 3230324
10002 | 3230647
10003 | 3230970
-;
+;
chainedEvalReusingPreviousValue
from employees | sort emp_no | eval x1 = concat(first_name, "."), x2 = concat(x1, "."), x3 = concat(x2, ".") | keep x*, first_name | limit 5;
- x1:keyword | x2:keyword | x3:keyword |first_name:keyword
-Georgi. |Georgi.. |Georgi... |Georgi
-Bezalel. |Bezalel.. |Bezalel... |Bezalel
-Parto. |Parto.. |Parto... |Parto
-Chirstian. |Chirstian.. |Chirstian... |Chirstian
+ x1:keyword | x2:keyword | x3:keyword |first_name:keyword
+Georgi. |Georgi.. |Georgi... |Georgi
+Bezalel. |Bezalel.. |Bezalel... |Bezalel
+Parto. |Parto.. |Parto... |Parto
+Chirstian. |Chirstian.. |Chirstian... |Chirstian
Kyoichi. |Kyoichi.. |Kyoichi... |Kyoichi
;
@@ -272,10 +272,10 @@ chainedEvalReusingPreviousValue2
from employees | sort emp_no | eval x1 = concat(first_name, "."), x2 = concat(x1, last_name), x3 = concat(x2, gender) | keep x*, first_name, gender | limit 5;
x1:keyword | x2:keyword | x3:keyword |first_name:keyword|gender:keyword
-Georgi. |Georgi.Facello |Georgi.FacelloM |Georgi |M
-Bezalel. |Bezalel.Simmel |Bezalel.SimmelF |Bezalel |F
-Parto. |Parto.Bamford |Parto.BamfordM |Parto |M
-Chirstian. |Chirstian.Koblick|Chirstian.KoblickM|Chirstian |M
+Georgi. |Georgi.Facello |Georgi.FacelloM |Georgi |M
+Bezalel. |Bezalel.Simmel |Bezalel.SimmelF |Bezalel |F
+Parto. |Parto.Bamford |Parto.BamfordM |Parto |M
+Chirstian. |Chirstian.Koblick|Chirstian.KoblickM|Chirstian |M
Kyoichi. |Kyoichi.Maliniak |Kyoichi.MaliniakM |Kyoichi |M
;
@@ -283,10 +283,10 @@ chainedEvalReusingPreviousValue3
from employees | sort emp_no | eval x1 = concat(first_name, "."), x2 = concat(x1, last_name), x3 = concat(x2, x1) | keep x*, first_name | limit 5;
x1:keyword | x2:keyword | x3:keyword |first_name:keyword
-Georgi. |Georgi.Facello |Georgi.FacelloGeorgi. |Georgi
-Bezalel. |Bezalel.Simmel |Bezalel.SimmelBezalel. |Bezalel
-Parto. |Parto.Bamford |Parto.BamfordParto. |Parto
-Chirstian. |Chirstian.Koblick|Chirstian.KoblickChirstian.|Chirstian
+Georgi. |Georgi.Facello |Georgi.FacelloGeorgi. |Georgi
+Bezalel. |Bezalel.Simmel |Bezalel.SimmelBezalel. |Bezalel
+Parto. |Parto.Bamford |Parto.BamfordParto. |Parto
+Chirstian. |Chirstian.Koblick|Chirstian.KoblickChirstian.|Chirstian
Kyoichi. |Kyoichi.Maliniak |Kyoichi.MaliniakKyoichi. |Kyoichi
;
@@ -301,7 +301,7 @@ warning:Line 1:88: java.lang.IllegalArgumentException: single-value function enc
warning:Line 1:133: evaluation of [round([1.14], [1, 2])] failed, treating result as null. Only first 20 failures recorded.
warning:Line 1:133: java.lang.IllegalArgumentException: single-value function encountered multi-value
-a:double | b:double | c:double | d: double | e:double | f:double | g:double | h:double
+a:double | b:double | c:double | d: double | e:double | f:double | g:double | h:double
1.2 | [2.4, 7.9] | 1.0 | null | 1.0 | null | 1.1 | null
;
@@ -356,22 +356,43 @@ FROM sample_data
docsLength
// tag::length[]
-FROM employees
-| KEEP first_name, last_name
-| EVAL fn_length = LENGTH(first_name)
+FROM airports
+| WHERE country == "India"
+| KEEP city
+| EVAL fn_length = LENGTH(city)
// end::length[]
-| SORT first_name
+| SORT city
| LIMIT 3
;
// tag::length-result[]
-first_name:keyword | last_name:keyword | fn_length:integer
-Alejandro |McAlpine |9
-Amabile |Gomatam |7
-Anneke |Preusig |6
+city:keyword | fn_length:integer
+Agwār | 5
+Ahmedabad | 9
+Bangalore | 9
// end::length-result[]
;
+docsByteLength
+required_capability: fn_byte_length
+// tag::byteLength[]
+FROM airports
+| WHERE country == "India"
+| KEEP city
+| EVAL fn_length=LENGTH(city), fn_byte_length = BYTE_LENGTH(city)
+// end::byteLength[]
+| SORT city
+| LIMIT 3
+;
+
+// tag::byteLength-result[]
+city:keyword | fn_length:integer | fn_byte_length:integer
+Agwār | 5 | 6
+Ahmedabad | 9 | 9
+Bangalore | 9 | 9
+// end::byteLength-result[]
+;
+
docsGettingStartedEvalNoColumnName
// tag::gs-eval-no-column-name[]
FROM sample_data
@@ -407,8 +428,8 @@ FROM employees
// tag::eval-result[]
first_name:keyword | last_name:keyword | height:double | height_feet:double | height_cm:double
Georgi |Facello |2.03 |6.66043 |202.99999999999997
-Bezalel |Simmel |2.08 |6.82448 |208.0
-Parto |Bamford |1.83 |6.004230000000001 |183.0
+Bezalel |Simmel |2.08 |6.82448 |208.0
+Parto |Bamford |1.83 |6.004230000000001 |183.0
// end::eval-result[]
;
@@ -423,9 +444,9 @@ FROM employees
// tag::evalReplace-result[]
first_name:keyword | last_name:keyword | height:double
-Georgi |Facello |6.66043
-Bezalel |Simmel |6.82448
-Parto |Bamford |6.004230000000001
+Georgi |Facello |6.66043
+Bezalel |Simmel |6.82448
+Parto |Bamford |6.004230000000001
// end::evalReplace-result[]
;
@@ -440,8 +461,8 @@ FROM employees
// tag::evalUnnamedColumn-result[]
first_name:keyword | last_name:keyword | height:double | height * 3.281:double
-Georgi |Facello |2.03 |6.66043
-Bezalel |Simmel |2.08 |6.82448
+Georgi |Facello |2.03 |6.66043
+Bezalel |Simmel |2.08 |6.82448
Parto |Bamford |1.83 |6.004230000000001
// end::evalUnnamedColumn-result[]
;
@@ -524,16 +545,16 @@ FROM employees
| KEEP emp_no, salary, sum
;
- emp_no:i | salary:i | sum:i
--10015 |25324 |35339
--10035 |25945 |35980
--10092 |25976 |36068
--10048 |26436 |36484
--10057 |27215 |37272
--10084 |28035 |38119
--10026 |28336 |38362
--10068 |28941 |39009
--10060 |29175 |39235
+ emp_no:i | salary:i | sum:i
+-10015 |25324 |35339
+-10035 |25945 |35980
+-10092 |25976 |36068
+-10048 |26436 |36484
+-10057 |27215 |37272
+-10084 |28035 |38119
+-10026 |28336 |38362
+-10068 |28941 |39009
+-10060 |29175 |39235
-10042 |30404 |40446
;
@@ -545,16 +566,16 @@ from employees
| limit 10
;
- first_name:keyword | last_name:keyword | salary:integer|ll:keyword|lf:keyword
-Mona |Azuma |46595 |A |M
-Satosi |Awdeh |50249 |A |S
-Brendon |Bernini |33370 |B |B
-Breannda |Billingsley |29175 |B |B
-Cristinel |Bouloucos |58715 |B |C
-Charlene |Brattka |28941 |B |C
-Margareta |Bierman |41933 |B |M
-Mokhtar |Bernatsky |38992 |B |M
-Parto |Bamford |61805 |B |P
+ first_name:keyword | last_name:keyword | salary:integer|ll:keyword|lf:keyword
+Mona |Azuma |46595 |A |M
+Satosi |Awdeh |50249 |A |S
+Brendon |Bernini |33370 |B |B
+Breannda |Billingsley |29175 |B |B
+Cristinel |Bouloucos |58715 |B |C
+Charlene |Brattka |28941 |B |C
+Margareta |Bierman |41933 |B |M
+Mokhtar |Bernatsky |38992 |B |M
+Parto |Bamford |61805 |B |P
Premal |Baek |52833 |B |P
;
@@ -568,15 +589,15 @@ from employees
| limit 10
;
- fn:keyword | ln:keyword | salary:integer| c:keyword
-Mona |Azuma |46595 |AM
-Satosi |Awdeh |50249 |AS
-Brendon |Bernini |33370 |BB
-Breannda |Billingsley |29175 |BB
-Cristinel |Bouloucos |58715 |BC
-Charlene |Brattka |28941 |BC
-Margareta |Bierman |41933 |BM
-Mokhtar |Bernatsky |38992 |BM
-Parto |Bamford |61805 |BP
+ fn:keyword | ln:keyword | salary:integer| c:keyword
+Mona |Azuma |46595 |AM
+Satosi |Awdeh |50249 |AS
+Brendon |Bernini |33370 |BB
+Breannda |Billingsley |29175 |BB
+Cristinel |Bouloucos |58715 |BC
+Charlene |Brattka |28941 |BC
+Margareta |Bierman |41933 |BM
+Mokhtar |Bernatsky |38992 |BM
+Parto |Bamford |61805 |BP
Premal |Baek |52833 |BP
;
diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/string/ByteLengthEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/string/ByteLengthEvaluator.java
new file mode 100644
index 0000000000000..1b0bff92d7d04
--- /dev/null
+++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/string/ByteLengthEvaluator.java
@@ -0,0 +1,127 @@
+// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+// or more contributor license agreements. Licensed under the Elastic License
+// 2.0; you may not use this file except in compliance with the Elastic License
+// 2.0.
+package org.elasticsearch.xpack.esql.expression.function.scalar.string;
+
+import java.lang.IllegalArgumentException;
+import java.lang.Override;
+import java.lang.String;
+import org.apache.lucene.util.BytesRef;
+import org.elasticsearch.compute.data.Block;
+import org.elasticsearch.compute.data.BytesRefBlock;
+import org.elasticsearch.compute.data.BytesRefVector;
+import org.elasticsearch.compute.data.IntBlock;
+import org.elasticsearch.compute.data.IntVector;
+import org.elasticsearch.compute.data.Page;
+import org.elasticsearch.compute.operator.DriverContext;
+import org.elasticsearch.compute.operator.EvalOperator;
+import org.elasticsearch.compute.operator.Warnings;
+import org.elasticsearch.core.Releasables;
+import org.elasticsearch.xpack.esql.core.tree.Source;
+
+/**
+ * {@link EvalOperator.ExpressionEvaluator} implementation for {@link ByteLength}.
+ * This class is generated. Do not edit it.
+ */
+public final class ByteLengthEvaluator implements EvalOperator.ExpressionEvaluator {
+ private final Source source;
+
+ private final EvalOperator.ExpressionEvaluator val;
+
+ private final DriverContext driverContext;
+
+ private Warnings warnings;
+
+ public ByteLengthEvaluator(Source source, EvalOperator.ExpressionEvaluator val,
+ DriverContext driverContext) {
+ this.source = source;
+ this.val = val;
+ this.driverContext = driverContext;
+ }
+
+ @Override
+ public Block eval(Page page) {
+ try (BytesRefBlock valBlock = (BytesRefBlock) val.eval(page)) {
+ BytesRefVector valVector = valBlock.asVector();
+ if (valVector == null) {
+ return eval(page.getPositionCount(), valBlock);
+ }
+ return eval(page.getPositionCount(), valVector).asBlock();
+ }
+ }
+
+ public IntBlock eval(int positionCount, BytesRefBlock valBlock) {
+ try(IntBlock.Builder result = driverContext.blockFactory().newIntBlockBuilder(positionCount)) {
+ BytesRef valScratch = new BytesRef();
+ position: for (int p = 0; p < positionCount; p++) {
+ if (valBlock.isNull(p)) {
+ result.appendNull();
+ continue position;
+ }
+ if (valBlock.getValueCount(p) != 1) {
+ if (valBlock.getValueCount(p) > 1) {
+ warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value"));
+ }
+ result.appendNull();
+ continue position;
+ }
+ result.appendInt(ByteLength.process(valBlock.getBytesRef(valBlock.getFirstValueIndex(p), valScratch)));
+ }
+ return result.build();
+ }
+ }
+
+ public IntVector eval(int positionCount, BytesRefVector valVector) {
+ try(IntVector.FixedBuilder result = driverContext.blockFactory().newIntVectorFixedBuilder(positionCount)) {
+ BytesRef valScratch = new BytesRef();
+ position: for (int p = 0; p < positionCount; p++) {
+ result.appendInt(p, ByteLength.process(valVector.getBytesRef(p, valScratch)));
+ }
+ return result.build();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "ByteLengthEvaluator[" + "val=" + val + "]";
+ }
+
+ @Override
+ public void close() {
+ Releasables.closeExpectNoException(val);
+ }
+
+ private Warnings warnings() {
+ if (warnings == null) {
+ this.warnings = Warnings.createWarnings(
+ driverContext.warningsMode(),
+ source.source().getLineNumber(),
+ source.source().getColumnNumber(),
+ source.text()
+ );
+ }
+ return warnings;
+ }
+
+ static class Factory implements EvalOperator.ExpressionEvaluator.Factory {
+ private final Source source;
+
+ private final EvalOperator.ExpressionEvaluator.Factory val;
+
+ public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory val) {
+ this.source = source;
+ this.val = val;
+ }
+
+ @Override
+ public ByteLengthEvaluator get(DriverContext context) {
+ return new ByteLengthEvaluator(source, val.get(context), context);
+ }
+
+ @Override
+ public String toString() {
+ return "ByteLengthEvaluator[" + "val=" + val + "]";
+ }
+ }
+}
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java
index b0111485adbe7..0d6af0ec3bbb1 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java
@@ -33,6 +33,11 @@ public enum Cap {
*/
FN_BIT_LENGTH,
+ /**
+ * Support for function {@code BYTE_LENGTH}.
+ */
+ FN_BYTE_LENGTH,
+
/**
* Support for function {@code REVERSE}.
*/
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java
index 7a6ff79d79a65..d1aef0e46caca 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java
@@ -118,6 +118,7 @@
import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StX;
import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StY;
import org.elasticsearch.xpack.esql.expression.function.scalar.string.BitLength;
+import org.elasticsearch.xpack.esql.expression.function.scalar.string.ByteLength;
import org.elasticsearch.xpack.esql.expression.function.scalar.string.Concat;
import org.elasticsearch.xpack.esql.expression.function.scalar.string.EndsWith;
import org.elasticsearch.xpack.esql.expression.function.scalar.string.LTrim;
@@ -308,6 +309,7 @@ private FunctionDefinition[][] functions() {
// string
new FunctionDefinition[] {
def(BitLength.class, BitLength::new, "bit_length"),
+ def(ByteLength.class, ByteLength::new, "byte_length"),
def(Concat.class, Concat::new, "concat"),
def(EndsWith.class, EndsWith::new, "ends_with"),
def(LTrim.class, LTrim::new, "ltrim"),
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/UnaryScalarFunction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/UnaryScalarFunction.java
index e9ca69055658d..610fe1c5ea000 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/UnaryScalarFunction.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/UnaryScalarFunction.java
@@ -55,6 +55,7 @@
import org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.AbstractMultivalueFunction;
import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StX;
import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StY;
+import org.elasticsearch.xpack.esql.expression.function.scalar.string.ByteLength;
import org.elasticsearch.xpack.esql.expression.function.scalar.string.LTrim;
import org.elasticsearch.xpack.esql.expression.function.scalar.string.Length;
import org.elasticsearch.xpack.esql.expression.function.scalar.string.RLike;
@@ -80,6 +81,7 @@ public static List getNamedWriteables() {
entries.add(Acos.ENTRY);
entries.add(Asin.ENTRY);
entries.add(Atan.ENTRY);
+ entries.add(ByteLength.ENTRY);
entries.add(Cbrt.ENTRY);
entries.add(Ceil.ENTRY);
entries.add(Cos.ENTRY);
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/BitLength.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/BitLength.java
index 5deb6fa7feba6..ad8b46df29df2 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/BitLength.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/BitLength.java
@@ -40,6 +40,7 @@ public class BitLength extends UnaryScalarFunction {
@FunctionInfo(
returnType = "integer",
description = "Returns the bit length of a string.",
+ note = "All strings are in UTF-8, so a single character can use multiple bytes.",
examples = @Example(file = "docs", tag = "bitLength")
)
public BitLength(
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/ByteLength.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/ByteLength.java
new file mode 100644
index 0000000000000..f967b20b8be32
--- /dev/null
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/ByteLength.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+package org.elasticsearch.xpack.esql.expression.function.scalar.string;
+
+import org.apache.lucene.util.BytesRef;
+import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
+import org.elasticsearch.common.io.stream.StreamInput;
+import org.elasticsearch.compute.ann.Evaluator;
+import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator;
+import org.elasticsearch.xpack.esql.core.expression.Expression;
+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.expression.function.Example;
+import org.elasticsearch.xpack.esql.expression.function.FunctionInfo;
+import org.elasticsearch.xpack.esql.expression.function.Param;
+import org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.DEFAULT;
+import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isString;
+
+public class ByteLength extends UnaryScalarFunction {
+ public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(
+ Expression.class,
+ "ByteLength",
+ ByteLength::new
+ );
+
+ @FunctionInfo(
+ returnType = "integer",
+ description = "Returns the byte length of a string.",
+ note = "All strings are in UTF-8, so a single character can use multiple bytes.",
+ examples = @Example(file = "eval", tag = "byteLength")
+ )
+ public ByteLength(
+ Source source,
+ @Param(
+ name = "string",
+ type = { "keyword", "text" },
+ description = "String expression. If `null`, the function returns `null`."
+ ) Expression field
+ ) {
+ super(source, field);
+ }
+
+ private ByteLength(StreamInput in) throws IOException {
+ super(in);
+ }
+
+ @Override
+ public String getWriteableName() {
+ return ENTRY.name;
+ }
+
+ @Override
+ public DataType dataType() {
+ return DataType.INTEGER;
+ }
+
+ @Override
+ protected TypeResolution resolveType() {
+ return childrenResolved() ? isString(field(), sourceText(), DEFAULT) : new TypeResolution("Unresolved children");
+ }
+
+ @Evaluator
+ static int process(BytesRef val) {
+ return val.length;
+ }
+
+ @Override
+ public Expression replaceChildren(List newChildren) {
+ return new ByteLength(source(), newChildren.get(0));
+ }
+
+ @Override
+ protected NodeInfo extends Expression> info() {
+ return NodeInfo.create(this, ByteLength::new, field());
+ }
+
+ @Override
+ public ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvaluator) {
+ return new ByteLengthEvaluator.Factory(source(), toEvaluator.apply(field()));
+ }
+}
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Length.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Length.java
index f4bb7f35cb466..3b442a8583a0a 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Length.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Length.java
@@ -34,6 +34,7 @@ public class Length extends UnaryScalarFunction {
@FunctionInfo(
returnType = "integer",
description = "Returns the character length of a string.",
+ note = "All strings are in UTF-8, so a single character can use multiple bytes.",
examples = @Example(file = "eval", tag = "length")
)
public Length(
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/ByteLengthSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/ByteLengthSerializationTests.java
new file mode 100644
index 0000000000000..98b5268797c8c
--- /dev/null
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/ByteLengthSerializationTests.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+package org.elasticsearch.xpack.esql.expression.function.scalar.string;
+
+import org.elasticsearch.xpack.esql.core.expression.Expression;
+import org.elasticsearch.xpack.esql.core.tree.Source;
+import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests;
+
+public class ByteLengthSerializationTests extends AbstractUnaryScalarSerializationTests {
+ @Override
+ protected ByteLength create(Source source, Expression child) {
+ return new ByteLength(source, child);
+ }
+}
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/ByteLengthTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/ByteLengthTests.java
new file mode 100644
index 0000000000000..866b8e0cd8da3
--- /dev/null
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/ByteLengthTests.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+package org.elasticsearch.xpack.esql.expression.function.scalar.string;
+
+import com.carrotsearch.randomizedtesting.annotations.Name;
+import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
+
+import org.apache.lucene.util.BytesRef;
+import org.elasticsearch.xpack.esql.core.expression.Expression;
+import org.elasticsearch.xpack.esql.core.tree.Source;
+import org.elasticsearch.xpack.esql.core.type.DataType;
+import org.elasticsearch.xpack.esql.expression.function.AbstractScalarFunctionTestCase;
+import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Supplier;
+import java.util.stream.Stream;
+
+import static org.hamcrest.Matchers.equalTo;
+
+public class ByteLengthTests extends AbstractScalarFunctionTestCase {
+ public ByteLengthTests(@Name("TestCase") Supplier testCaseSupplier) {
+ this.testCase = testCaseSupplier.get();
+ }
+
+ @ParametersFactory
+ public static Iterable