Skip to content

Commit

Permalink
ESQL: Introduce a casting operator, :: (elastic#107409)
Browse files Browse the repository at this point in the history
This adds support for an "inline" casting operator, `::`. The operator
can be used with literals, fields and functions.

The operator delegates to one the existing `to_xxx()` conversion
functions, so only the types for which such a converter exist can be
cast to with the new opeator.

For convenience, a list of type name aliases are introduced as well.

Example: `ROW 1::bool, "1"::int`
  • Loading branch information
bpintea authored Apr 18, 2024
1 parent f1bcb33 commit d7c5557
Show file tree
Hide file tree
Showing 20 changed files with 2,275 additions and 1,749 deletions.
5 changes: 5 additions & 0 deletions docs/changelog/107409.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 107409
summary: "ESQL: Introduce a casting operator, `::`"
area: ES|QL
type: feature
issues: []
169 changes: 169 additions & 0 deletions x-pack/plugin/esql/qa/testFixtures/src/main/resources/convert.csv-spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
// Conversion-specific tests

convertToBoolean
required_feature: esql.casting_operator
ROW zero=0::boolean, one=1::bool
;

zero:boolean | one:boolean
false |true
;

convertToInteger
required_feature: esql.casting_operator
ROW zero="0"::integer, one="1"::int
;

zero:integer | one:integer
0 |1
;

convertToIP
required_feature: esql.casting_operator
ROW ip="1.1.1.1"::ip
;

ip:ip
1.1.1.1
;

convertToLong
required_feature: esql.casting_operator
ROW long="-1"::long
;

long:long
-1
;

convertToLongWithWarning
required_feature: esql.casting_operator
ROW long="1.1.1.1"::long
;
warning:Line 1:10: evaluation of [\"1.1.1.1\"::long] failed, treating result as null. Only first 20 failures recorded.
warning:Line 1:10: org.elasticsearch.xpack.ql.InvalidArgumentException: Cannot parse number [1.1.1.1]

long:long
null
;

convertToDouble
required_feature: esql.casting_operator
ROW zero="0"::double
;

zero:double
0.0
;

convertToString
required_feature: esql.casting_operator
ROW one=1::keyword, two=2::text, three=3::string
;

one:keyword | two:keyword | three:keyword
1 |2 |3
;

convertToDatetime
required_feature: esql.casting_operator
ROW date="1985-01-01T00:00:00Z"::datetime, zero=0::datetime
;

date:datetime | zero:datetime
1985-01-01T00:00:00.000Z|1970-01-01T00:00:00.000Z
;

convertToVersion
required_feature: esql.casting_operator
ROW ver="1.2.3"::version
;

ver:version
1.2.3
;

convertToUnsignedLong
required_feature: esql.casting_operator
ROW zero="0"::unsigned_long, two=abs(-2)::UnsigneD_LOng
;

zero:unsigned_long | two:unsigned_long
0 |2
;

convertToGeoPoint
required_feature: esql.casting_operator
ROW gp="POINT(0 0)"::geo_point
;

gp:geo_point
POINT (0.0 0.0)
;

convertToGeoShape
required_feature: esql.casting_operator
ROW gs="POINT(0 0)"::geo_shape
;

gs:geo_shape
POINT (0.0 0.0)
;

convertToCartesianPoint
required_feature: esql.casting_operator
ROW cp="POINT(0 0)"::cartesian_point
;

cp:cartesian_point
POINT (0.0 0.0)
;

convertToCartesianShape
required_feature: esql.casting_operator
ROW cs="POINT(0 0)"::cartesian_shape
;

cs:cartesian_shape
POINT (0.0 0.0)
;

convertChained
required_feature: esql.casting_operator
ROW one=1::STRING::LONG::BOOL
;

one:boolean
true
;

convertWithIndexMultipleConversionsInSameExpressionAndConversionInFiltering
required_feature: esql.casting_operator
FROM employees
| EVAL en_str=emp_no::STRING, bd=ABS(birth_date::LONG)::STRING
| KEEP en_str, emp_no, bd, birth_date
| WHERE ABS(birth_date::LONG) < 176169600000
| SORT emp_no
;

en_str:keyword| emp_no:integer| bd:keyword | birth_date:datetime
10092 |10092 |164246400000 |1964-10-18T00:00:00.000Z
10093 |10093 |175392000000 |1964-06-11T00:00:00.000Z
10095 |10095 |157593600000 |1965-01-03T00:00:00.000Z
;

convertWithBoolExpressionAndQualifiedName
required_feature: esql.casting_operator
FROM employees
| EVAL neg = (NOT still_hired)::string, sf = ROUND(height.scaled_float::double, 2)
| KEEP emp_no, still_hired, neg, sf
| SORT emp_no
| WHERE neg == "false"
| LIMIT 3
;

emp_no:integer| still_hired:boolean | neg:keyword | sf:double
10001 |true |false |2.03
10002 |true |false |2.08
10004 |true |false |1.78
;
1 change: 1 addition & 0 deletions x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ BY : 'by';
AND : 'and';
ASC : 'asc';
ASSIGN : '=';
CAST_OP : '::';
COMMA : ',';
DESC : 'desc';
DOT : '.';
Expand Down
Loading

0 comments on commit d7c5557

Please sign in to comment.