Implement the ?: operator in painless (#21506)

Implements a null coalescing operator in painless that looks like `?:`. This form was chosen to emulate Groovy's `?:` operator. It is different in that it only coalesces null values, instead of Groovy's `?:` operator which coalesces all falsy values. I believe that makes it the same as Kotlin's `?:` operator. In other languages this operator looks like `??` (C#) and `COALESCE` (SQL) and `:-` (bash).

This operator is lazy, meaning the right hand side is only evaluated at all if the left hand side is null.
This commit is contained in:
Nik Everett 2016-11-18 13:54:26 -05:00 committed by GitHub
parent 484ad31ed9
commit ae468441dc
17 changed files with 1344 additions and 1003 deletions

View file

@ -175,6 +175,21 @@ There are only a few minor differences and add-ons:
* `=~` true if a portion of the text matches a pattern (e.g. `x =~ /b/`)
* `==~` true if the entire text matches a pattern (e.g. `x ==~ /[Bb]ob/`)
The `?:` (aka Elvis) operator coalesces null values. So `x ?: 0` is `0` if `x`
is `null` and whatever value `x` has otherwise. It is a convenient way to write
default values like `doc['x'].value ?: 0` which is 0 if `x` is not in the
document being processed. It can also work with null safe dereferences to
efficiently handle null in chains. For example,
`doc['foo.keyword'].value?.length() ?: 0` is 0 if the document being processed
doesn't have a `foo.keyword` field but is the length of that field if it does.
Lastly, `?:` is lazy so the right hand side is not evaluated at all if the left
hand side isn't null.
NOTE: Unlike Groovy, Painless' `?:` operator only coalesces `null`, not `false`
or http://groovy-lang.org/semantics.html#Groovy-Truth[falsy] values. Strictly
speaking Painless' `?:` is more like Kotlin's `?:` than Groovy's `?:`.
[float]
[[painless-control-flow]]
=== Control flow