mirror of
https://github.com/elastic/elasticsearch.git
synced 2025-06-28 17:34:17 -04:00
Implement reading from null safe dereferences
Null safe dereferences make handling null or missing values shorter. Compare without: ``` if (ctx._source.missing != null && ctx._source.missing.foo != null) { ctx._source.foo_length = ctx.source.missing.foo.length() } ``` To with: ``` Integer length = ctx._source.missing?.foo?.length(); if (length != null) { ctx._source.foo_length = length } ``` Combining this with the as of yet unimplemented elvis operator allows for very concise defaults for nulls: ``` ctx._source.foo_length = ctx._source.missing?.foo?.length() ?: 0; ``` Since you have to start somewhere, we started with null safe dereferenes. Anyway, this is a feature borrowed from groovy. Groovy allows writing to null values like: ``` def v = null v?.field = 'cat' ``` And the writes are simply ignored. Painless doesn't support this at this point because it'd be complex to implement and maybe not all that useful. There is no runtime cost for this feature if it is not used. When it is used we implement it fairly efficiently, adding a jump rather than a temporary variable. This should also work fairly well with doc values.
This commit is contained in:
parent
b743ab0b07
commit
d03b8e4abb
13 changed files with 699 additions and 295 deletions
|
@ -130,6 +130,37 @@ using these characters:
|
|||
|`x` | COMMENTS (aka extended) | `'a' ==~ /a #comment/x`
|
||||
|=======================================================================
|
||||
|
||||
[float]
|
||||
[[painless-deref]]
|
||||
=== Dereferences
|
||||
|
||||
Like lots of languages, Painless uses `.` to reference fields and call methods:
|
||||
|
||||
[source,painless]
|
||||
---------------------------------------------------------
|
||||
String foo = 'foo';
|
||||
TypeWithGetterOrPublicField bar = new TypeWithGetterOrPublicField()
|
||||
return foo.length() + bar.x
|
||||
---------------------------------------------------------
|
||||
|
||||
Like Groovy, Painless uses `?.` to perform null-safe references, with the
|
||||
result being `null` if the left hand side is null:
|
||||
|
||||
[source,painless]
|
||||
---------------------------------------------------------
|
||||
String foo = null;
|
||||
return foo?.length() // Returns null
|
||||
---------------------------------------------------------
|
||||
|
||||
Unlike Groovy, Painless doesn't support writing to null values with this
|
||||
operator:
|
||||
|
||||
[source,painless]
|
||||
---------------------------------------------------------
|
||||
TypeWithSetterOrPublicField foo = null;
|
||||
foo?.x = 'bar' // Compile error
|
||||
---------------------------------------------------------
|
||||
|
||||
[float]
|
||||
[[painless-operators]]
|
||||
=== Operators
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue