mirror of
https://github.com/elastic/elasticsearch.git
synced 2025-06-28 17:34:17 -04:00
Runtime fields to optionally ignore script errors (#92380)
Currently Elasticsearch always returns a shard failure once a runtime error arises from using a runtime field, the exception being script-less runtime fields. This also means that execution of the query for that shard stops, which is okay for development and exploration. In a production scenario, however, it is often desirable to ignore runtime errors and continue with the query execution. This change adds a new a new on_script_error parameter to runtime field definitions similar to the already existing parameter for index-time scripted fields. When `on_script_error` is set to `continue`, errors from script execution are effectively ignored. This means affected documents don't show up in query results, but also don't prevent other matches from the same shard. Runtime fields accessed through the fields API don't return values on errors, aggregations will ignore documents that throw errors. Note that this change affects scripted runtime fields only, while leaving default behaviour untouched. Also, ignored errors are not reported back to users for now. Relates to #72143
This commit is contained in:
parent
3bbf202843
commit
8067f01d48
78 changed files with 2184 additions and 303 deletions
5
docs/changelog/92380.yaml
Normal file
5
docs/changelog/92380.yaml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
pr: 92380
|
||||||
|
summary: Add option to allow script errors on runtime fields
|
||||||
|
area: Search
|
||||||
|
type: enhancement
|
||||||
|
issues: []
|
|
@ -227,6 +227,16 @@ with `params._source` (such as `params._source.day_of_week`). For simplicity,
|
||||||
defining a runtime field in the mapping definition without a script is the
|
defining a runtime field in the mapping definition without a script is the
|
||||||
recommended option, whenever possible.
|
recommended option, whenever possible.
|
||||||
|
|
||||||
|
[[runtime-errorhandling]]
|
||||||
|
==== Ignoring script errors on runtime fields
|
||||||
|
|
||||||
|
Scripts can throw errors at runtime, e.g. on accessing missing or invalid values
|
||||||
|
in documents or because of performing invalid operations. The `on_script_error`
|
||||||
|
parameter can be used to control error behaviour when this happens. Setting this
|
||||||
|
parameter to `continue` will have the effect of silently ignoring all errors on
|
||||||
|
this runtime field. The default `fail` value will cause a shard failure which
|
||||||
|
gets reported in the search response.
|
||||||
|
|
||||||
[[runtime-updating-scripts]]
|
[[runtime-updating-scripts]]
|
||||||
==== Updating and removing runtime fields
|
==== Updating and removing runtime fields
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ import org.elasticsearch.index.Index;
|
||||||
import org.elasticsearch.index.IndexService;
|
import org.elasticsearch.index.IndexService;
|
||||||
import org.elasticsearch.index.mapper.DateFieldMapper;
|
import org.elasticsearch.index.mapper.DateFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||||
|
import org.elasticsearch.index.mapper.OnScriptError;
|
||||||
import org.elasticsearch.index.mapper.ParsedDocument;
|
import org.elasticsearch.index.mapper.ParsedDocument;
|
||||||
import org.elasticsearch.index.mapper.SourceToParse;
|
import org.elasticsearch.index.mapper.SourceToParse;
|
||||||
import org.elasticsearch.index.query.AbstractQueryBuilder;
|
import org.elasticsearch.index.query.AbstractQueryBuilder;
|
||||||
|
@ -557,7 +558,8 @@ public class PainlessExecuteAction extends ActionType<PainlessExecuteAction.Resp
|
||||||
BooleanFieldScript.LeafFactory leafFactory = factory.newFactory(
|
BooleanFieldScript.LeafFactory leafFactory = factory.newFactory(
|
||||||
BooleanFieldScript.CONTEXT.name,
|
BooleanFieldScript.CONTEXT.name,
|
||||||
request.getScript().getParams(),
|
request.getScript().getParams(),
|
||||||
context.lookup()
|
context.lookup(),
|
||||||
|
OnScriptError.FAIL
|
||||||
);
|
);
|
||||||
BooleanFieldScript booleanFieldScript = leafFactory.newInstance(leafReaderContext);
|
BooleanFieldScript booleanFieldScript = leafFactory.newInstance(leafReaderContext);
|
||||||
List<Boolean> booleans = new ArrayList<>();
|
List<Boolean> booleans = new ArrayList<>();
|
||||||
|
@ -571,7 +573,8 @@ public class PainlessExecuteAction extends ActionType<PainlessExecuteAction.Resp
|
||||||
DateFieldScript.CONTEXT.name,
|
DateFieldScript.CONTEXT.name,
|
||||||
request.getScript().getParams(),
|
request.getScript().getParams(),
|
||||||
context.lookup(),
|
context.lookup(),
|
||||||
DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER
|
DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER,
|
||||||
|
OnScriptError.FAIL
|
||||||
);
|
);
|
||||||
DateFieldScript dateFieldScript = leafFactory.newInstance(leafReaderContext);
|
DateFieldScript dateFieldScript = leafFactory.newInstance(leafReaderContext);
|
||||||
List<String> dates = new ArrayList<>();
|
List<String> dates = new ArrayList<>();
|
||||||
|
@ -584,7 +587,8 @@ public class PainlessExecuteAction extends ActionType<PainlessExecuteAction.Resp
|
||||||
DoubleFieldScript.LeafFactory leafFactory = factory.newFactory(
|
DoubleFieldScript.LeafFactory leafFactory = factory.newFactory(
|
||||||
DoubleFieldScript.CONTEXT.name,
|
DoubleFieldScript.CONTEXT.name,
|
||||||
request.getScript().getParams(),
|
request.getScript().getParams(),
|
||||||
context.lookup()
|
context.lookup(),
|
||||||
|
OnScriptError.FAIL
|
||||||
);
|
);
|
||||||
DoubleFieldScript doubleFieldScript = leafFactory.newInstance(leafReaderContext);
|
DoubleFieldScript doubleFieldScript = leafFactory.newInstance(leafReaderContext);
|
||||||
List<Double> doubles = new ArrayList<>();
|
List<Double> doubles = new ArrayList<>();
|
||||||
|
@ -597,7 +601,8 @@ public class PainlessExecuteAction extends ActionType<PainlessExecuteAction.Resp
|
||||||
GeoPointFieldScript.LeafFactory leafFactory = factory.newFactory(
|
GeoPointFieldScript.LeafFactory leafFactory = factory.newFactory(
|
||||||
GeoPointFieldScript.CONTEXT.name,
|
GeoPointFieldScript.CONTEXT.name,
|
||||||
request.getScript().getParams(),
|
request.getScript().getParams(),
|
||||||
context.lookup()
|
context.lookup(),
|
||||||
|
OnScriptError.FAIL
|
||||||
);
|
);
|
||||||
GeoPointFieldScript geoPointFieldScript = leafFactory.newInstance(leafReaderContext);
|
GeoPointFieldScript geoPointFieldScript = leafFactory.newInstance(leafReaderContext);
|
||||||
List<GeoPoint> points = new ArrayList<>();
|
List<GeoPoint> points = new ArrayList<>();
|
||||||
|
@ -615,7 +620,8 @@ public class PainlessExecuteAction extends ActionType<PainlessExecuteAction.Resp
|
||||||
IpFieldScript.LeafFactory leafFactory = factory.newFactory(
|
IpFieldScript.LeafFactory leafFactory = factory.newFactory(
|
||||||
IpFieldScript.CONTEXT.name,
|
IpFieldScript.CONTEXT.name,
|
||||||
request.getScript().getParams(),
|
request.getScript().getParams(),
|
||||||
context.lookup()
|
context.lookup(),
|
||||||
|
OnScriptError.FAIL
|
||||||
);
|
);
|
||||||
IpFieldScript ipFieldScript = leafFactory.newInstance(leafReaderContext);
|
IpFieldScript ipFieldScript = leafFactory.newInstance(leafReaderContext);
|
||||||
List<String> ips = new ArrayList<>();
|
List<String> ips = new ArrayList<>();
|
||||||
|
@ -634,7 +640,8 @@ public class PainlessExecuteAction extends ActionType<PainlessExecuteAction.Resp
|
||||||
LongFieldScript.LeafFactory leafFactory = factory.newFactory(
|
LongFieldScript.LeafFactory leafFactory = factory.newFactory(
|
||||||
LongFieldScript.CONTEXT.name,
|
LongFieldScript.CONTEXT.name,
|
||||||
request.getScript().getParams(),
|
request.getScript().getParams(),
|
||||||
context.lookup()
|
context.lookup(),
|
||||||
|
OnScriptError.FAIL
|
||||||
);
|
);
|
||||||
LongFieldScript longFieldScript = leafFactory.newInstance(leafReaderContext);
|
LongFieldScript longFieldScript = leafFactory.newInstance(leafReaderContext);
|
||||||
List<Long> longs = new ArrayList<>();
|
List<Long> longs = new ArrayList<>();
|
||||||
|
@ -647,7 +654,8 @@ public class PainlessExecuteAction extends ActionType<PainlessExecuteAction.Resp
|
||||||
StringFieldScript.LeafFactory leafFactory = factory.newFactory(
|
StringFieldScript.LeafFactory leafFactory = factory.newFactory(
|
||||||
StringFieldScript.CONTEXT.name,
|
StringFieldScript.CONTEXT.name,
|
||||||
request.getScript().getParams(),
|
request.getScript().getParams(),
|
||||||
context.lookup()
|
context.lookup(),
|
||||||
|
OnScriptError.FAIL
|
||||||
);
|
);
|
||||||
StringFieldScript stringFieldScript = leafFactory.newInstance(leafReaderContext);
|
StringFieldScript stringFieldScript = leafFactory.newInstance(leafReaderContext);
|
||||||
List<String> keywords = new ArrayList<>();
|
List<String> keywords = new ArrayList<>();
|
||||||
|
@ -660,7 +668,8 @@ public class PainlessExecuteAction extends ActionType<PainlessExecuteAction.Resp
|
||||||
CompositeFieldScript.LeafFactory leafFactory = factory.newFactory(
|
CompositeFieldScript.LeafFactory leafFactory = factory.newFactory(
|
||||||
CompositeFieldScript.CONTEXT.name,
|
CompositeFieldScript.CONTEXT.name,
|
||||||
request.getScript().getParams(),
|
request.getScript().getParams(),
|
||||||
context.lookup()
|
context.lookup(),
|
||||||
|
OnScriptError.FAIL
|
||||||
);
|
);
|
||||||
CompositeFieldScript compositeFieldScript = leafFactory.newInstance(leafReaderContext);
|
CompositeFieldScript compositeFieldScript = leafFactory.newInstance(leafReaderContext);
|
||||||
compositeFieldScript.runForDoc(0);
|
compositeFieldScript.runForDoc(0);
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
---
|
||||||
|
setup:
|
||||||
|
- do:
|
||||||
|
indices.create:
|
||||||
|
index: test
|
||||||
|
body:
|
||||||
|
settings:
|
||||||
|
number_of_shards: 1
|
||||||
|
number_of_replicas: 0
|
||||||
|
mappings:
|
||||||
|
runtime:
|
||||||
|
rtf:
|
||||||
|
type: composite
|
||||||
|
on_script_error: continue
|
||||||
|
script:
|
||||||
|
source: |
|
||||||
|
if (doc["message"].value.equals("fail")) throw new Exception("error");
|
||||||
|
emit('msg', doc['message'].value);
|
||||||
|
fields:
|
||||||
|
msg:
|
||||||
|
type: keyword
|
||||||
|
rtf_strict:
|
||||||
|
type: composite
|
||||||
|
on_script_error: fail
|
||||||
|
script:
|
||||||
|
source: |
|
||||||
|
if (doc["message"].value.equals("fail")) throw new Exception("error");
|
||||||
|
emit('msg', doc['message'].value);
|
||||||
|
fields:
|
||||||
|
msg:
|
||||||
|
type: keyword
|
||||||
|
properties:
|
||||||
|
timestamp:
|
||||||
|
type: date
|
||||||
|
message:
|
||||||
|
type: keyword
|
||||||
|
|
||||||
|
- do:
|
||||||
|
bulk:
|
||||||
|
index: test
|
||||||
|
refresh: true
|
||||||
|
body: |
|
||||||
|
{"index":{}}
|
||||||
|
{"timestamp": "1998-04-30T14:30:17-05:00", "message" : "this is okay"}
|
||||||
|
{"index":{}}
|
||||||
|
{"timestamp": "1998-04-30T14:30:53-05:00", "message" : "fail"}
|
||||||
|
|
||||||
|
---
|
||||||
|
"query with continue on error":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: test
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
term:
|
||||||
|
rtf.msg: "this is okay"
|
||||||
|
- match: { hits.total.value: 1 }
|
||||||
|
- match: { hits.hits.0._source.message: "this is okay"}
|
||||||
|
|
||||||
|
---
|
||||||
|
"query with fail on error":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: test
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
term:
|
||||||
|
rtf_strict.msg: "this is okay"
|
||||||
|
|
||||||
|
---
|
||||||
|
"query with search time field":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: test
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
term:
|
||||||
|
rtf_search.msg: "this is okay"
|
||||||
|
runtime_mappings:
|
||||||
|
rtf_search:
|
||||||
|
type: composite
|
||||||
|
on_script_error: continue
|
||||||
|
script:
|
||||||
|
source: |
|
||||||
|
if (doc["message"].value.equals("fail")) throw new Exception("error");
|
||||||
|
emit('msg', doc['message'].value);
|
||||||
|
fields:
|
||||||
|
msg:
|
||||||
|
type: keyword
|
||||||
|
|
||||||
|
- match: { hits.total.value: 1 }
|
||||||
|
- match: { hits.hits.0._source.message: "this is okay"}
|
||||||
|
|
||||||
|
---
|
||||||
|
fetch:
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: test
|
||||||
|
body:
|
||||||
|
sort: timestamp
|
||||||
|
fields:
|
||||||
|
- message
|
||||||
|
- rtf.msg
|
||||||
|
- match: {hits.total.value: 2}
|
||||||
|
- match: {hits.hits.0.fields.message: ["this is okay"] }
|
||||||
|
- match: {hits.hits.0.fields.rtf\.msg: ["this is okay"] }
|
||||||
|
- match: {hits.hits.1.fields.message: ["fail"] }
|
||||||
|
- is_false: hits.hits.1.fields.rtf.msg
|
||||||
|
|
||||||
|
---
|
||||||
|
"terms agg":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: test
|
||||||
|
body:
|
||||||
|
aggs:
|
||||||
|
messages:
|
||||||
|
terms:
|
||||||
|
field: rtf.msg
|
||||||
|
- match: { hits.total.value: 2}
|
||||||
|
- length: { aggregations.messages.buckets: 1 }
|
||||||
|
- match: { aggregations.messages.buckets.0.key: "this is okay" }
|
||||||
|
- match: { aggregations.messages.buckets.0.doc_count: 1 }
|
|
@ -0,0 +1,216 @@
|
||||||
|
---
|
||||||
|
setup:
|
||||||
|
- do:
|
||||||
|
indices.create:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
settings:
|
||||||
|
number_of_shards: 1
|
||||||
|
mappings:
|
||||||
|
runtime:
|
||||||
|
first_char:
|
||||||
|
type: keyword
|
||||||
|
script: |
|
||||||
|
emit(doc['name'].value.substring(0,1));
|
||||||
|
on_script_error: continue
|
||||||
|
first_char_strict_error:
|
||||||
|
type: keyword
|
||||||
|
script: |
|
||||||
|
emit(doc['name'].value.substring(0,1));
|
||||||
|
on_script_error: fail
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: keyword
|
||||||
|
|
||||||
|
- do:
|
||||||
|
bulk:
|
||||||
|
index: testindex
|
||||||
|
refresh: true
|
||||||
|
body: |
|
||||||
|
{"index":{}}
|
||||||
|
{"name": "foo"}
|
||||||
|
{"index":{}}
|
||||||
|
{"name": ""}
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query rtf with on_script_error continue":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
match:
|
||||||
|
first_char: "f"
|
||||||
|
fields: [ name, first_char ]
|
||||||
|
- match: { hits.total.value: 1 }
|
||||||
|
- match: { hits.hits.0.fields.name: [ foo ] }
|
||||||
|
- match: { hits.hits.0.fields.first_char: [ f ] }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query rtf with on_script_error fail":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
match:
|
||||||
|
first_char_strict_error: "f"
|
||||||
|
fields: [ name, first_char_strict_error ]
|
||||||
|
|
||||||
|
---
|
||||||
|
"Aggregate on rtf with on_script_error continue":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
aggs:
|
||||||
|
firstchar:
|
||||||
|
terms:
|
||||||
|
field: first_char
|
||||||
|
- length: { aggregations.firstchar.buckets: 1 }
|
||||||
|
- match: { aggregations.firstchar.buckets.0.key: "f" }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Aggregate on rtf with on_script_error fail":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
aggs:
|
||||||
|
firstchar:
|
||||||
|
terms:
|
||||||
|
field: first_char_strict_error
|
||||||
|
|
||||||
|
---
|
||||||
|
"Fields retrieval with ignoring error":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ name, first_char ]
|
||||||
|
- match: { hits.total.value: 2 }
|
||||||
|
- match: { hits.hits.0.fields.name: [ foo ] }
|
||||||
|
- match: { hits.hits.0.fields.first_char: [ f ] }
|
||||||
|
- match: { hits.hits.1.fields.name: [ "" ] }
|
||||||
|
- is_false: hits.hits.1.fields.first_char
|
||||||
|
|
||||||
|
---
|
||||||
|
"Fields retrieval with failing on error":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ name, first_char_strict_error ]
|
||||||
|
|
||||||
|
---
|
||||||
|
"Sorting with ignoring error":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ name ]
|
||||||
|
sort: first_char
|
||||||
|
- match: { hits.total.value: 2 }
|
||||||
|
- match: { hits.hits.0.fields.name: [ foo ] }
|
||||||
|
- match: { hits.hits.1.fields.name: [ "" ] }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Sorting with with failing on error":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ name ]
|
||||||
|
sort: first_char_strict_error
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query search time rtf with on_script_error continue":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
match:
|
||||||
|
first_char_search: "f"
|
||||||
|
fields: [ name, first_char_search ]
|
||||||
|
runtime_mappings:
|
||||||
|
first_char_search:
|
||||||
|
type: keyword
|
||||||
|
script: |
|
||||||
|
emit(doc['name'].value.substring(0,1));
|
||||||
|
on_script_error: continue
|
||||||
|
|
||||||
|
- match: { hits.total.value: 1 }
|
||||||
|
- match: { hits.hits.0.fields.name: [ foo ] }
|
||||||
|
- match: { hits.hits.0.fields.first_char_search: [ f ] }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query search time rtf with on_script_error fail":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
match:
|
||||||
|
first_char_search: "f"
|
||||||
|
fields: [ name, first_char_search ]
|
||||||
|
runtime_mappings:
|
||||||
|
first_char_search:
|
||||||
|
type: keyword
|
||||||
|
script: |
|
||||||
|
emit(doc['name'].value.substring(0,1));
|
||||||
|
on_script_error: fail
|
||||||
|
|
||||||
|
---
|
||||||
|
"Change error behaviour for lenient runtime field":
|
||||||
|
|
||||||
|
- do:
|
||||||
|
indices.put_mapping:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
runtime:
|
||||||
|
first_char_variant:
|
||||||
|
type: keyword
|
||||||
|
script: |
|
||||||
|
emit(doc['name'].value.substring(0,1));
|
||||||
|
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
match:
|
||||||
|
first_char_variant: "f"
|
||||||
|
|
||||||
|
- do:
|
||||||
|
indices.put_mapping:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
runtime:
|
||||||
|
first_char_variant:
|
||||||
|
type: keyword
|
||||||
|
script: |
|
||||||
|
emit(doc['name'].value.substring(0,1));
|
||||||
|
on_script_error: continue
|
||||||
|
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
match:
|
||||||
|
first_char_variant: "f"
|
||||||
|
fields: [ name, first_char_variant ]
|
||||||
|
- match: { hits.total.value: 1 }
|
||||||
|
- match: { hits.hits.0.fields.name: [ foo ] }
|
||||||
|
- match: { hits.hits.0.fields.first_char_variant: [ f ] }
|
|
@ -0,0 +1,176 @@
|
||||||
|
---
|
||||||
|
setup:
|
||||||
|
- do:
|
||||||
|
indices.create:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
settings:
|
||||||
|
number_of_shards: 1
|
||||||
|
number_of_replicas: 0
|
||||||
|
mappings:
|
||||||
|
runtime:
|
||||||
|
rtf:
|
||||||
|
type: long
|
||||||
|
script: |
|
||||||
|
if(doc['name'].value.equals("")) throw new Exception("empty");
|
||||||
|
emit(doc['name'].value.length());
|
||||||
|
on_script_error: continue
|
||||||
|
rtf_strict_error:
|
||||||
|
type: long
|
||||||
|
script: |
|
||||||
|
if(doc['name'].value.equals("")) throw new Exception("empty");
|
||||||
|
emit(doc['name'].value.length());
|
||||||
|
on_script_error: fail
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: keyword
|
||||||
|
|
||||||
|
- do:
|
||||||
|
bulk:
|
||||||
|
index: testindex
|
||||||
|
refresh: true
|
||||||
|
body: |
|
||||||
|
{"index":{}}
|
||||||
|
{"name": "foo"}
|
||||||
|
{"index":{}}
|
||||||
|
{"name": ""}
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query rtf with on_script_error continue":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
match:
|
||||||
|
rtf: 3
|
||||||
|
fields: [ name, rtf ]
|
||||||
|
- match: { hits.total.value: 1 }
|
||||||
|
- match: { hits.hits.0.fields.name: [ foo ] }
|
||||||
|
- match: { hits.hits.0.fields.rtf: [ 3 ] }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query rtf with on_script_error fail":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
match:
|
||||||
|
rtf_strict_error: 3
|
||||||
|
fields: [ name, rtf_strict_error ]
|
||||||
|
|
||||||
|
---
|
||||||
|
"Aggregate on rtf with on_script_error continue":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
aggs:
|
||||||
|
firstchar:
|
||||||
|
terms:
|
||||||
|
field: rtf
|
||||||
|
- length: { aggregations.firstchar.buckets: 1 }
|
||||||
|
- match: { aggregations.firstchar.buckets.0.key: 3 }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Aggregate on rtf with on_script_error fail":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
aggs:
|
||||||
|
firstchar:
|
||||||
|
terms:
|
||||||
|
field: rtf_strict_error
|
||||||
|
|
||||||
|
---
|
||||||
|
"Fields retrieval with ignoring error":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ name, rtf ]
|
||||||
|
- match: { hits.total.value: 2 }
|
||||||
|
- match: { hits.hits.0.fields.name: [ foo ] }
|
||||||
|
- match: { hits.hits.0.fields.rtf: [ 3 ] }
|
||||||
|
- match: { hits.hits.1.fields.name: [ "" ] }
|
||||||
|
- is_false: hits.hits.1.fields.rtf
|
||||||
|
|
||||||
|
---
|
||||||
|
"Fields retrieval with failing on error":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ name, rtf_strict_error ]
|
||||||
|
|
||||||
|
---
|
||||||
|
"Sorting with ignoring error":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ name ]
|
||||||
|
sort: rtf
|
||||||
|
- match: { hits.total.value: 2 }
|
||||||
|
- match: { hits.hits.0.fields.name: [ foo ] }
|
||||||
|
- match: { hits.hits.1.fields.name: [ "" ] }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Sorting with with failing on error":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ name ]
|
||||||
|
sort: rtf_strict_error
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query search time rtf with on_script_error continue":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
match:
|
||||||
|
rtf_search: 3
|
||||||
|
fields: [ name, rtf_search ]
|
||||||
|
runtime_mappings:
|
||||||
|
rtf_search:
|
||||||
|
type: long
|
||||||
|
script: |
|
||||||
|
if(doc['name'].value.equals("")) throw new Exception("empty");
|
||||||
|
emit(doc['name'].value.length());
|
||||||
|
on_script_error: continue
|
||||||
|
|
||||||
|
- match: { hits.total.value: 1 }
|
||||||
|
- match: { hits.hits.0.fields.name: [ foo ] }
|
||||||
|
- match: { hits.hits.0.fields.rtf_search: [ 3 ] }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query search time rtf with on_script_error fail":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
match:
|
||||||
|
rtf_search: 3
|
||||||
|
fields: [ name, rtf_search ]
|
||||||
|
runtime_mappings:
|
||||||
|
rtf_search:
|
||||||
|
type: long
|
||||||
|
script: |
|
||||||
|
if(doc['name'].value.equals("")) throw new Exception("empty");
|
||||||
|
emit(doc['name'].value.length());
|
||||||
|
on_script_error: fail
|
|
@ -0,0 +1,176 @@
|
||||||
|
---
|
||||||
|
setup:
|
||||||
|
- do:
|
||||||
|
indices.create:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
settings:
|
||||||
|
number_of_shards: 1
|
||||||
|
number_of_replicas: 0
|
||||||
|
mappings:
|
||||||
|
runtime:
|
||||||
|
rtf:
|
||||||
|
type: double
|
||||||
|
script: |
|
||||||
|
if(doc['name'].value.equals("")) throw new Exception("empty");
|
||||||
|
emit(doc['name'].value.length());
|
||||||
|
on_script_error: continue
|
||||||
|
rtf_strict_error:
|
||||||
|
type: double
|
||||||
|
script: |
|
||||||
|
if(doc['name'].value.equals("")) throw new Exception("empty");
|
||||||
|
emit(doc['name'].value.length());
|
||||||
|
on_script_error: fail
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: keyword
|
||||||
|
|
||||||
|
- do:
|
||||||
|
bulk:
|
||||||
|
index: testindex
|
||||||
|
refresh: true
|
||||||
|
body: |
|
||||||
|
{"index":{}}
|
||||||
|
{"name": "foo"}
|
||||||
|
{"index":{}}
|
||||||
|
{"name": ""}
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query rtf with on_script_error continue":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
match:
|
||||||
|
rtf: 3
|
||||||
|
fields: [ name, rtf ]
|
||||||
|
- match: { hits.total.value: 1 }
|
||||||
|
- match: { hits.hits.0.fields.name: [ foo ] }
|
||||||
|
- match: { hits.hits.0.fields.rtf: [ 3.0 ] }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query rtf with on_script_error fail":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
match:
|
||||||
|
rtf_strict_error: 3
|
||||||
|
fields: [ name, rtf_strict_error ]
|
||||||
|
|
||||||
|
---
|
||||||
|
"Aggregate on rtf with on_script_error continue":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
aggs:
|
||||||
|
firstchar:
|
||||||
|
terms:
|
||||||
|
field: rtf
|
||||||
|
- length: { aggregations.firstchar.buckets: 1 }
|
||||||
|
- match: { aggregations.firstchar.buckets.0.key: 3.0 }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Aggregate on rtf with on_script_error fail":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
aggs:
|
||||||
|
firstchar:
|
||||||
|
terms:
|
||||||
|
field: rtf_strict_error
|
||||||
|
|
||||||
|
---
|
||||||
|
"Fields retrieval with ignoring error":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ name, rtf ]
|
||||||
|
- match: { hits.total.value: 2 }
|
||||||
|
- match: { hits.hits.0.fields.name: [ foo ] }
|
||||||
|
- match: { hits.hits.0.fields.rtf: [ 3.0 ] }
|
||||||
|
- match: { hits.hits.1.fields.name: [ "" ] }
|
||||||
|
- is_false: hits.hits.1.fields.rtf
|
||||||
|
|
||||||
|
---
|
||||||
|
"Fields retrieval with failing on error":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ name, rtf_strict_error ]
|
||||||
|
|
||||||
|
---
|
||||||
|
"Sorting with ignoring error":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ name ]
|
||||||
|
sort: rtf
|
||||||
|
- match: { hits.total.value: 2 }
|
||||||
|
- match: { hits.hits.0.fields.name: [ foo ] }
|
||||||
|
- match: { hits.hits.1.fields.name: [ "" ] }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Sorting with with failing on error":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ name ]
|
||||||
|
sort: rtf_strict_error
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query search time rtf with on_script_error continue":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
match:
|
||||||
|
rtf_search: 3
|
||||||
|
fields: [ name, rtf_search ]
|
||||||
|
runtime_mappings:
|
||||||
|
rtf_search:
|
||||||
|
type: double
|
||||||
|
script: |
|
||||||
|
if(doc['name'].value.equals("")) throw new Exception("empty");
|
||||||
|
emit(doc['name'].value.length());
|
||||||
|
on_script_error: continue
|
||||||
|
|
||||||
|
- match: { hits.total.value: 1 }
|
||||||
|
- match: { hits.hits.0.fields.name: [ foo ] }
|
||||||
|
- match: { hits.hits.0.fields.rtf_search: [ 3.0 ] }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query search time rtf with on_script_error fail":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
match:
|
||||||
|
rtf_search: 3
|
||||||
|
fields: [ name, rtf_search ]
|
||||||
|
runtime_mappings:
|
||||||
|
rtf_search:
|
||||||
|
type: double
|
||||||
|
script: |
|
||||||
|
if(doc['name'].value.equals("")) throw new Exception("empty");
|
||||||
|
emit(doc['name'].value.length());
|
||||||
|
on_script_error: fail
|
|
@ -0,0 +1,184 @@
|
||||||
|
---
|
||||||
|
setup:
|
||||||
|
- do:
|
||||||
|
indices.create:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
settings:
|
||||||
|
number_of_shards: 1
|
||||||
|
number_of_replicas: 0
|
||||||
|
mappings:
|
||||||
|
runtime:
|
||||||
|
rtf:
|
||||||
|
type: date
|
||||||
|
format: yyyy-MM-dd
|
||||||
|
script: |
|
||||||
|
if(doc['millis_since_epoch'].value < 0) throw new Exception("date before 1970");
|
||||||
|
emit(doc['millis_since_epoch'].value);
|
||||||
|
on_script_error: continue
|
||||||
|
rtf_strict_error:
|
||||||
|
type: date
|
||||||
|
format: yyyy-MM-dd
|
||||||
|
script: |
|
||||||
|
if(doc['millis_since_epoch'].value < 0) throw new Exception("date before 1970");
|
||||||
|
emit(doc['millis_since_epoch'].value);
|
||||||
|
on_script_error: fail
|
||||||
|
properties:
|
||||||
|
millis_since_epoch:
|
||||||
|
type: long
|
||||||
|
|
||||||
|
- do:
|
||||||
|
bulk:
|
||||||
|
index: testindex
|
||||||
|
refresh: true
|
||||||
|
body: |
|
||||||
|
{"index":{}}
|
||||||
|
{"millis_since_epoch": 1671033474411}
|
||||||
|
{"index":{}}
|
||||||
|
{"millis_since_epoch": -1}
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query rtf with on_script_error continue":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
range:
|
||||||
|
rtf:
|
||||||
|
gte: "2022-12-14"
|
||||||
|
fields: [ millis_since_epoch, rtf ]
|
||||||
|
- match: { hits.total.value: 1 }
|
||||||
|
- match: { hits.hits.0.fields.millis_since_epoch: [ 1671033474411 ] }
|
||||||
|
- match: { hits.hits.0.fields.rtf: [ "2022-12-14" ] }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query rtf with on_script_error fail":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
range:
|
||||||
|
rtf_strict_error:
|
||||||
|
gte: "2022-12-14"
|
||||||
|
fields: [ millis_since_epoch, rtf_strict_error ]
|
||||||
|
|
||||||
|
---
|
||||||
|
"Aggregate on rtf with on_script_error continue":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
aggs:
|
||||||
|
firstchar:
|
||||||
|
terms:
|
||||||
|
field: rtf
|
||||||
|
- length: { aggregations.firstchar.buckets: 1 }
|
||||||
|
- match: { aggregations.firstchar.buckets.0.key_as_string: "2022-12-14" }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Aggregate on rtf with on_script_error fail":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
aggs:
|
||||||
|
firstchar:
|
||||||
|
terms:
|
||||||
|
field: rtf_strict_error
|
||||||
|
|
||||||
|
---
|
||||||
|
"Fields retrieval with ignoring error":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ millis_since_epoch, rtf ]
|
||||||
|
- match: { hits.total.value: 2 }
|
||||||
|
- match: { hits.hits.0.fields.millis_since_epoch: [ 1671033474411 ] }
|
||||||
|
- match: { hits.hits.0.fields.rtf: [ "2022-12-14" ] }
|
||||||
|
- match: { hits.hits.1.fields.millis_since_epoch: [ -1 ] }
|
||||||
|
- is_false: hits.hits.1.fields.rtf
|
||||||
|
|
||||||
|
---
|
||||||
|
"Fields retrieval with failing on error":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ millis_since_epoch, rtf_strict_error ]
|
||||||
|
|
||||||
|
---
|
||||||
|
"Sorting with ignoring error":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ millis_since_epoch ]
|
||||||
|
sort: rtf
|
||||||
|
- match: { hits.total.value: 2 }
|
||||||
|
- match: { hits.hits.0.fields.millis_since_epoch: [ 1671033474411 ] }
|
||||||
|
- match: { hits.hits.1.fields.millis_since_epoch: [ -1 ] }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Sorting with with failing on error":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ millis_since_epoch ]
|
||||||
|
sort: rtf_strict_error
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query search time rtf with on_script_error continue":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
range:
|
||||||
|
rtf_search:
|
||||||
|
gte: "2022-12-14"
|
||||||
|
fields: [ millis_since_epoch, rtf_search ]
|
||||||
|
runtime_mappings:
|
||||||
|
rtf_search:
|
||||||
|
type: date
|
||||||
|
format: yyyy-MM-dd
|
||||||
|
script: |
|
||||||
|
if(doc['millis_since_epoch'].value < 0) throw new Exception("date before 1970");
|
||||||
|
emit(doc['millis_since_epoch'].value);
|
||||||
|
on_script_error: continue
|
||||||
|
|
||||||
|
- match: { hits.total.value: 1 }
|
||||||
|
- match: { hits.hits.0.fields.millis_since_epoch: [ 1671033474411 ] }
|
||||||
|
- match: { hits.hits.0.fields.rtf_search: [ "2022-12-14" ] }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query search time rtf with on_script_error fail":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
range:
|
||||||
|
rtf_search:
|
||||||
|
gte: "2022-12-14"
|
||||||
|
fields: [ millis_since_epoch, rtf_search ]
|
||||||
|
runtime_mappings:
|
||||||
|
rtf_search:
|
||||||
|
type: date
|
||||||
|
format: yyyy-MM-dd
|
||||||
|
script: |
|
||||||
|
if(doc['millis_since_epoch'].value < 0) throw new Exception("date before 1970");
|
||||||
|
emit(doc['millis_since_epoch'].value);
|
||||||
|
on_script_error: fail
|
|
@ -0,0 +1,177 @@
|
||||||
|
---
|
||||||
|
setup:
|
||||||
|
- do:
|
||||||
|
indices.create:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
settings:
|
||||||
|
number_of_shards: 1
|
||||||
|
number_of_replicas: 0
|
||||||
|
mappings:
|
||||||
|
runtime:
|
||||||
|
rtf:
|
||||||
|
type: ip
|
||||||
|
script: |
|
||||||
|
if(doc['ip_string'].value.length() <= 0) throw new Exception("empty");
|
||||||
|
emit(doc['ip_string'].value);
|
||||||
|
on_script_error: continue
|
||||||
|
rtf_strict_error:
|
||||||
|
type: ip
|
||||||
|
script: |
|
||||||
|
if(doc['ip_string'].value.length() <= 0) throw new Exception("empty");
|
||||||
|
emit(doc['ip_string'].value);
|
||||||
|
on_script_error: fail
|
||||||
|
properties:
|
||||||
|
ip_string:
|
||||||
|
type: keyword
|
||||||
|
|
||||||
|
- do:
|
||||||
|
bulk:
|
||||||
|
index: testindex
|
||||||
|
refresh: true
|
||||||
|
body: |
|
||||||
|
{"index":{}}
|
||||||
|
{"ip_string": "192.68.0.1"}
|
||||||
|
{"index":{}}
|
||||||
|
{"ip_string": ""}
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query rtf with on_script_error continue":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
term:
|
||||||
|
rtf:
|
||||||
|
192.68.0.1
|
||||||
|
fields: [ ip_string, rtf ]
|
||||||
|
- match: { hits.total.value: 1 }
|
||||||
|
- match: { hits.hits.0.fields.ip_string: [ "192.68.0.1" ] }
|
||||||
|
- match: { hits.hits.0.fields.rtf: [ 192.68.0.1 ] }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query rtf with on_script_error fail":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
term:
|
||||||
|
rtf_strict_error: 192.68.0.1
|
||||||
|
fields: [ ip_string, rtf_strict_error ]
|
||||||
|
|
||||||
|
---
|
||||||
|
"Aggregate on rtf with on_script_error continue":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
aggs:
|
||||||
|
rtf:
|
||||||
|
terms:
|
||||||
|
field: rtf
|
||||||
|
- length: { aggregations.rtf.buckets: 1 }
|
||||||
|
- match: { aggregations.rtf.buckets.0.key: 192.68.0.1 }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Aggregate on rtf with on_script_error fail":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
aggs:
|
||||||
|
rtf:
|
||||||
|
terms:
|
||||||
|
field: rtf_strict_error
|
||||||
|
|
||||||
|
---
|
||||||
|
"Fields retrieval with ignoring error":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ ip_string, rtf ]
|
||||||
|
- match: { hits.total.value: 2 }
|
||||||
|
- match: { hits.hits.0.fields.ip_string: [ "192.68.0.1" ] }
|
||||||
|
- match: { hits.hits.0.fields.rtf: [ "192.68.0.1" ] }
|
||||||
|
- match: { hits.hits.1.fields.ip_string: [ "" ] }
|
||||||
|
- is_false: hits.hits.1.fields.rtf
|
||||||
|
|
||||||
|
---
|
||||||
|
"Fields retrieval with failing on error":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ ip_string, rtf_strict_error ]
|
||||||
|
|
||||||
|
---
|
||||||
|
"Sorting with ignoring error":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ ip_string ]
|
||||||
|
sort: rtf
|
||||||
|
- match: { hits.total.value: 2 }
|
||||||
|
- match: { hits.hits.0.fields.ip_string: [ "192.68.0.1" ] }
|
||||||
|
- match: { hits.hits.1.fields.ip_string: [ "" ] }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Sorting with with failing on error":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ ip_string ]
|
||||||
|
sort: rtf_strict_error
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query search time rtf with on_script_error continue":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
match:
|
||||||
|
rtf_search: "192.68.0.1"
|
||||||
|
fields: [ ip_string, rtf_search ]
|
||||||
|
runtime_mappings:
|
||||||
|
rtf_search:
|
||||||
|
type: ip
|
||||||
|
script: |
|
||||||
|
if(doc['ip_string'].value.length() <= 0) throw new Exception("empty");
|
||||||
|
emit(doc['ip_string'].value);
|
||||||
|
on_script_error: continue
|
||||||
|
|
||||||
|
- match: { hits.total.value: 1 }
|
||||||
|
- match: { hits.hits.0.fields.ip_string: [ "192.68.0.1" ] }
|
||||||
|
- match: { hits.hits.0.fields.rtf_search: [ "192.68.0.1" ] }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query search time rtf with on_script_error fail":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
match:
|
||||||
|
rtf_search: "192.68.0.1"
|
||||||
|
fields: [ ip_string, rtf_search ]
|
||||||
|
runtime_mappings:
|
||||||
|
rtf_search:
|
||||||
|
type: ip
|
||||||
|
script: |
|
||||||
|
if(doc['ip_string'].value.length() <= 0) throw new Exception("empty");
|
||||||
|
emit(doc['ip_string'].value);
|
||||||
|
on_script_error: fail
|
|
@ -0,0 +1,184 @@
|
||||||
|
---
|
||||||
|
setup:
|
||||||
|
- do:
|
||||||
|
indices.create:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
settings:
|
||||||
|
number_of_shards: 1
|
||||||
|
number_of_replicas: 0
|
||||||
|
mappings:
|
||||||
|
runtime:
|
||||||
|
rtf:
|
||||||
|
type: boolean
|
||||||
|
script: |
|
||||||
|
if(doc['age'].value < 0) throw new Exception("invalid age");
|
||||||
|
emit(doc['age'].value >= 18);
|
||||||
|
on_script_error: continue
|
||||||
|
rtf_strict_error:
|
||||||
|
type: boolean
|
||||||
|
script: |
|
||||||
|
if(doc['age'].value <= 0) throw new Exception("invalid age");
|
||||||
|
emit(doc['age'].value >=18);
|
||||||
|
on_script_error: fail
|
||||||
|
properties:
|
||||||
|
age:
|
||||||
|
type: integer
|
||||||
|
|
||||||
|
- do:
|
||||||
|
bulk:
|
||||||
|
index: testindex
|
||||||
|
refresh: true
|
||||||
|
body: |
|
||||||
|
{"index":{}}
|
||||||
|
{"age": 14}
|
||||||
|
{"index":{}}
|
||||||
|
{"age": 20}
|
||||||
|
{"index":{}}
|
||||||
|
{"age": -1}
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query rtf with on_script_error continue":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
match:
|
||||||
|
rtf:
|
||||||
|
true
|
||||||
|
fields: [ age, rtf ]
|
||||||
|
- match: { hits.total.value: 1 }
|
||||||
|
- match: { hits.hits.0.fields.age: [ 20 ] }
|
||||||
|
- match: { hits.hits.0.fields.rtf: [ true ] }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query rtf with on_script_error fail":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
match:
|
||||||
|
rtf_strict_error: true
|
||||||
|
fields: [ age, rtf_strict_error ]
|
||||||
|
|
||||||
|
---
|
||||||
|
"Aggregate on rtf with on_script_error continue":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
aggs:
|
||||||
|
rtf:
|
||||||
|
terms:
|
||||||
|
field: rtf
|
||||||
|
order: { "_key": "asc" }
|
||||||
|
- length: { aggregations.rtf.buckets: 2 }
|
||||||
|
- match: { aggregations.rtf.buckets.0.key_as_string: "false" }
|
||||||
|
- match: { aggregations.rtf.buckets.1.key_as_string: "true" }
|
||||||
|
---
|
||||||
|
"Aggregate on rtf with on_script_error fail":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
aggs:
|
||||||
|
rtf:
|
||||||
|
terms:
|
||||||
|
field: rtf_strict_error
|
||||||
|
|
||||||
|
---
|
||||||
|
"Fields retrieval with ignoring error":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ age, rtf ]
|
||||||
|
sort: { "age": "desc" }
|
||||||
|
- match: { hits.total.value: 3 }
|
||||||
|
- match: { hits.hits.0.fields.age: [ 20 ] }
|
||||||
|
- match: { hits.hits.0.fields.rtf: [ true ] }
|
||||||
|
- match: { hits.hits.1.fields.age: [ 14 ] }
|
||||||
|
- match: { hits.hits.1.fields.rtf: [ false ] }
|
||||||
|
- match: { hits.hits.2.fields.age: [ -1 ] }
|
||||||
|
- is_false: hits.hits.2.fields.rtf
|
||||||
|
|
||||||
|
---
|
||||||
|
"Fields retrieval with failing on error":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ age, rtf_strict_error ]
|
||||||
|
|
||||||
|
---
|
||||||
|
"Sorting with ignoring error":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ age ]
|
||||||
|
sort: rtf
|
||||||
|
- match: { hits.total.value: 3 }
|
||||||
|
- match: { hits.hits.0.fields.age: [ 14 ] }
|
||||||
|
- match: { hits.hits.1.fields.age: [ 20 ] }
|
||||||
|
- match: { hits.hits.2.fields.age: [ -1 ] }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Sorting with with failing on error":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query: { match_all: { } }
|
||||||
|
fields: [ age ]
|
||||||
|
sort: rtf_strict_error
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query search time rtf with on_script_error continue":
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
match:
|
||||||
|
rtf_search: true
|
||||||
|
fields: [ age, rtf_search ]
|
||||||
|
runtime_mappings:
|
||||||
|
rtf_search:
|
||||||
|
type: boolean
|
||||||
|
script: |
|
||||||
|
if(doc['age'].value < 0) throw new Exception("invalid age");
|
||||||
|
emit(doc['age'].value >= 18);
|
||||||
|
on_script_error: continue
|
||||||
|
|
||||||
|
- match: { hits.total.value: 1 }
|
||||||
|
- match: { hits.hits.0.fields.age: [ 20 ] }
|
||||||
|
- match: { hits.hits.0.fields.rtf_search: [ true ] }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Query search time rtf with on_script_error fail":
|
||||||
|
- do:
|
||||||
|
catch: /type=script_exception, reason=runtime error/
|
||||||
|
search:
|
||||||
|
index: testindex
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
match:
|
||||||
|
rtf_search: true
|
||||||
|
fields: [ age, rtf_search ]
|
||||||
|
runtime_mappings:
|
||||||
|
rtf_search:
|
||||||
|
type: boolean
|
||||||
|
script: |
|
||||||
|
if(doc['age'].value < 0) throw new Exception("invalid age");
|
||||||
|
emit(doc['age'].value >= 18);
|
||||||
|
on_script_error: fail
|
|
@ -215,7 +215,7 @@ abstract class AbstractScriptFieldType<LeafFactory> extends MappedFieldType {
|
||||||
abstract static class Builder<Factory> extends RuntimeField.Builder {
|
abstract static class Builder<Factory> extends RuntimeField.Builder {
|
||||||
private final ScriptContext<Factory> scriptContext;
|
private final ScriptContext<Factory> scriptContext;
|
||||||
|
|
||||||
final FieldMapper.Parameter<Script> script = new FieldMapper.Parameter<>(
|
private final FieldMapper.Parameter<Script> script = new FieldMapper.Parameter<>(
|
||||||
"script",
|
"script",
|
||||||
true,
|
true,
|
||||||
() -> null,
|
() -> null,
|
||||||
|
@ -225,6 +225,8 @@ abstract class AbstractScriptFieldType<LeafFactory> extends MappedFieldType {
|
||||||
Objects::toString
|
Objects::toString
|
||||||
).setSerializerCheck((id, ic, v) -> ic);
|
).setSerializerCheck((id, ic, v) -> ic);
|
||||||
|
|
||||||
|
private final FieldMapper.Parameter<String> onScriptError = FieldMapper.Parameter.onScriptErrorParam(m -> m.onScriptError, script);
|
||||||
|
|
||||||
Builder(String name, ScriptContext<Factory> scriptContext) {
|
Builder(String name, ScriptContext<Factory> scriptContext) {
|
||||||
super(name);
|
super(name);
|
||||||
this.scriptContext = scriptContext;
|
this.scriptContext = scriptContext;
|
||||||
|
@ -247,7 +249,8 @@ abstract class AbstractScriptFieldType<LeafFactory> extends MappedFieldType {
|
||||||
protected final RuntimeField createChildRuntimeField(
|
protected final RuntimeField createChildRuntimeField(
|
||||||
MappingParserContext parserContext,
|
MappingParserContext parserContext,
|
||||||
String parent,
|
String parent,
|
||||||
Function<SearchLookup, CompositeFieldScript.LeafFactory> parentScriptFactory
|
Function<SearchLookup, CompositeFieldScript.LeafFactory> parentScriptFactory,
|
||||||
|
OnScriptError onScriptError
|
||||||
) {
|
) {
|
||||||
if (script.isConfigured()) {
|
if (script.isConfigured()) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
|
@ -257,7 +260,7 @@ abstract class AbstractScriptFieldType<LeafFactory> extends MappedFieldType {
|
||||||
String fullName = parent + "." + name;
|
String fullName = parent + "." + name;
|
||||||
return new LeafRuntimeField(
|
return new LeafRuntimeField(
|
||||||
name,
|
name,
|
||||||
createFieldType(fullName, getCompositeLeafFactory(parentScriptFactory), getScript(), meta()),
|
createFieldType(fullName, getCompositeLeafFactory(parentScriptFactory), getScript(), meta(), onScriptError),
|
||||||
getParameters()
|
getParameters()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -267,26 +270,41 @@ abstract class AbstractScriptFieldType<LeafFactory> extends MappedFieldType {
|
||||||
}
|
}
|
||||||
|
|
||||||
final RuntimeField createRuntimeField(Factory scriptFactory, Version indexVersion) {
|
final RuntimeField createRuntimeField(Factory scriptFactory, Version indexVersion) {
|
||||||
var fieldType = createFieldType(name, scriptFactory, getScript(), meta(), indexVersion);
|
var fieldType = createFieldType(
|
||||||
|
name,
|
||||||
|
scriptFactory,
|
||||||
|
getScript(),
|
||||||
|
meta(),
|
||||||
|
indexVersion,
|
||||||
|
OnScriptError.fromString(onScriptError.get())
|
||||||
|
);
|
||||||
return new LeafRuntimeField(name, fieldType, getParameters());
|
return new LeafRuntimeField(name, fieldType, getParameters());
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract AbstractScriptFieldType<?> createFieldType(String name, Factory factory, Script script, Map<String, String> meta);
|
abstract AbstractScriptFieldType<?> createFieldType(
|
||||||
|
String name,
|
||||||
|
Factory factory,
|
||||||
|
Script script,
|
||||||
|
Map<String, String> meta,
|
||||||
|
OnScriptError onScriptError
|
||||||
|
);
|
||||||
|
|
||||||
AbstractScriptFieldType<?> createFieldType(
|
AbstractScriptFieldType<?> createFieldType(
|
||||||
String name,
|
String name,
|
||||||
Factory factory,
|
Factory factory,
|
||||||
Script script,
|
Script script,
|
||||||
Map<String, String> meta,
|
Map<String, String> meta,
|
||||||
Version supportedVersion
|
Version supportedVersion,
|
||||||
|
OnScriptError onScriptError
|
||||||
) {
|
) {
|
||||||
return createFieldType(name, factory, script, meta);
|
return createFieldType(name, factory, script, meta, onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<FieldMapper.Parameter<?>> getParameters() {
|
protected List<FieldMapper.Parameter<?>> getParameters() {
|
||||||
List<FieldMapper.Parameter<?>> parameters = new ArrayList<>(super.getParameters());
|
List<FieldMapper.Parameter<?>> parameters = new ArrayList<>(super.getParameters());
|
||||||
parameters.add(script);
|
parameters.add(script);
|
||||||
|
parameters.add(onScriptError);
|
||||||
return Collections.unmodifiableList(parameters);
|
return Collections.unmodifiableList(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,5 +314,6 @@ abstract class AbstractScriptFieldType<LeafFactory> extends MappedFieldType {
|
||||||
}
|
}
|
||||||
return script.get();
|
return script.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,7 +139,7 @@ public class BooleanFieldMapper extends FieldMapper {
|
||||||
BooleanFieldScript.Factory scriptFactory = scriptCompiler.compile(script.get(), BooleanFieldScript.CONTEXT);
|
BooleanFieldScript.Factory scriptFactory = scriptCompiler.compile(script.get(), BooleanFieldScript.CONTEXT);
|
||||||
return scriptFactory == null
|
return scriptFactory == null
|
||||||
? null
|
? null
|
||||||
: (lookup, ctx, doc, consumer) -> scriptFactory.newFactory(name, script.get().getParams(), lookup)
|
: (lookup, ctx, doc, consumer) -> scriptFactory.newFactory(name, script.get().getParams(), lookup, OnScriptError.FAIL)
|
||||||
.newInstance(ctx)
|
.newInstance(ctx)
|
||||||
.runForDoc(doc, consumer);
|
.runForDoc(doc, consumer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,9 +46,10 @@ public final class BooleanScriptFieldType extends AbstractScriptFieldType<Boolea
|
||||||
String name,
|
String name,
|
||||||
BooleanFieldScript.Factory factory,
|
BooleanFieldScript.Factory factory,
|
||||||
Script script,
|
Script script,
|
||||||
Map<String, String> meta
|
Map<String, String> meta,
|
||||||
|
OnScriptError onScriptError
|
||||||
) {
|
) {
|
||||||
return new BooleanScriptFieldType(name, factory, script, meta);
|
return new BooleanScriptFieldType(name, factory, script, meta, onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -67,10 +68,16 @@ public final class BooleanScriptFieldType extends AbstractScriptFieldType<Boolea
|
||||||
return new Builder(name).createRuntimeField(BooleanFieldScript.PARSE_FROM_SOURCE);
|
return new Builder(name).createRuntimeField(BooleanFieldScript.PARSE_FROM_SOURCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
BooleanScriptFieldType(String name, BooleanFieldScript.Factory scriptFactory, Script script, Map<String, String> meta) {
|
BooleanScriptFieldType(
|
||||||
|
String name,
|
||||||
|
BooleanFieldScript.Factory scriptFactory,
|
||||||
|
Script script,
|
||||||
|
Map<String, String> meta,
|
||||||
|
OnScriptError onScriptError
|
||||||
|
) {
|
||||||
super(
|
super(
|
||||||
name,
|
name,
|
||||||
searchLookup -> scriptFactory.newFactory(name, script.getParams(), searchLookup),
|
searchLookup -> scriptFactory.newFactory(name, script.getParams(), searchLookup, onScriptError),
|
||||||
script,
|
script,
|
||||||
scriptFactory.isResultDeterministic(),
|
scriptFactory.isResultDeterministic(),
|
||||||
meta
|
meta
|
||||||
|
|
|
@ -47,6 +47,8 @@ public class CompositeRuntimeField implements RuntimeField {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
private final FieldMapper.Parameter<String> onScriptError = FieldMapper.Parameter.onScriptErrorParam(m -> m.onScriptError, script);
|
||||||
|
|
||||||
private final FieldMapper.Parameter<Map<String, Object>> fields = new FieldMapper.Parameter<Map<String, Object>>(
|
private final FieldMapper.Parameter<Map<String, Object>> fields = new FieldMapper.Parameter<Map<String, Object>>(
|
||||||
"fields",
|
"fields",
|
||||||
false,
|
false,
|
||||||
|
@ -66,6 +68,7 @@ public class CompositeRuntimeField implements RuntimeField {
|
||||||
List<FieldMapper.Parameter<?>> parameters = new ArrayList<>(super.getParameters());
|
List<FieldMapper.Parameter<?>> parameters = new ArrayList<>(super.getParameters());
|
||||||
parameters.add(script);
|
parameters.add(script);
|
||||||
parameters.add(fields);
|
parameters.add(fields);
|
||||||
|
parameters.add(onScriptError);
|
||||||
return Collections.unmodifiableList(parameters);
|
return Collections.unmodifiableList(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +76,8 @@ public class CompositeRuntimeField implements RuntimeField {
|
||||||
protected RuntimeField createChildRuntimeField(
|
protected RuntimeField createChildRuntimeField(
|
||||||
MappingParserContext parserContext,
|
MappingParserContext parserContext,
|
||||||
String parent,
|
String parent,
|
||||||
Function<SearchLookup, CompositeFieldScript.LeafFactory> parentScriptFactory
|
Function<SearchLookup, CompositeFieldScript.LeafFactory> parentScriptFactory,
|
||||||
|
OnScriptError onScriptError
|
||||||
) {
|
) {
|
||||||
throw new IllegalArgumentException("Composite field [" + name + "] cannot be a child of composite field [" + parent + "]");
|
throw new IllegalArgumentException("Composite field [" + name + "] cannot be a child of composite field [" + parent + "]");
|
||||||
}
|
}
|
||||||
|
@ -81,11 +85,15 @@ public class CompositeRuntimeField implements RuntimeField {
|
||||||
@Override
|
@Override
|
||||||
protected RuntimeField createRuntimeField(MappingParserContext parserContext) {
|
protected RuntimeField createRuntimeField(MappingParserContext parserContext) {
|
||||||
CompositeFieldScript.Factory factory = parserContext.scriptCompiler().compile(script.get(), CompositeFieldScript.CONTEXT);
|
CompositeFieldScript.Factory factory = parserContext.scriptCompiler().compile(script.get(), CompositeFieldScript.CONTEXT);
|
||||||
Function<RuntimeField.Builder, RuntimeField> builder = b -> b.createChildRuntimeField(
|
Function<RuntimeField.Builder, RuntimeField> builder = b -> {
|
||||||
|
OnScriptError onScriptError = OnScriptError.fromString(this.onScriptError.get());
|
||||||
|
return b.createChildRuntimeField(
|
||||||
parserContext,
|
parserContext,
|
||||||
name,
|
name,
|
||||||
lookup -> factory.newFactory(name, script.get().getParams(), lookup)
|
lookup -> factory.newFactory(name, script.get().getParams(), lookup, onScriptError),
|
||||||
|
onScriptError
|
||||||
);
|
);
|
||||||
|
};
|
||||||
Map<String, RuntimeField> runtimeFields = RuntimeField.parseRuntimeFields(
|
Map<String, RuntimeField> runtimeFields = RuntimeField.parseRuntimeFields(
|
||||||
new HashMap<>(fields.getValue()),
|
new HashMap<>(fields.getValue()),
|
||||||
parserContext,
|
parserContext,
|
||||||
|
|
|
@ -303,9 +303,13 @@ public final class DateFieldMapper extends FieldMapper {
|
||||||
DateFieldScript.Factory factory = scriptCompiler.compile(script.get(), DateFieldScript.CONTEXT);
|
DateFieldScript.Factory factory = scriptCompiler.compile(script.get(), DateFieldScript.CONTEXT);
|
||||||
return factory == null
|
return factory == null
|
||||||
? null
|
? null
|
||||||
: (lookup, ctx, doc, consumer) -> factory.newFactory(name, script.get().getParams(), lookup, buildFormatter())
|
: (lookup, ctx, doc, consumer) -> factory.newFactory(
|
||||||
.newInstance(ctx)
|
name,
|
||||||
.runForDoc(doc, consumer::accept);
|
script.get().getParams(),
|
||||||
|
lookup,
|
||||||
|
buildFormatter(),
|
||||||
|
OnScriptError.FAIL
|
||||||
|
).newInstance(ctx).runForDoc(doc, consumer::accept);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -87,23 +87,29 @@ public class DateScriptFieldType extends AbstractScriptFieldType<DateFieldScript
|
||||||
return Collections.unmodifiableList(parameters);
|
return Collections.unmodifiableList(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AbstractScriptFieldType<?> createFieldType(
|
||||||
|
String name,
|
||||||
|
DateFieldScript.Factory factory,
|
||||||
|
Script script,
|
||||||
|
Map<String, String> meta,
|
||||||
|
Version supportedVersion,
|
||||||
|
OnScriptError onScriptError
|
||||||
|
) {
|
||||||
|
String pattern = format.getValue() == null ? DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.pattern() : format.getValue();
|
||||||
|
Locale locale = this.locale.getValue() == null ? Locale.ROOT : this.locale.getValue();
|
||||||
|
DateFormatter dateTimeFormatter = DateFormatter.forPattern(pattern, supportedVersion).withLocale(locale);
|
||||||
|
return new DateScriptFieldType(name, factory, dateTimeFormatter, script, meta, onScriptError);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
AbstractScriptFieldType<?> createFieldType(
|
AbstractScriptFieldType<?> createFieldType(
|
||||||
String name,
|
String name,
|
||||||
DateFieldScript.Factory factory,
|
DateFieldScript.Factory factory,
|
||||||
Script script,
|
Script script,
|
||||||
Map<String, String> meta,
|
Map<String, String> meta,
|
||||||
Version supportedVersion
|
OnScriptError onScriptError
|
||||||
) {
|
) {
|
||||||
String pattern = format.getValue() == null ? DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.pattern() : format.getValue();
|
return createFieldType(name, factory, script, meta, Version.CURRENT, onScriptError);
|
||||||
Locale locale = this.locale.getValue() == null ? Locale.ROOT : this.locale.getValue();
|
|
||||||
DateFormatter dateTimeFormatter = DateFormatter.forPattern(pattern, supportedVersion).withLocale(locale);
|
|
||||||
return new DateScriptFieldType(name, factory, dateTimeFormatter, script, meta);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
AbstractScriptFieldType<?> createFieldType(String name, DateFieldScript.Factory factory, Script script, Map<String, String> meta) {
|
|
||||||
return createFieldType(name, factory, script, meta, Version.CURRENT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -131,11 +137,12 @@ public class DateScriptFieldType extends AbstractScriptFieldType<DateFieldScript
|
||||||
DateFieldScript.Factory scriptFactory,
|
DateFieldScript.Factory scriptFactory,
|
||||||
DateFormatter dateTimeFormatter,
|
DateFormatter dateTimeFormatter,
|
||||||
Script script,
|
Script script,
|
||||||
Map<String, String> meta
|
Map<String, String> meta,
|
||||||
|
OnScriptError onScriptError
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
name,
|
name,
|
||||||
searchLookup -> scriptFactory.newFactory(name, script.getParams(), searchLookup, dateTimeFormatter),
|
searchLookup -> scriptFactory.newFactory(name, script.getParams(), searchLookup, dateTimeFormatter, onScriptError),
|
||||||
script,
|
script,
|
||||||
scriptFactory.isResultDeterministic(),
|
scriptFactory.isResultDeterministic(),
|
||||||
meta
|
meta
|
||||||
|
|
|
@ -47,9 +47,10 @@ public final class DoubleScriptFieldType extends AbstractScriptFieldType<DoubleF
|
||||||
String name,
|
String name,
|
||||||
DoubleFieldScript.Factory factory,
|
DoubleFieldScript.Factory factory,
|
||||||
Script script,
|
Script script,
|
||||||
Map<String, String> meta
|
Map<String, String> meta,
|
||||||
|
OnScriptError onScriptError
|
||||||
) {
|
) {
|
||||||
return new DoubleScriptFieldType(name, factory, script, meta);
|
return new DoubleScriptFieldType(name, factory, script, meta, onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -67,10 +68,16 @@ public final class DoubleScriptFieldType extends AbstractScriptFieldType<DoubleF
|
||||||
return new Builder(name).createRuntimeField(DoubleFieldScript.PARSE_FROM_SOURCE);
|
return new Builder(name).createRuntimeField(DoubleFieldScript.PARSE_FROM_SOURCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
DoubleScriptFieldType(String name, DoubleFieldScript.Factory scriptFactory, Script script, Map<String, String> meta) {
|
DoubleScriptFieldType(
|
||||||
|
String name,
|
||||||
|
DoubleFieldScript.Factory scriptFactory,
|
||||||
|
Script script,
|
||||||
|
Map<String, String> meta,
|
||||||
|
OnScriptError onScriptError
|
||||||
|
) {
|
||||||
super(
|
super(
|
||||||
name,
|
name,
|
||||||
searchLookup -> scriptFactory.newFactory(name, script.getParams(), searchLookup),
|
searchLookup -> scriptFactory.newFactory(name, script.getParams(), searchLookup, onScriptError),
|
||||||
script,
|
script,
|
||||||
scriptFactory.isResultDeterministic(),
|
scriptFactory.isResultDeterministic(),
|
||||||
meta
|
meta
|
||||||
|
|
|
@ -143,7 +143,7 @@ public class GeoPointFieldMapper extends AbstractPointGeometryFieldMapper<GeoPoi
|
||||||
GeoPointFieldScript.Factory factory = scriptCompiler.compile(this.script.get(), GeoPointFieldScript.CONTEXT);
|
GeoPointFieldScript.Factory factory = scriptCompiler.compile(this.script.get(), GeoPointFieldScript.CONTEXT);
|
||||||
return factory == null
|
return factory == null
|
||||||
? null
|
? null
|
||||||
: (lookup, ctx, doc, consumer) -> factory.newFactory(name, script.get().getParams(), lookup)
|
: (lookup, ctx, doc, consumer) -> factory.newFactory(name, script.get().getParams(), lookup, OnScriptError.FAIL)
|
||||||
.newInstance(ctx)
|
.newInstance(ctx)
|
||||||
.runForDoc(doc, consumer);
|
.runForDoc(doc, consumer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,9 +50,10 @@ public final class GeoPointScriptFieldType extends AbstractScriptFieldType<GeoPo
|
||||||
String name,
|
String name,
|
||||||
GeoPointFieldScript.Factory factory,
|
GeoPointFieldScript.Factory factory,
|
||||||
Script script,
|
Script script,
|
||||||
Map<String, String> meta
|
Map<String, String> meta,
|
||||||
|
OnScriptError onScriptError
|
||||||
) {
|
) {
|
||||||
return new GeoPointScriptFieldType(name, factory, getScript(), meta());
|
return new GeoPointScriptFieldType(name, factory, getScript(), meta(), onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -66,10 +67,16 @@ public final class GeoPointScriptFieldType extends AbstractScriptFieldType<GeoPo
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
GeoPointScriptFieldType(String name, GeoPointFieldScript.Factory scriptFactory, Script script, Map<String, String> meta) {
|
GeoPointScriptFieldType(
|
||||||
|
String name,
|
||||||
|
GeoPointFieldScript.Factory scriptFactory,
|
||||||
|
Script script,
|
||||||
|
Map<String, String> meta,
|
||||||
|
OnScriptError onScriptError
|
||||||
|
) {
|
||||||
super(
|
super(
|
||||||
name,
|
name,
|
||||||
searchLookup -> scriptFactory.newFactory(name, script.getParams(), searchLookup),
|
searchLookup -> scriptFactory.newFactory(name, script.getParams(), searchLookup, onScriptError),
|
||||||
script,
|
script,
|
||||||
scriptFactory.isResultDeterministic(),
|
scriptFactory.isResultDeterministic(),
|
||||||
meta
|
meta
|
||||||
|
@ -154,7 +161,7 @@ public final class GeoPointScriptFieldType extends AbstractScriptFieldType<GeoPo
|
||||||
) {
|
) {
|
||||||
return ctx -> {
|
return ctx -> {
|
||||||
GeoPointFieldScript script = delegateLeafFactory.apply(ctx);
|
GeoPointFieldScript script = delegateLeafFactory.apply(ctx);
|
||||||
return new AbstractLongFieldScript(name, Map.of(), lookup, ctx) {
|
return new AbstractLongFieldScript(name, Map.of(), lookup, OnScriptError.FAIL, ctx) {
|
||||||
private int docId;
|
private int docId;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -145,7 +145,7 @@ public class IpFieldMapper extends FieldMapper {
|
||||||
IpFieldScript.Factory factory = scriptCompiler.compile(this.script.get(), IpFieldScript.CONTEXT);
|
IpFieldScript.Factory factory = scriptCompiler.compile(this.script.get(), IpFieldScript.CONTEXT);
|
||||||
return factory == null
|
return factory == null
|
||||||
? null
|
? null
|
||||||
: (lookup, ctx, doc, consumer) -> factory.newFactory(name, script.get().getParams(), lookup)
|
: (lookup, ctx, doc, consumer) -> factory.newFactory(name, script.get().getParams(), lookup, OnScriptError.FAIL)
|
||||||
.newInstance(ctx)
|
.newInstance(ctx)
|
||||||
.runForDoc(doc, consumer);
|
.runForDoc(doc, consumer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,8 +45,14 @@ public final class IpScriptFieldType extends AbstractScriptFieldType<IpFieldScri
|
||||||
|
|
||||||
public static final RuntimeField.Parser PARSER = new RuntimeField.Parser(name -> new Builder<>(name, IpFieldScript.CONTEXT) {
|
public static final RuntimeField.Parser PARSER = new RuntimeField.Parser(name -> new Builder<>(name, IpFieldScript.CONTEXT) {
|
||||||
@Override
|
@Override
|
||||||
AbstractScriptFieldType<?> createFieldType(String name, IpFieldScript.Factory factory, Script script, Map<String, String> meta) {
|
AbstractScriptFieldType<?> createFieldType(
|
||||||
return new IpScriptFieldType(name, factory, getScript(), meta());
|
String name,
|
||||||
|
IpFieldScript.Factory factory,
|
||||||
|
Script script,
|
||||||
|
Map<String, String> meta,
|
||||||
|
OnScriptError onScriptError
|
||||||
|
) {
|
||||||
|
return new IpScriptFieldType(name, factory, getScript(), meta(), onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -60,10 +66,16 @@ public final class IpScriptFieldType extends AbstractScriptFieldType<IpFieldScri
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
IpScriptFieldType(String name, IpFieldScript.Factory scriptFactory, Script script, Map<String, String> meta) {
|
IpScriptFieldType(
|
||||||
|
String name,
|
||||||
|
IpFieldScript.Factory scriptFactory,
|
||||||
|
Script script,
|
||||||
|
Map<String, String> meta,
|
||||||
|
OnScriptError onScriptError
|
||||||
|
) {
|
||||||
super(
|
super(
|
||||||
name,
|
name,
|
||||||
searchLookup -> scriptFactory.newFactory(name, script.getParams(), searchLookup),
|
searchLookup -> scriptFactory.newFactory(name, script.getParams(), searchLookup, onScriptError),
|
||||||
script,
|
script,
|
||||||
scriptFactory.isResultDeterministic(),
|
scriptFactory.isResultDeterministic(),
|
||||||
meta
|
meta
|
||||||
|
|
|
@ -245,7 +245,7 @@ public final class KeywordFieldMapper extends FieldMapper {
|
||||||
StringFieldScript.Factory scriptFactory = scriptCompiler.compile(script.get(), StringFieldScript.CONTEXT);
|
StringFieldScript.Factory scriptFactory = scriptCompiler.compile(script.get(), StringFieldScript.CONTEXT);
|
||||||
return scriptFactory == null
|
return scriptFactory == null
|
||||||
? null
|
? null
|
||||||
: (lookup, ctx, doc, consumer) -> scriptFactory.newFactory(name, script.get().getParams(), lookup)
|
: (lookup, ctx, doc, consumer) -> scriptFactory.newFactory(name, script.get().getParams(), lookup, OnScriptError.FAIL)
|
||||||
.newInstance(ctx)
|
.newInstance(ctx)
|
||||||
.runForDoc(doc, consumer);
|
.runForDoc(doc, consumer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,9 +54,10 @@ public final class KeywordScriptFieldType extends AbstractScriptFieldType<String
|
||||||
String name,
|
String name,
|
||||||
StringFieldScript.Factory factory,
|
StringFieldScript.Factory factory,
|
||||||
Script script,
|
Script script,
|
||||||
Map<String, String> meta
|
Map<String, String> meta,
|
||||||
|
OnScriptError onScriptError
|
||||||
) {
|
) {
|
||||||
return new KeywordScriptFieldType(name, factory, script, meta);
|
return new KeywordScriptFieldType(name, factory, script, meta, onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -74,10 +75,16 @@ public final class KeywordScriptFieldType extends AbstractScriptFieldType<String
|
||||||
return new Builder(name).createRuntimeField(StringFieldScript.PARSE_FROM_SOURCE);
|
return new Builder(name).createRuntimeField(StringFieldScript.PARSE_FROM_SOURCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeywordScriptFieldType(String name, StringFieldScript.Factory scriptFactory, Script script, Map<String, String> meta) {
|
public KeywordScriptFieldType(
|
||||||
|
String name,
|
||||||
|
StringFieldScript.Factory scriptFactory,
|
||||||
|
Script script,
|
||||||
|
Map<String, String> meta,
|
||||||
|
OnScriptError onScriptError
|
||||||
|
) {
|
||||||
super(
|
super(
|
||||||
name,
|
name,
|
||||||
searchLookup -> scriptFactory.newFactory(name, script.getParams(), searchLookup),
|
searchLookup -> scriptFactory.newFactory(name, script.getParams(), searchLookup, onScriptError),
|
||||||
script,
|
script,
|
||||||
scriptFactory.isResultDeterministic(),
|
scriptFactory.isResultDeterministic(),
|
||||||
meta
|
meta
|
||||||
|
|
|
@ -43,8 +43,14 @@ public final class LongScriptFieldType extends AbstractScriptFieldType<LongField
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
AbstractScriptFieldType<?> createFieldType(String name, LongFieldScript.Factory factory, Script script, Map<String, String> meta) {
|
AbstractScriptFieldType<?> createFieldType(
|
||||||
return new LongScriptFieldType(name, factory, script, meta);
|
String name,
|
||||||
|
LongFieldScript.Factory factory,
|
||||||
|
Script script,
|
||||||
|
Map<String, String> meta,
|
||||||
|
OnScriptError onScriptError
|
||||||
|
) {
|
||||||
|
return new LongScriptFieldType(name, factory, script, meta, onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -62,10 +68,16 @@ public final class LongScriptFieldType extends AbstractScriptFieldType<LongField
|
||||||
return new Builder(name).createRuntimeField(LongFieldScript.PARSE_FROM_SOURCE);
|
return new Builder(name).createRuntimeField(LongFieldScript.PARSE_FROM_SOURCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LongScriptFieldType(String name, LongFieldScript.Factory scriptFactory, Script script, Map<String, String> meta) {
|
public LongScriptFieldType(
|
||||||
|
String name,
|
||||||
|
LongFieldScript.Factory scriptFactory,
|
||||||
|
Script script,
|
||||||
|
Map<String, String> meta,
|
||||||
|
OnScriptError onScriptError
|
||||||
|
) {
|
||||||
super(
|
super(
|
||||||
name,
|
name,
|
||||||
searchLookup -> scriptFactory.newFactory(name, script.getParams(), searchLookup),
|
searchLookup -> scriptFactory.newFactory(name, script.getParams(), searchLookup, onScriptError),
|
||||||
script,
|
script,
|
||||||
scriptFactory.isResultDeterministic(),
|
scriptFactory.isResultDeterministic(),
|
||||||
meta
|
meta
|
||||||
|
|
|
@ -159,7 +159,8 @@ public final class LookupRuntimeFieldType extends MappedFieldType {
|
||||||
protected RuntimeField createChildRuntimeField(
|
protected RuntimeField createChildRuntimeField(
|
||||||
MappingParserContext parserContext,
|
MappingParserContext parserContext,
|
||||||
String parentName,
|
String parentName,
|
||||||
Function<SearchLookup, CompositeFieldScript.LeafFactory> parentScriptFactory
|
Function<SearchLookup, CompositeFieldScript.LeafFactory> parentScriptFactory,
|
||||||
|
OnScriptError onScriptError
|
||||||
) {
|
) {
|
||||||
return createRuntimeField(parserContext);
|
return createRuntimeField(parserContext);
|
||||||
}
|
}
|
||||||
|
|
|
@ -592,7 +592,7 @@ public class NumberFieldMapper extends FieldMapper {
|
||||||
@Override
|
@Override
|
||||||
public FieldValues<Number> compile(String fieldName, Script script, ScriptCompiler compiler) {
|
public FieldValues<Number> compile(String fieldName, Script script, ScriptCompiler compiler) {
|
||||||
DoubleFieldScript.Factory scriptFactory = compiler.compile(script, DoubleFieldScript.CONTEXT);
|
DoubleFieldScript.Factory scriptFactory = compiler.compile(script, DoubleFieldScript.CONTEXT);
|
||||||
return (lookup, ctx, doc, consumer) -> scriptFactory.newFactory(fieldName, script.getParams(), lookup)
|
return (lookup, ctx, doc, consumer) -> scriptFactory.newFactory(fieldName, script.getParams(), lookup, OnScriptError.FAIL)
|
||||||
.newInstance(ctx)
|
.newInstance(ctx)
|
||||||
.runForDoc(doc, consumer::accept);
|
.runForDoc(doc, consumer::accept);
|
||||||
}
|
}
|
||||||
|
@ -1055,7 +1055,7 @@ public class NumberFieldMapper extends FieldMapper {
|
||||||
@Override
|
@Override
|
||||||
public FieldValues<Number> compile(String fieldName, Script script, ScriptCompiler compiler) {
|
public FieldValues<Number> compile(String fieldName, Script script, ScriptCompiler compiler) {
|
||||||
final LongFieldScript.Factory scriptFactory = compiler.compile(script, LongFieldScript.CONTEXT);
|
final LongFieldScript.Factory scriptFactory = compiler.compile(script, LongFieldScript.CONTEXT);
|
||||||
return (lookup, ctx, doc, consumer) -> scriptFactory.newFactory(fieldName, script.getParams(), lookup)
|
return (lookup, ctx, doc, consumer) -> scriptFactory.newFactory(fieldName, script.getParams(), lookup, OnScriptError.FAIL)
|
||||||
.newInstance(ctx)
|
.newInstance(ctx)
|
||||||
.runForDoc(doc, consumer::accept);
|
.runForDoc(doc, consumer::accept);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.index.mapper;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the behaviour when a runtime field or an index-time script fails: either fail and raise the error,
|
||||||
|
* or continue and ignore the error.
|
||||||
|
*/
|
||||||
|
public enum OnScriptError {
|
||||||
|
FAIL,
|
||||||
|
CONTINUE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the on_script_error parameter from a string into its corresponding enum instance
|
||||||
|
*/
|
||||||
|
public static OnScriptError fromString(final String str) {
|
||||||
|
Objects.requireNonNull(str, "input string is null");
|
||||||
|
return switch (str.toLowerCase(Locale.ROOT)) {
|
||||||
|
case "fail" -> FAIL;
|
||||||
|
case "continue" -> CONTINUE;
|
||||||
|
default -> throw new IllegalArgumentException("Unknown onScriptError [" + str + "]");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -63,7 +63,8 @@ public interface RuntimeField extends ToXContentFragment {
|
||||||
protected abstract RuntimeField createChildRuntimeField(
|
protected abstract RuntimeField createChildRuntimeField(
|
||||||
MappingParserContext parserContext,
|
MappingParserContext parserContext,
|
||||||
String parentName,
|
String parentName,
|
||||||
Function<SearchLookup, CompositeFieldScript.LeafFactory> parentScriptFactory
|
Function<SearchLookup, CompositeFieldScript.LeafFactory> parentScriptFactory,
|
||||||
|
OnScriptError onScriptError
|
||||||
);
|
);
|
||||||
|
|
||||||
public final void parse(String name, MappingParserContext parserContext, Map<String, Object> fieldNode) {
|
public final void parse(String name, MappingParserContext parserContext, Map<String, Object> fieldNode) {
|
||||||
|
|
|
@ -10,6 +10,7 @@ package org.elasticsearch.script;
|
||||||
|
|
||||||
import org.apache.lucene.index.LeafReaderContext;
|
import org.apache.lucene.index.LeafReaderContext;
|
||||||
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
||||||
|
import org.elasticsearch.index.mapper.OnScriptError;
|
||||||
import org.elasticsearch.search.lookup.SearchLookup;
|
import org.elasticsearch.search.lookup.SearchLookup;
|
||||||
import org.elasticsearch.search.lookup.SourceLookup;
|
import org.elasticsearch.search.lookup.SourceLookup;
|
||||||
|
|
||||||
|
@ -69,10 +70,16 @@ public abstract class AbstractFieldScript extends DocBasedScript {
|
||||||
protected final String fieldName;
|
protected final String fieldName;
|
||||||
protected final SourceLookup sourceLookup;
|
protected final SourceLookup sourceLookup;
|
||||||
private final Map<String, Object> params;
|
private final Map<String, Object> params;
|
||||||
|
private final OnScriptError onScriptError;
|
||||||
|
|
||||||
public AbstractFieldScript(String fieldName, Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
|
public AbstractFieldScript(
|
||||||
|
String fieldName,
|
||||||
|
Map<String, Object> params,
|
||||||
|
SearchLookup searchLookup,
|
||||||
|
LeafReaderContext ctx,
|
||||||
|
OnScriptError onScriptError
|
||||||
|
) {
|
||||||
super(new DocValuesDocReader(searchLookup, ctx));
|
super(new DocValuesDocReader(searchLookup, ctx));
|
||||||
|
|
||||||
this.fieldName = fieldName;
|
this.fieldName = fieldName;
|
||||||
Map<String, Object> docAsMap = docAsMap();
|
Map<String, Object> docAsMap = docAsMap();
|
||||||
this.sourceLookup = (SourceLookup) docAsMap.get("_source");
|
this.sourceLookup = (SourceLookup) docAsMap.get("_source");
|
||||||
|
@ -80,6 +87,7 @@ public abstract class AbstractFieldScript extends DocBasedScript {
|
||||||
params.put("_source", sourceLookup);
|
params.put("_source", sourceLookup);
|
||||||
params.put("_fields", docAsMap.get("_fields"));
|
params.put("_fields", docAsMap.get("_fields"));
|
||||||
this.params = new DynamicMap(params, PARAMS_FUNCTIONS);
|
this.params = new DynamicMap(params, PARAMS_FUNCTIONS);
|
||||||
|
this.onScriptError = onScriptError;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -141,7 +149,15 @@ public abstract class AbstractFieldScript extends DocBasedScript {
|
||||||
public final void runForDoc(int docId) {
|
public final void runForDoc(int docId) {
|
||||||
prepareExecute();
|
prepareExecute();
|
||||||
setDocument(docId);
|
setDocument(docId);
|
||||||
|
try {
|
||||||
execute();
|
execute();
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (onScriptError == OnScriptError.CONTINUE) {
|
||||||
|
// ignore
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void execute();
|
public abstract void execute();
|
||||||
|
|
|
@ -10,6 +10,7 @@ package org.elasticsearch.script;
|
||||||
|
|
||||||
import org.apache.lucene.index.LeafReaderContext;
|
import org.apache.lucene.index.LeafReaderContext;
|
||||||
import org.apache.lucene.util.ArrayUtil;
|
import org.apache.lucene.util.ArrayUtil;
|
||||||
|
import org.elasticsearch.index.mapper.OnScriptError;
|
||||||
import org.elasticsearch.search.lookup.SearchLookup;
|
import org.elasticsearch.search.lookup.SearchLookup;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -22,8 +23,14 @@ public abstract class AbstractLongFieldScript extends AbstractFieldScript {
|
||||||
private long[] values = new long[1];
|
private long[] values = new long[1];
|
||||||
private int count;
|
private int count;
|
||||||
|
|
||||||
public AbstractLongFieldScript(String fieldName, Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
|
public AbstractLongFieldScript(
|
||||||
super(fieldName, params, searchLookup, ctx);
|
String fieldName,
|
||||||
|
Map<String, Object> params,
|
||||||
|
SearchLookup searchLookup,
|
||||||
|
OnScriptError onScriptError,
|
||||||
|
LeafReaderContext ctx
|
||||||
|
) {
|
||||||
|
super(fieldName, params, searchLookup, ctx, onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -10,6 +10,7 @@ package org.elasticsearch.script;
|
||||||
|
|
||||||
import org.apache.lucene.index.LeafReaderContext;
|
import org.apache.lucene.index.LeafReaderContext;
|
||||||
import org.elasticsearch.core.Booleans;
|
import org.elasticsearch.core.Booleans;
|
||||||
|
import org.elasticsearch.index.mapper.OnScriptError;
|
||||||
import org.elasticsearch.search.lookup.SearchLookup;
|
import org.elasticsearch.search.lookup.SearchLookup;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -22,8 +23,8 @@ public abstract class BooleanFieldScript extends AbstractFieldScript {
|
||||||
|
|
||||||
public static final Factory PARSE_FROM_SOURCE = new Factory() {
|
public static final Factory PARSE_FROM_SOURCE = new Factory() {
|
||||||
@Override
|
@Override
|
||||||
public LeafFactory newFactory(String field, Map<String, Object> params, SearchLookup lookup) {
|
public LeafFactory newFactory(String field, Map<String, Object> params, SearchLookup lookup, OnScriptError onScriptError) {
|
||||||
return ctx -> new BooleanFieldScript(field, params, lookup, ctx) {
|
return ctx -> new BooleanFieldScript(field, params, lookup, OnScriptError.FAIL, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emitFromSource();
|
emitFromSource();
|
||||||
|
@ -38,11 +39,11 @@ public abstract class BooleanFieldScript extends AbstractFieldScript {
|
||||||
};
|
};
|
||||||
|
|
||||||
public static Factory leafAdapter(Function<SearchLookup, CompositeFieldScript.LeafFactory> parentFactory) {
|
public static Factory leafAdapter(Function<SearchLookup, CompositeFieldScript.LeafFactory> parentFactory) {
|
||||||
return (leafFieldName, params, searchLookup) -> {
|
return (leafFieldName, params, searchLookup, onScriptError) -> {
|
||||||
CompositeFieldScript.LeafFactory parentLeafFactory = parentFactory.apply(searchLookup);
|
CompositeFieldScript.LeafFactory parentLeafFactory = parentFactory.apply(searchLookup);
|
||||||
return (LeafFactory) ctx -> {
|
return (LeafFactory) ctx -> {
|
||||||
CompositeFieldScript compositeFieldScript = parentLeafFactory.newInstance(ctx);
|
CompositeFieldScript compositeFieldScript = parentLeafFactory.newInstance(ctx);
|
||||||
return new BooleanFieldScript(leafFieldName, params, searchLookup, ctx) {
|
return new BooleanFieldScript(leafFieldName, params, searchLookup, onScriptError, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void setDocument(int docId) {
|
public void setDocument(int docId) {
|
||||||
compositeFieldScript.setDocument(docId);
|
compositeFieldScript.setDocument(docId);
|
||||||
|
@ -61,7 +62,7 @@ public abstract class BooleanFieldScript extends AbstractFieldScript {
|
||||||
public static final String[] PARAMETERS = {};
|
public static final String[] PARAMETERS = {};
|
||||||
|
|
||||||
public interface Factory extends ScriptFactory {
|
public interface Factory extends ScriptFactory {
|
||||||
LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup);
|
LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup, OnScriptError onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface LeafFactory {
|
public interface LeafFactory {
|
||||||
|
@ -71,8 +72,14 @@ public abstract class BooleanFieldScript extends AbstractFieldScript {
|
||||||
private int trues;
|
private int trues;
|
||||||
private int falses;
|
private int falses;
|
||||||
|
|
||||||
public BooleanFieldScript(String fieldName, Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
|
public BooleanFieldScript(
|
||||||
super(fieldName, params, searchLookup, ctx);
|
String fieldName,
|
||||||
|
Map<String, Object> params,
|
||||||
|
SearchLookup searchLookup,
|
||||||
|
OnScriptError onScriptError,
|
||||||
|
LeafReaderContext ctx
|
||||||
|
) {
|
||||||
|
super(fieldName, params, searchLookup, ctx, onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
package org.elasticsearch.script;
|
package org.elasticsearch.script;
|
||||||
|
|
||||||
import org.apache.lucene.index.LeafReaderContext;
|
import org.apache.lucene.index.LeafReaderContext;
|
||||||
|
import org.elasticsearch.index.mapper.OnScriptError;
|
||||||
import org.elasticsearch.search.lookup.SearchLookup;
|
import org.elasticsearch.search.lookup.SearchLookup;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -27,7 +28,12 @@ public abstract class CompositeFieldScript extends AbstractFieldScript {
|
||||||
public static final String[] PARAMETERS = {};
|
public static final String[] PARAMETERS = {};
|
||||||
|
|
||||||
public interface Factory extends ScriptFactory {
|
public interface Factory extends ScriptFactory {
|
||||||
CompositeFieldScript.LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup);
|
CompositeFieldScript.LeafFactory newFactory(
|
||||||
|
String fieldName,
|
||||||
|
Map<String, Object> params,
|
||||||
|
SearchLookup searchLookup,
|
||||||
|
OnScriptError onScriptError
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface LeafFactory {
|
public interface LeafFactory {
|
||||||
|
@ -36,8 +42,14 @@ public abstract class CompositeFieldScript extends AbstractFieldScript {
|
||||||
|
|
||||||
private final Map<String, List<Object>> fieldValues = new HashMap<>();
|
private final Map<String, List<Object>> fieldValues = new HashMap<>();
|
||||||
|
|
||||||
public CompositeFieldScript(String fieldName, Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
|
public CompositeFieldScript(
|
||||||
super(fieldName, params, searchLookup, ctx);
|
String fieldName,
|
||||||
|
Map<String, Object> params,
|
||||||
|
SearchLookup searchLookup,
|
||||||
|
OnScriptError onScriptError,
|
||||||
|
LeafReaderContext ctx
|
||||||
|
) {
|
||||||
|
super(fieldName, params, searchLookup, ctx, onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -10,6 +10,7 @@ package org.elasticsearch.script;
|
||||||
|
|
||||||
import org.apache.lucene.index.LeafReaderContext;
|
import org.apache.lucene.index.LeafReaderContext;
|
||||||
import org.elasticsearch.common.time.DateFormatter;
|
import org.elasticsearch.common.time.DateFormatter;
|
||||||
|
import org.elasticsearch.index.mapper.OnScriptError;
|
||||||
import org.elasticsearch.search.lookup.SearchLookup;
|
import org.elasticsearch.search.lookup.SearchLookup;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -21,8 +22,14 @@ public abstract class DateFieldScript extends AbstractLongFieldScript {
|
||||||
|
|
||||||
public static final Factory PARSE_FROM_SOURCE = new Factory() {
|
public static final Factory PARSE_FROM_SOURCE = new Factory() {
|
||||||
@Override
|
@Override
|
||||||
public LeafFactory newFactory(String field, Map<String, Object> params, SearchLookup lookup, DateFormatter formatter) {
|
public LeafFactory newFactory(
|
||||||
return ctx -> new DateFieldScript(field, params, lookup, formatter, ctx) {
|
String field,
|
||||||
|
Map<String, Object> params,
|
||||||
|
SearchLookup lookup,
|
||||||
|
DateFormatter formatter,
|
||||||
|
OnScriptError onScriptError
|
||||||
|
) {
|
||||||
|
return ctx -> new DateFieldScript(field, params, lookup, formatter, OnScriptError.FAIL, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emitFromSource();
|
emitFromSource();
|
||||||
|
@ -37,11 +44,11 @@ public abstract class DateFieldScript extends AbstractLongFieldScript {
|
||||||
};
|
};
|
||||||
|
|
||||||
public static Factory leafAdapter(Function<SearchLookup, CompositeFieldScript.LeafFactory> parentFactory) {
|
public static Factory leafAdapter(Function<SearchLookup, CompositeFieldScript.LeafFactory> parentFactory) {
|
||||||
return (leafFieldName, params, searchLookup, formatter) -> {
|
return (leafFieldName, params, searchLookup, formatter, onScriptError) -> {
|
||||||
CompositeFieldScript.LeafFactory parentLeafFactory = parentFactory.apply(searchLookup);
|
CompositeFieldScript.LeafFactory parentLeafFactory = parentFactory.apply(searchLookup);
|
||||||
return (LeafFactory) ctx -> {
|
return (LeafFactory) ctx -> {
|
||||||
CompositeFieldScript compositeFieldScript = parentLeafFactory.newInstance(ctx);
|
CompositeFieldScript compositeFieldScript = parentLeafFactory.newInstance(ctx);
|
||||||
return new DateFieldScript(leafFieldName, params, searchLookup, formatter, ctx) {
|
return new DateFieldScript(leafFieldName, params, searchLookup, formatter, onScriptError, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void setDocument(int docId) {
|
public void setDocument(int docId) {
|
||||||
compositeFieldScript.setDocument(docId);
|
compositeFieldScript.setDocument(docId);
|
||||||
|
@ -60,7 +67,13 @@ public abstract class DateFieldScript extends AbstractLongFieldScript {
|
||||||
public static final String[] PARAMETERS = {};
|
public static final String[] PARAMETERS = {};
|
||||||
|
|
||||||
public interface Factory extends ScriptFactory {
|
public interface Factory extends ScriptFactory {
|
||||||
LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup, DateFormatter formatter);
|
LeafFactory newFactory(
|
||||||
|
String fieldName,
|
||||||
|
Map<String, Object> params,
|
||||||
|
SearchLookup searchLookup,
|
||||||
|
DateFormatter formatter,
|
||||||
|
OnScriptError onScriptError
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface LeafFactory {
|
public interface LeafFactory {
|
||||||
|
@ -74,9 +87,10 @@ public abstract class DateFieldScript extends AbstractLongFieldScript {
|
||||||
Map<String, Object> params,
|
Map<String, Object> params,
|
||||||
SearchLookup searchLookup,
|
SearchLookup searchLookup,
|
||||||
DateFormatter formatter,
|
DateFormatter formatter,
|
||||||
|
OnScriptError onScriptError,
|
||||||
LeafReaderContext ctx
|
LeafReaderContext ctx
|
||||||
) {
|
) {
|
||||||
super(fieldName, params, searchLookup, ctx);
|
super(fieldName, params, searchLookup, onScriptError, ctx);
|
||||||
this.formatter = formatter;
|
this.formatter = formatter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ package org.elasticsearch.script;
|
||||||
|
|
||||||
import org.apache.lucene.index.LeafReaderContext;
|
import org.apache.lucene.index.LeafReaderContext;
|
||||||
import org.apache.lucene.util.ArrayUtil;
|
import org.apache.lucene.util.ArrayUtil;
|
||||||
|
import org.elasticsearch.index.mapper.OnScriptError;
|
||||||
import org.elasticsearch.search.lookup.SearchLookup;
|
import org.elasticsearch.search.lookup.SearchLookup;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -21,8 +22,8 @@ public abstract class DoubleFieldScript extends AbstractFieldScript {
|
||||||
|
|
||||||
public static final Factory PARSE_FROM_SOURCE = new Factory() {
|
public static final Factory PARSE_FROM_SOURCE = new Factory() {
|
||||||
@Override
|
@Override
|
||||||
public LeafFactory newFactory(String field, Map<String, Object> params, SearchLookup lookup) {
|
public LeafFactory newFactory(String field, Map<String, Object> params, SearchLookup lookup, OnScriptError onScriptError) {
|
||||||
return ctx -> new DoubleFieldScript(field, params, lookup, ctx) {
|
return ctx -> new DoubleFieldScript(field, params, lookup, OnScriptError.FAIL, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emitFromSource();
|
emitFromSource();
|
||||||
|
@ -37,11 +38,11 @@ public abstract class DoubleFieldScript extends AbstractFieldScript {
|
||||||
};
|
};
|
||||||
|
|
||||||
public static Factory leafAdapter(Function<SearchLookup, CompositeFieldScript.LeafFactory> parentFactory) {
|
public static Factory leafAdapter(Function<SearchLookup, CompositeFieldScript.LeafFactory> parentFactory) {
|
||||||
return (leafFieldName, params, searchLookup) -> {
|
return (leafFieldName, params, searchLookup, onScriptError) -> {
|
||||||
CompositeFieldScript.LeafFactory parentLeafFactory = parentFactory.apply(searchLookup);
|
CompositeFieldScript.LeafFactory parentLeafFactory = parentFactory.apply(searchLookup);
|
||||||
return (LeafFactory) ctx -> {
|
return (LeafFactory) ctx -> {
|
||||||
CompositeFieldScript compositeFieldScript = parentLeafFactory.newInstance(ctx);
|
CompositeFieldScript compositeFieldScript = parentLeafFactory.newInstance(ctx);
|
||||||
return new DoubleFieldScript(leafFieldName, params, searchLookup, ctx) {
|
return new DoubleFieldScript(leafFieldName, params, searchLookup, onScriptError, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void setDocument(int docId) {
|
public void setDocument(int docId) {
|
||||||
compositeFieldScript.setDocument(docId);
|
compositeFieldScript.setDocument(docId);
|
||||||
|
@ -60,7 +61,7 @@ public abstract class DoubleFieldScript extends AbstractFieldScript {
|
||||||
public static final String[] PARAMETERS = {};
|
public static final String[] PARAMETERS = {};
|
||||||
|
|
||||||
public interface Factory extends ScriptFactory {
|
public interface Factory extends ScriptFactory {
|
||||||
LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup);
|
LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup, OnScriptError onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface LeafFactory {
|
public interface LeafFactory {
|
||||||
|
@ -70,8 +71,14 @@ public abstract class DoubleFieldScript extends AbstractFieldScript {
|
||||||
private double[] values = new double[1];
|
private double[] values = new double[1];
|
||||||
private int count;
|
private int count;
|
||||||
|
|
||||||
public DoubleFieldScript(String fieldName, Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
|
public DoubleFieldScript(
|
||||||
super(fieldName, params, searchLookup, ctx);
|
String fieldName,
|
||||||
|
Map<String, Object> params,
|
||||||
|
SearchLookup searchLookup,
|
||||||
|
OnScriptError onScriptError,
|
||||||
|
LeafReaderContext ctx
|
||||||
|
) {
|
||||||
|
super(fieldName, params, searchLookup, ctx, onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.apache.lucene.util.ArrayUtil;
|
||||||
import org.elasticsearch.common.geo.GeoPoint;
|
import org.elasticsearch.common.geo.GeoPoint;
|
||||||
import org.elasticsearch.common.geo.GeoUtils;
|
import org.elasticsearch.common.geo.GeoUtils;
|
||||||
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
||||||
|
import org.elasticsearch.index.mapper.OnScriptError;
|
||||||
import org.elasticsearch.search.lookup.SearchLookup;
|
import org.elasticsearch.search.lookup.SearchLookup;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -31,8 +32,8 @@ public abstract class GeoPointFieldScript extends AbstractFieldScript {
|
||||||
|
|
||||||
public static final Factory PARSE_FROM_SOURCE = new Factory() {
|
public static final Factory PARSE_FROM_SOURCE = new Factory() {
|
||||||
@Override
|
@Override
|
||||||
public LeafFactory newFactory(String field, Map<String, Object> params, SearchLookup lookup) {
|
public LeafFactory newFactory(String field, Map<String, Object> params, SearchLookup lookup, OnScriptError onScriptError) {
|
||||||
return ctx -> new GeoPointFieldScript(field, params, lookup, ctx) {
|
return ctx -> new GeoPointFieldScript(field, params, lookup, OnScriptError.FAIL, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emitFromSource();
|
emitFromSource();
|
||||||
|
@ -47,11 +48,11 @@ public abstract class GeoPointFieldScript extends AbstractFieldScript {
|
||||||
};
|
};
|
||||||
|
|
||||||
public static Factory leafAdapter(Function<SearchLookup, CompositeFieldScript.LeafFactory> parentFactory) {
|
public static Factory leafAdapter(Function<SearchLookup, CompositeFieldScript.LeafFactory> parentFactory) {
|
||||||
return (leafFieldName, params, searchLookup) -> {
|
return (leafFieldName, params, searchLookup, onScriptError) -> {
|
||||||
CompositeFieldScript.LeafFactory parentLeafFactory = parentFactory.apply(searchLookup);
|
CompositeFieldScript.LeafFactory parentLeafFactory = parentFactory.apply(searchLookup);
|
||||||
return (LeafFactory) ctx -> {
|
return (LeafFactory) ctx -> {
|
||||||
CompositeFieldScript compositeFieldScript = parentLeafFactory.newInstance(ctx);
|
CompositeFieldScript compositeFieldScript = parentLeafFactory.newInstance(ctx);
|
||||||
return new GeoPointFieldScript(leafFieldName, params, searchLookup, ctx) {
|
return new GeoPointFieldScript(leafFieldName, params, searchLookup, onScriptError, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void setDocument(int docId) {
|
public void setDocument(int docId) {
|
||||||
compositeFieldScript.setDocument(docId);
|
compositeFieldScript.setDocument(docId);
|
||||||
|
@ -70,7 +71,7 @@ public abstract class GeoPointFieldScript extends AbstractFieldScript {
|
||||||
public static final String[] PARAMETERS = {};
|
public static final String[] PARAMETERS = {};
|
||||||
|
|
||||||
public interface Factory extends ScriptFactory {
|
public interface Factory extends ScriptFactory {
|
||||||
LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup);
|
LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup, OnScriptError onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface LeafFactory {
|
public interface LeafFactory {
|
||||||
|
@ -81,8 +82,14 @@ public abstract class GeoPointFieldScript extends AbstractFieldScript {
|
||||||
private double[] lons = new double[1];
|
private double[] lons = new double[1];
|
||||||
private int count;
|
private int count;
|
||||||
|
|
||||||
public GeoPointFieldScript(String fieldName, Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
|
public GeoPointFieldScript(
|
||||||
super(fieldName, params, searchLookup, ctx);
|
String fieldName,
|
||||||
|
Map<String, Object> params,
|
||||||
|
SearchLookup searchLookup,
|
||||||
|
OnScriptError onScriptError,
|
||||||
|
LeafReaderContext ctx
|
||||||
|
) {
|
||||||
|
super(fieldName, params, searchLookup, ctx, onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.apache.lucene.util.ArrayUtil;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.elasticsearch.common.network.InetAddresses;
|
import org.elasticsearch.common.network.InetAddresses;
|
||||||
import org.elasticsearch.index.mapper.IpFieldMapper;
|
import org.elasticsearch.index.mapper.IpFieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.OnScriptError;
|
||||||
import org.elasticsearch.search.lookup.SearchLookup;
|
import org.elasticsearch.search.lookup.SearchLookup;
|
||||||
|
|
||||||
import java.net.Inet4Address;
|
import java.net.Inet4Address;
|
||||||
|
@ -42,8 +43,8 @@ public abstract class IpFieldScript extends AbstractFieldScript {
|
||||||
|
|
||||||
public static final Factory PARSE_FROM_SOURCE = new Factory() {
|
public static final Factory PARSE_FROM_SOURCE = new Factory() {
|
||||||
@Override
|
@Override
|
||||||
public LeafFactory newFactory(String field, Map<String, Object> params, SearchLookup lookup) {
|
public LeafFactory newFactory(String field, Map<String, Object> params, SearchLookup lookup, OnScriptError onScriptError) {
|
||||||
return ctx -> new IpFieldScript(field, params, lookup, ctx) {
|
return ctx -> new IpFieldScript(field, params, lookup, OnScriptError.FAIL, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emitFromSource();
|
emitFromSource();
|
||||||
|
@ -58,11 +59,11 @@ public abstract class IpFieldScript extends AbstractFieldScript {
|
||||||
};
|
};
|
||||||
|
|
||||||
public static Factory leafAdapter(Function<SearchLookup, CompositeFieldScript.LeafFactory> parentFactory) {
|
public static Factory leafAdapter(Function<SearchLookup, CompositeFieldScript.LeafFactory> parentFactory) {
|
||||||
return (leafFieldName, params, searchLookup) -> {
|
return (leafFieldName, params, searchLookup, onScriptError) -> {
|
||||||
CompositeFieldScript.LeafFactory parentLeafFactory = parentFactory.apply(searchLookup);
|
CompositeFieldScript.LeafFactory parentLeafFactory = parentFactory.apply(searchLookup);
|
||||||
return (LeafFactory) ctx -> {
|
return (LeafFactory) ctx -> {
|
||||||
CompositeFieldScript compositeFieldScript = parentLeafFactory.newInstance(ctx);
|
CompositeFieldScript compositeFieldScript = parentLeafFactory.newInstance(ctx);
|
||||||
return new IpFieldScript(leafFieldName, params, searchLookup, ctx) {
|
return new IpFieldScript(leafFieldName, params, searchLookup, onScriptError, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void setDocument(int docId) {
|
public void setDocument(int docId) {
|
||||||
compositeFieldScript.setDocument(docId);
|
compositeFieldScript.setDocument(docId);
|
||||||
|
@ -81,7 +82,7 @@ public abstract class IpFieldScript extends AbstractFieldScript {
|
||||||
public static final String[] PARAMETERS = {};
|
public static final String[] PARAMETERS = {};
|
||||||
|
|
||||||
public interface Factory extends ScriptFactory {
|
public interface Factory extends ScriptFactory {
|
||||||
LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup);
|
LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup, OnScriptError onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface LeafFactory {
|
public interface LeafFactory {
|
||||||
|
@ -91,8 +92,14 @@ public abstract class IpFieldScript extends AbstractFieldScript {
|
||||||
private BytesRef[] values = new BytesRef[1];
|
private BytesRef[] values = new BytesRef[1];
|
||||||
private int count;
|
private int count;
|
||||||
|
|
||||||
public IpFieldScript(String fieldName, Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
|
public IpFieldScript(
|
||||||
super(fieldName, params, searchLookup, ctx);
|
String fieldName,
|
||||||
|
Map<String, Object> params,
|
||||||
|
SearchLookup searchLookup,
|
||||||
|
OnScriptError onScriptError,
|
||||||
|
LeafReaderContext ctx
|
||||||
|
) {
|
||||||
|
super(fieldName, params, searchLookup, ctx, onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -10,6 +10,7 @@ package org.elasticsearch.script;
|
||||||
|
|
||||||
import org.apache.lucene.index.LeafReaderContext;
|
import org.apache.lucene.index.LeafReaderContext;
|
||||||
import org.elasticsearch.index.mapper.NumberFieldMapper;
|
import org.elasticsearch.index.mapper.NumberFieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.OnScriptError;
|
||||||
import org.elasticsearch.search.lookup.SearchLookup;
|
import org.elasticsearch.search.lookup.SearchLookup;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -20,8 +21,8 @@ public abstract class LongFieldScript extends AbstractLongFieldScript {
|
||||||
|
|
||||||
public static final Factory PARSE_FROM_SOURCE = new Factory() {
|
public static final Factory PARSE_FROM_SOURCE = new Factory() {
|
||||||
@Override
|
@Override
|
||||||
public LeafFactory newFactory(String field, Map<String, Object> params, SearchLookup lookup) {
|
public LeafFactory newFactory(String field, Map<String, Object> params, SearchLookup lookup, OnScriptError onScriptError) {
|
||||||
return ctx -> new LongFieldScript(field, params, lookup, ctx) {
|
return ctx -> new LongFieldScript(field, params, lookup, OnScriptError.FAIL, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emitFromSource();
|
emitFromSource();
|
||||||
|
@ -36,11 +37,11 @@ public abstract class LongFieldScript extends AbstractLongFieldScript {
|
||||||
};
|
};
|
||||||
|
|
||||||
public static Factory leafAdapter(Function<SearchLookup, CompositeFieldScript.LeafFactory> parentFactory) {
|
public static Factory leafAdapter(Function<SearchLookup, CompositeFieldScript.LeafFactory> parentFactory) {
|
||||||
return (leafFieldName, params, searchLookup) -> {
|
return (leafFieldName, params, searchLookup, onScriptError) -> {
|
||||||
CompositeFieldScript.LeafFactory parentLeafFactory = parentFactory.apply(searchLookup);
|
CompositeFieldScript.LeafFactory parentLeafFactory = parentFactory.apply(searchLookup);
|
||||||
return (LeafFactory) ctx -> {
|
return (LeafFactory) ctx -> {
|
||||||
CompositeFieldScript compositeFieldScript = parentLeafFactory.newInstance(ctx);
|
CompositeFieldScript compositeFieldScript = parentLeafFactory.newInstance(ctx);
|
||||||
return new LongFieldScript(leafFieldName, params, searchLookup, ctx) {
|
return new LongFieldScript(leafFieldName, params, searchLookup, onScriptError, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void setDocument(int docId) {
|
public void setDocument(int docId) {
|
||||||
compositeFieldScript.setDocument(docId);
|
compositeFieldScript.setDocument(docId);
|
||||||
|
@ -59,15 +60,21 @@ public abstract class LongFieldScript extends AbstractLongFieldScript {
|
||||||
public static final String[] PARAMETERS = {};
|
public static final String[] PARAMETERS = {};
|
||||||
|
|
||||||
public interface Factory extends ScriptFactory {
|
public interface Factory extends ScriptFactory {
|
||||||
LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup);
|
LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup, OnScriptError onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface LeafFactory {
|
public interface LeafFactory {
|
||||||
LongFieldScript newInstance(LeafReaderContext ctx);
|
LongFieldScript newInstance(LeafReaderContext ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LongFieldScript(String fieldName, Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
|
public LongFieldScript(
|
||||||
super(fieldName, params, searchLookup, ctx);
|
String fieldName,
|
||||||
|
Map<String, Object> params,
|
||||||
|
SearchLookup searchLookup,
|
||||||
|
OnScriptError onScriptError,
|
||||||
|
LeafReaderContext ctx
|
||||||
|
) {
|
||||||
|
super(fieldName, params, searchLookup, onScriptError, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -10,6 +10,7 @@ package org.elasticsearch.script;
|
||||||
|
|
||||||
import org.apache.lucene.index.DocValues;
|
import org.apache.lucene.index.DocValues;
|
||||||
import org.apache.lucene.index.LeafReaderContext;
|
import org.apache.lucene.index.LeafReaderContext;
|
||||||
|
import org.elasticsearch.index.mapper.OnScriptError;
|
||||||
import org.elasticsearch.script.field.LongDocValuesField;
|
import org.elasticsearch.script.field.LongDocValuesField;
|
||||||
import org.elasticsearch.search.lookup.SearchLookup;
|
import org.elasticsearch.search.lookup.SearchLookup;
|
||||||
|
|
||||||
|
@ -21,7 +22,7 @@ public class SortedNumericDocValuesLongFieldScript extends AbstractLongFieldScri
|
||||||
final LongDocValuesField longDocValuesField;
|
final LongDocValuesField longDocValuesField;
|
||||||
|
|
||||||
public SortedNumericDocValuesLongFieldScript(String fieldName, SearchLookup lookup, LeafReaderContext ctx) {
|
public SortedNumericDocValuesLongFieldScript(String fieldName, SearchLookup lookup, LeafReaderContext ctx) {
|
||||||
super(fieldName, Map.of(), lookup, ctx);
|
super(fieldName, Map.of(), lookup, OnScriptError.FAIL, ctx);
|
||||||
try {
|
try {
|
||||||
longDocValuesField = new LongDocValuesField(DocValues.getSortedNumeric(ctx.reader(), fieldName), fieldName);
|
longDocValuesField = new LongDocValuesField(DocValues.getSortedNumeric(ctx.reader(), fieldName), fieldName);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.apache.lucene.index.DocValues;
|
||||||
import org.apache.lucene.index.LeafReaderContext;
|
import org.apache.lucene.index.LeafReaderContext;
|
||||||
import org.apache.lucene.index.SortedSetDocValues;
|
import org.apache.lucene.index.SortedSetDocValues;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
|
import org.elasticsearch.index.mapper.OnScriptError;
|
||||||
import org.elasticsearch.search.lookup.SearchLookup;
|
import org.elasticsearch.search.lookup.SearchLookup;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -23,7 +24,7 @@ public class SortedSetDocValuesStringFieldScript extends StringFieldScript {
|
||||||
boolean hasValue = false;
|
boolean hasValue = false;
|
||||||
|
|
||||||
public SortedSetDocValuesStringFieldScript(String fieldName, SearchLookup searchLookup, LeafReaderContext ctx) {
|
public SortedSetDocValuesStringFieldScript(String fieldName, SearchLookup searchLookup, LeafReaderContext ctx) {
|
||||||
super(fieldName, Map.of(), searchLookup, ctx);
|
super(fieldName, Map.of(), searchLookup, OnScriptError.FAIL, ctx);
|
||||||
try {
|
try {
|
||||||
sortedSetDocValues = DocValues.getSortedSet(ctx.reader(), fieldName);
|
sortedSetDocValues = DocValues.getSortedSet(ctx.reader(), fieldName);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
package org.elasticsearch.script;
|
package org.elasticsearch.script;
|
||||||
|
|
||||||
import org.apache.lucene.index.LeafReaderContext;
|
import org.apache.lucene.index.LeafReaderContext;
|
||||||
|
import org.elasticsearch.index.mapper.OnScriptError;
|
||||||
import org.elasticsearch.search.lookup.SearchLookup;
|
import org.elasticsearch.search.lookup.SearchLookup;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -28,8 +29,8 @@ public abstract class StringFieldScript extends AbstractFieldScript {
|
||||||
|
|
||||||
public static final StringFieldScript.Factory PARSE_FROM_SOURCE = new Factory() {
|
public static final StringFieldScript.Factory PARSE_FROM_SOURCE = new Factory() {
|
||||||
@Override
|
@Override
|
||||||
public LeafFactory newFactory(String field, Map<String, Object> params, SearchLookup lookup) {
|
public LeafFactory newFactory(String field, Map<String, Object> params, SearchLookup lookup, OnScriptError onScriptError) {
|
||||||
return ctx -> new StringFieldScript(field, params, lookup, ctx) {
|
return ctx -> new StringFieldScript(field, params, lookup, OnScriptError.FAIL, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emitFromSource();
|
emitFromSource();
|
||||||
|
@ -44,11 +45,11 @@ public abstract class StringFieldScript extends AbstractFieldScript {
|
||||||
};
|
};
|
||||||
|
|
||||||
public static Factory leafAdapter(Function<SearchLookup, CompositeFieldScript.LeafFactory> parentFactory) {
|
public static Factory leafAdapter(Function<SearchLookup, CompositeFieldScript.LeafFactory> parentFactory) {
|
||||||
return (leafFieldName, params, searchLookup) -> {
|
return (leafFieldName, params, searchLookup, onScriptError) -> {
|
||||||
CompositeFieldScript.LeafFactory parentLeafFactory = parentFactory.apply(searchLookup);
|
CompositeFieldScript.LeafFactory parentLeafFactory = parentFactory.apply(searchLookup);
|
||||||
return (LeafFactory) ctx -> {
|
return (LeafFactory) ctx -> {
|
||||||
CompositeFieldScript compositeFieldScript = parentLeafFactory.newInstance(ctx);
|
CompositeFieldScript compositeFieldScript = parentLeafFactory.newInstance(ctx);
|
||||||
return new StringFieldScript(leafFieldName, params, searchLookup, ctx) {
|
return new StringFieldScript(leafFieldName, params, searchLookup, onScriptError, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void setDocument(int docId) {
|
public void setDocument(int docId) {
|
||||||
compositeFieldScript.setDocument(docId);
|
compositeFieldScript.setDocument(docId);
|
||||||
|
@ -67,7 +68,7 @@ public abstract class StringFieldScript extends AbstractFieldScript {
|
||||||
public static final String[] PARAMETERS = {};
|
public static final String[] PARAMETERS = {};
|
||||||
|
|
||||||
public interface Factory extends ScriptFactory {
|
public interface Factory extends ScriptFactory {
|
||||||
LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup);
|
LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup, OnScriptError onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface LeafFactory {
|
public interface LeafFactory {
|
||||||
|
@ -77,8 +78,14 @@ public abstract class StringFieldScript extends AbstractFieldScript {
|
||||||
private final List<String> results = new ArrayList<>();
|
private final List<String> results = new ArrayList<>();
|
||||||
private long chars;
|
private long chars;
|
||||||
|
|
||||||
public StringFieldScript(String fieldName, Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
|
public StringFieldScript(
|
||||||
super(fieldName, params, searchLookup, ctx);
|
String fieldName,
|
||||||
|
Map<String, Object> params,
|
||||||
|
SearchLookup searchLookup,
|
||||||
|
OnScriptError onScriptError,
|
||||||
|
LeafReaderContext ctx
|
||||||
|
) {
|
||||||
|
super(fieldName, params, searchLookup, ctx, onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.elasticsearch.cluster.metadata.IndexMetadata;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.time.DateUtils;
|
import org.elasticsearch.common.time.DateUtils;
|
||||||
import org.elasticsearch.index.mapper.MapperServiceTestCase;
|
import org.elasticsearch.index.mapper.MapperServiceTestCase;
|
||||||
|
import org.elasticsearch.index.mapper.OnScriptError;
|
||||||
import org.elasticsearch.script.Script;
|
import org.elasticsearch.script.Script;
|
||||||
import org.elasticsearch.script.ScriptContext;
|
import org.elasticsearch.script.ScriptContext;
|
||||||
import org.elasticsearch.script.StringFieldScript;
|
import org.elasticsearch.script.StringFieldScript;
|
||||||
|
@ -264,7 +265,12 @@ public class TimeSeriesModeTests extends MapperServiceTestCase {
|
||||||
if (context.equals(StringFieldScript.CONTEXT) && script.getLang().equals("mock")) {
|
if (context.equals(StringFieldScript.CONTEXT) && script.getLang().equals("mock")) {
|
||||||
return (T) new StringFieldScript.Factory() {
|
return (T) new StringFieldScript.Factory() {
|
||||||
@Override
|
@Override
|
||||||
public LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup) {
|
public LeafFactory newFactory(
|
||||||
|
String fieldName,
|
||||||
|
Map<String, Object> params,
|
||||||
|
SearchLookup searchLookup,
|
||||||
|
OnScriptError onScriptError
|
||||||
|
) {
|
||||||
throw new UnsupportedOperationException("error should be thrown before getting here");
|
throw new UnsupportedOperationException("error should be thrown before getting here");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,9 +8,14 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.mapper;
|
package org.elasticsearch.index.mapper;
|
||||||
|
|
||||||
|
import org.apache.lucene.document.StoredField;
|
||||||
|
import org.apache.lucene.index.DirectoryReader;
|
||||||
import org.apache.lucene.index.IndexReader;
|
import org.apache.lucene.index.IndexReader;
|
||||||
import org.apache.lucene.search.IndexSearcher;
|
import org.apache.lucene.search.IndexSearcher;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
|
import org.apache.lucene.store.Directory;
|
||||||
|
import org.apache.lucene.tests.index.RandomIndexWriter;
|
||||||
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.elasticsearch.ElasticsearchException;
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
import org.elasticsearch.common.bytes.BytesReference;
|
||||||
|
@ -18,6 +23,7 @@ import org.elasticsearch.common.geo.ShapeRelation;
|
||||||
import org.elasticsearch.common.xcontent.XContentHelper;
|
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataContext;
|
import org.elasticsearch.index.fielddata.FieldDataContext;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
|
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
|
||||||
|
import org.elasticsearch.index.query.ExistsQueryBuilder;
|
||||||
import org.elasticsearch.index.query.SearchExecutionContext;
|
import org.elasticsearch.index.query.SearchExecutionContext;
|
||||||
import org.elasticsearch.indices.breaker.NoneCircuitBreakerService;
|
import org.elasticsearch.indices.breaker.NoneCircuitBreakerService;
|
||||||
import org.elasticsearch.script.BooleanFieldScript;
|
import org.elasticsearch.script.BooleanFieldScript;
|
||||||
|
@ -38,7 +44,9 @@ import org.elasticsearch.xcontent.json.JsonXContent;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
@ -157,6 +165,45 @@ public abstract class AbstractScriptFieldTypeTestCase extends MapperServiceTestC
|
||||||
assertEquals(concreteIndexType.isAggregatable(), scriptFieldType.isAggregatable());
|
assertEquals(concreteIndexType.isAggregatable(), scriptFieldType.isAggregatable());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that running query on a runtime field script that fails has the expected behaviour according to its configuration
|
||||||
|
*/
|
||||||
|
public final void testOnScriptError() throws IOException {
|
||||||
|
try (Directory directory = newDirectory(); RandomIndexWriter iw = new RandomIndexWriter(random(), directory)) {
|
||||||
|
iw.addDocument(List.of(new StoredField("_source", new BytesRef("{\"foo\": [1]}"))));
|
||||||
|
try (DirectoryReader reader = iw.getReader()) {
|
||||||
|
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
||||||
|
{
|
||||||
|
AbstractScriptFieldType<?> fieldType = build("error", Collections.emptyMap(), OnScriptError.CONTINUE);
|
||||||
|
SearchExecutionContext searchExecutionContext = mockContext(true, fieldType);
|
||||||
|
Query query = new ExistsQueryBuilder("test").rewrite(searchExecutionContext).toQuery(searchExecutionContext);
|
||||||
|
assertEquals(0, searcher.count(query));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
AbstractScriptFieldType<?> fieldType = build("error", Collections.emptyMap(), OnScriptError.FAIL);
|
||||||
|
SearchExecutionContext searchExecutionContext = mockContext(true, fieldType);
|
||||||
|
Query query = new ExistsQueryBuilder("test").rewrite(searchExecutionContext).toQuery(searchExecutionContext);
|
||||||
|
expectThrows(RuntimeException.class, () -> searcher.count(query));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void testOnScriptErrorFail() throws IOException {
|
||||||
|
try (Directory directory = newDirectory(); RandomIndexWriter iw = new RandomIndexWriter(random(), directory)) {
|
||||||
|
iw.addDocument(List.of(new StoredField("_source", new BytesRef("{\"foo\": [1]}"))));
|
||||||
|
try (DirectoryReader reader = iw.getReader()) {
|
||||||
|
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
||||||
|
AbstractScriptFieldType<?> fieldType = build("error", Collections.emptyMap(), OnScriptError.FAIL);
|
||||||
|
SearchExecutionContext searchExecutionContext = mockContext(true, fieldType);
|
||||||
|
Query query = new ExistsQueryBuilder("test").rewrite(searchExecutionContext).toQuery(searchExecutionContext);
|
||||||
|
expectThrows(RuntimeException.class, () -> searcher.count(query));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract AbstractScriptFieldType<?> build(String error, Map<String, Object> emptyMap, OnScriptError onScriptError);
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public abstract void testDocValues() throws IOException;
|
public abstract void testDocValues() throws IOException;
|
||||||
|
|
||||||
|
@ -237,6 +284,7 @@ public abstract class AbstractScriptFieldTypeTestCase extends MapperServiceTestC
|
||||||
return ft.fielddataBuilder(new FieldDataContext("test", context::lookup, context::sourcePath, fdo))
|
return ft.fielddataBuilder(new FieldDataContext("test", context::lookup, context::sourcePath, fdo))
|
||||||
.build(new IndexFieldDataCache.None(), new NoneCircuitBreakerService());
|
.build(new IndexFieldDataCache.None(), new NoneCircuitBreakerService());
|
||||||
});
|
});
|
||||||
|
when(context.getMatchingFieldNames(any())).thenReturn(Set.of("dummy_field"));
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -258,7 +258,13 @@ public class BooleanFieldMapperTests extends MapperTestCase {
|
||||||
return new IngestScriptSupport() {
|
return new IngestScriptSupport() {
|
||||||
@Override
|
@Override
|
||||||
protected BooleanFieldScript.Factory emptyFieldScript() {
|
protected BooleanFieldScript.Factory emptyFieldScript() {
|
||||||
return (fieldName, params, searchLookup) -> ctx -> new BooleanFieldScript(fieldName, params, searchLookup, ctx) {
|
return (fieldName, params, searchLookup, onScriptError) -> ctx -> new BooleanFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
searchLookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {}
|
public void execute() {}
|
||||||
};
|
};
|
||||||
|
@ -266,7 +272,13 @@ public class BooleanFieldMapperTests extends MapperTestCase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected BooleanFieldScript.Factory nonEmptyFieldScript() {
|
protected BooleanFieldScript.Factory nonEmptyFieldScript() {
|
||||||
return (fieldName, params, searchLookup) -> ctx -> new BooleanFieldScript(fieldName, params, searchLookup, ctx) {
|
return (fieldName, params, searchLookup, onScriptError) -> ctx -> new BooleanFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
searchLookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emit(true);
|
emit(true);
|
||||||
|
|
|
@ -24,10 +24,11 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class BooleanFieldScriptTests extends FieldScriptTestCase<BooleanFieldScript.Factory> {
|
public class BooleanFieldScriptTests extends FieldScriptTestCase<BooleanFieldScript.Factory> {
|
||||||
public static final BooleanFieldScript.Factory DUMMY = (fieldName, params, lookup) -> ctx -> new BooleanFieldScript(
|
public static final BooleanFieldScript.Factory DUMMY = (fieldName, params, lookup, onScriptError) -> ctx -> new BooleanFieldScript(
|
||||||
fieldName,
|
fieldName,
|
||||||
params,
|
params,
|
||||||
lookup,
|
lookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
ctx
|
ctx
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -59,6 +60,7 @@ public class BooleanFieldScriptTests extends FieldScriptTestCase<BooleanFieldScr
|
||||||
"test",
|
"test",
|
||||||
Map.of(),
|
Map.of(),
|
||||||
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
||||||
|
OnScriptError.FAIL,
|
||||||
reader.leaves().get(0)
|
reader.leaves().get(0)
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -253,7 +253,10 @@ public class BooleanScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeT
|
||||||
assertThat(searcher.count(simpleMappedFieldType().termQuery(true, mockContext())), equalTo(1));
|
assertThat(searcher.count(simpleMappedFieldType().termQuery(true, mockContext())), equalTo(1));
|
||||||
assertThat(searcher.count(simpleMappedFieldType().termQuery("true", mockContext())), equalTo(1));
|
assertThat(searcher.count(simpleMappedFieldType().termQuery("true", mockContext())), equalTo(1));
|
||||||
assertThat(searcher.count(simpleMappedFieldType().termQuery(false, mockContext())), equalTo(0));
|
assertThat(searcher.count(simpleMappedFieldType().termQuery(false, mockContext())), equalTo(0));
|
||||||
assertThat(searcher.count(build("xor_param", Map.of("param", false)).termQuery(true, mockContext())), equalTo(1));
|
assertThat(
|
||||||
|
searcher.count(build("xor_param", Map.of("param", false), OnScriptError.FAIL).termQuery(true, mockContext())),
|
||||||
|
equalTo(1)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try (Directory directory = newDirectory(); RandomIndexWriter iw = new RandomIndexWriter(random(), directory)) {
|
try (Directory directory = newDirectory(); RandomIndexWriter iw = new RandomIndexWriter(random(), directory)) {
|
||||||
|
@ -264,7 +267,10 @@ public class BooleanScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeT
|
||||||
assertThat(searcher.count(simpleMappedFieldType().termQuery("false", mockContext())), equalTo(1));
|
assertThat(searcher.count(simpleMappedFieldType().termQuery("false", mockContext())), equalTo(1));
|
||||||
assertThat(searcher.count(simpleMappedFieldType().termQuery(null, mockContext())), equalTo(1));
|
assertThat(searcher.count(simpleMappedFieldType().termQuery(null, mockContext())), equalTo(1));
|
||||||
assertThat(searcher.count(simpleMappedFieldType().termQuery(true, mockContext())), equalTo(0));
|
assertThat(searcher.count(simpleMappedFieldType().termQuery(true, mockContext())), equalTo(0));
|
||||||
assertThat(searcher.count(build("xor_param", Map.of("param", false)).termQuery(false, mockContext())), equalTo(1));
|
assertThat(
|
||||||
|
searcher.count(build("xor_param", Map.of("param", false), OnScriptError.FAIL).termQuery(false, mockContext())),
|
||||||
|
equalTo(1)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -400,12 +406,12 @@ public class BooleanScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeT
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected BooleanScriptFieldType simpleMappedFieldType() {
|
protected BooleanScriptFieldType simpleMappedFieldType() {
|
||||||
return build("read_foo", Map.of());
|
return build("read_foo", Map.of(), OnScriptError.FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MappedFieldType loopFieldType() {
|
protected MappedFieldType loopFieldType() {
|
||||||
return build("loop", Map.of());
|
return build("loop", Map.of(), OnScriptError.FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -413,13 +419,20 @@ public class BooleanScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeT
|
||||||
return "boolean";
|
return "boolean";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BooleanScriptFieldType build(String code, Map<String, Object> params) {
|
protected BooleanScriptFieldType build(String code, Map<String, Object> params, OnScriptError onScriptError) {
|
||||||
return build(new Script(ScriptType.INLINE, "test", code, params));
|
Script script = new Script(ScriptType.INLINE, "test", code, params);
|
||||||
|
return new BooleanScriptFieldType("test", factory(script), script, emptyMap(), onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BooleanFieldScript.Factory factory(Script script) {
|
private static BooleanFieldScript.Factory factory(Script script) {
|
||||||
return switch (script.getIdOrCode()) {
|
return switch (script.getIdOrCode()) {
|
||||||
case "read_foo" -> (fieldName, params, lookup) -> (ctx) -> new BooleanFieldScript(fieldName, params, lookup, ctx) {
|
case "read_foo" -> (fieldName, params, lookup, onScriptError) -> (ctx) -> new BooleanFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
lookup,
|
||||||
|
onScriptError,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
for (Object foo : (List<?>) lookup.source().source().get("foo")) {
|
for (Object foo : (List<?>) lookup.source().source().get("foo")) {
|
||||||
|
@ -427,7 +440,13 @@ public class BooleanScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
case "xor_param" -> (fieldName, params, lookup) -> (ctx) -> new BooleanFieldScript(fieldName, params, lookup, ctx) {
|
case "xor_param" -> (fieldName, params, lookup, onScriptError) -> (ctx) -> new BooleanFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
lookup,
|
||||||
|
onScriptError,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
for (Object foo : (List<?>) lookup.source().source().get("foo")) {
|
for (Object foo : (List<?>) lookup.source().source().get("foo")) {
|
||||||
|
@ -435,16 +454,24 @@ public class BooleanScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
case "loop" -> (fieldName, params, lookup) -> {
|
case "loop" -> (fieldName, params, lookup, onScriptError) -> {
|
||||||
// Indicate that this script wants the field call "test", which *is* the name of this field
|
// Indicate that this script wants the field call "test", which *is* the name of this field
|
||||||
lookup.forkAndTrackFieldReferences("test");
|
lookup.forkAndTrackFieldReferences("test");
|
||||||
throw new IllegalStateException("should have thrown on the line above");
|
throw new IllegalStateException("should have thrown on the line above");
|
||||||
};
|
};
|
||||||
|
case "error" -> (fieldName, params, lookup, onScriptError) -> ctx -> new BooleanFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
lookup,
|
||||||
|
onScriptError,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
throw new RuntimeException("test error");
|
||||||
|
}
|
||||||
|
};
|
||||||
default -> throw new IllegalArgumentException("unsupported script [" + script.getIdOrCode() + "]");
|
default -> throw new IllegalArgumentException("unsupported script [" + script.getIdOrCode() + "]");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BooleanScriptFieldType build(Script script) {
|
|
||||||
return new BooleanScriptFieldType("test", factory(script), script, emptyMap());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,11 +21,16 @@ public class BooleanScriptMapperTests extends MapperScriptTestCase<BooleanFieldS
|
||||||
private static BooleanFieldScript.Factory factory(Consumer<BooleanFieldScript> executor) {
|
private static BooleanFieldScript.Factory factory(Consumer<BooleanFieldScript> executor) {
|
||||||
return new BooleanFieldScript.Factory() {
|
return new BooleanFieldScript.Factory() {
|
||||||
@Override
|
@Override
|
||||||
public BooleanFieldScript.LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup) {
|
public BooleanFieldScript.LeafFactory newFactory(
|
||||||
|
String fieldName,
|
||||||
|
Map<String, Object> params,
|
||||||
|
SearchLookup searchLookup,
|
||||||
|
OnScriptError onScriptError
|
||||||
|
) {
|
||||||
return new BooleanFieldScript.LeafFactory() {
|
return new BooleanFieldScript.LeafFactory() {
|
||||||
@Override
|
@Override
|
||||||
public BooleanFieldScript newInstance(LeafReaderContext ctx) {
|
public BooleanFieldScript newInstance(LeafReaderContext ctx) {
|
||||||
return new BooleanFieldScript(fieldName, params, searchLookup, ctx) {
|
return new BooleanFieldScript(fieldName, params, searchLookup, OnScriptError.FAIL, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
executor.accept(this);
|
executor.accept(this);
|
||||||
|
|
|
@ -33,10 +33,11 @@ public class CompositeRuntimeFieldTests extends MapperServiceTestCase {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected <T> T compileScript(Script script, ScriptContext<T> context) {
|
protected <T> T compileScript(Script script, ScriptContext<T> context) {
|
||||||
if (context == CompositeFieldScript.CONTEXT) {
|
if (context == CompositeFieldScript.CONTEXT) {
|
||||||
return (T) (CompositeFieldScript.Factory) (fieldName, params, searchLookup) -> ctx -> new CompositeFieldScript(
|
return (T) (CompositeFieldScript.Factory) (fieldName, params, searchLookup, onScriptError) -> ctx -> new CompositeFieldScript(
|
||||||
fieldName,
|
fieldName,
|
||||||
params,
|
params,
|
||||||
searchLookup,
|
searchLookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
ctx
|
ctx
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -52,7 +53,13 @@ public class CompositeRuntimeFieldTests extends MapperServiceTestCase {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (context == LongFieldScript.CONTEXT) {
|
if (context == LongFieldScript.CONTEXT) {
|
||||||
return (T) (LongFieldScript.Factory) (field, params, lookup) -> ctx -> new LongFieldScript(field, params, lookup, ctx) {
|
return (T) (LongFieldScript.Factory) (field, params, lookup, onScriptError) -> ctx -> new LongFieldScript(
|
||||||
|
field,
|
||||||
|
params,
|
||||||
|
lookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
|
|
||||||
|
|
|
@ -669,11 +669,12 @@ public class DateFieldMapperTests extends MapperTestCase {
|
||||||
return new IngestScriptSupport() {
|
return new IngestScriptSupport() {
|
||||||
@Override
|
@Override
|
||||||
protected DateFieldScript.Factory emptyFieldScript() {
|
protected DateFieldScript.Factory emptyFieldScript() {
|
||||||
return (fieldName, params, searchLookup, formatter) -> ctx -> new DateFieldScript(
|
return (fieldName, params, searchLookup, formatter, onScriptError) -> ctx -> new DateFieldScript(
|
||||||
fieldName,
|
fieldName,
|
||||||
params,
|
params,
|
||||||
searchLookup,
|
searchLookup,
|
||||||
formatter,
|
formatter,
|
||||||
|
OnScriptError.FAIL,
|
||||||
ctx
|
ctx
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -683,11 +684,12 @@ public class DateFieldMapperTests extends MapperTestCase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DateFieldScript.Factory nonEmptyFieldScript() {
|
protected DateFieldScript.Factory nonEmptyFieldScript() {
|
||||||
return (fieldName, params, searchLookup, formatter) -> ctx -> new DateFieldScript(
|
return (fieldName, params, searchLookup, formatter, onScriptError) -> ctx -> new DateFieldScript(
|
||||||
fieldName,
|
fieldName,
|
||||||
params,
|
params,
|
||||||
searchLookup,
|
searchLookup,
|
||||||
formatter,
|
formatter,
|
||||||
|
OnScriptError.FAIL,
|
||||||
ctx
|
ctx
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -32,11 +32,12 @@ import java.util.Map;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
public class DateFieldScriptTests extends FieldScriptTestCase<DateFieldScript.Factory> {
|
public class DateFieldScriptTests extends FieldScriptTestCase<DateFieldScript.Factory> {
|
||||||
public static final DateFieldScript.Factory DUMMY = (fieldName, params, lookup, formatter) -> ctx -> new DateFieldScript(
|
public static final DateFieldScript.Factory DUMMY = (fieldName, params, lookup, formatter, onScriptError) -> ctx -> new DateFieldScript(
|
||||||
fieldName,
|
fieldName,
|
||||||
params,
|
params,
|
||||||
lookup,
|
lookup,
|
||||||
formatter,
|
formatter,
|
||||||
|
OnScriptError.FAIL,
|
||||||
ctx
|
ctx
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -69,6 +70,7 @@ public class DateFieldScriptTests extends FieldScriptTestCase<DateFieldScript.Fa
|
||||||
Map.of(),
|
Map.of(),
|
||||||
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
||||||
DateFormatter.forPattern(randomDateFormatterPattern()).withLocale(randomLocale(random())),
|
DateFormatter.forPattern(randomDateFormatterPattern()).withLocale(randomLocale(random())),
|
||||||
|
OnScriptError.FAIL,
|
||||||
reader.leaves().get(0)
|
reader.leaves().get(0)
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -104,7 +106,8 @@ public class DateFieldScriptTests extends FieldScriptTestCase<DateFieldScript.Fa
|
||||||
"field",
|
"field",
|
||||||
Collections.emptyMap(),
|
Collections.emptyMap(),
|
||||||
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
||||||
DateFormatter.forPattern("epoch_millis")
|
DateFormatter.forPattern("epoch_millis"),
|
||||||
|
OnScriptError.FAIL
|
||||||
);
|
);
|
||||||
DateFieldScript dateFieldScript = leafFactory.newInstance(reader.leaves().get(0));
|
DateFieldScript dateFieldScript = leafFactory.newInstance(reader.leaves().get(0));
|
||||||
List<Long> results = new ArrayList<>();
|
List<Long> results = new ArrayList<>();
|
||||||
|
|
|
@ -128,7 +128,11 @@ public class DateScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeTest
|
||||||
|
|
||||||
public void testFormatDuel() throws IOException {
|
public void testFormatDuel() throws IOException {
|
||||||
DateFormatter formatter = DateFormatter.forPattern(randomDateFormatterPattern()).withLocale(randomLocale(random()));
|
DateFormatter formatter = DateFormatter.forPattern(randomDateFormatterPattern()).withLocale(randomLocale(random()));
|
||||||
DateScriptFieldType scripted = build(new Script(ScriptType.INLINE, "test", "read_timestamp", Map.of()), formatter);
|
DateScriptFieldType scripted = build(
|
||||||
|
new Script(ScriptType.INLINE, "test", "read_timestamp", Map.of()),
|
||||||
|
formatter,
|
||||||
|
OnScriptError.FAIL
|
||||||
|
);
|
||||||
DateFieldMapper.DateFieldType indexed = new DateFieldMapper.DateFieldType("test", formatter);
|
DateFieldMapper.DateFieldType indexed = new DateFieldMapper.DateFieldType("test", formatter);
|
||||||
for (int i = 0; i < 100; i++) {
|
for (int i = 0; i < 100; i++) {
|
||||||
long date = randomDate();
|
long date = randomDate();
|
||||||
|
@ -149,7 +153,7 @@ public class DateScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeTest
|
||||||
List<Long> results = new ArrayList<>();
|
List<Long> results = new ArrayList<>();
|
||||||
try (DirectoryReader reader = iw.getReader()) {
|
try (DirectoryReader reader = iw.getReader()) {
|
||||||
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
||||||
DateScriptFieldType ft = build("add_days", Map.of("days", 1));
|
DateScriptFieldType ft = build("add_days", Map.of("days", 1), OnScriptError.FAIL);
|
||||||
DateScriptFieldData ifd = ft.fielddataBuilder(mockFielddataContext()).build(null, null);
|
DateScriptFieldData ifd = ft.fielddataBuilder(mockFielddataContext()).build(null, null);
|
||||||
searcher.search(new MatchAllDocsQuery(), new Collector() {
|
searcher.search(new MatchAllDocsQuery(), new Collector() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -381,7 +385,9 @@ public class DateScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeTest
|
||||||
assertThat(searcher.count(simpleMappedFieldType().termQuery(1595432181354L, mockContext())), equalTo(1));
|
assertThat(searcher.count(simpleMappedFieldType().termQuery(1595432181354L, mockContext())), equalTo(1));
|
||||||
assertThat(searcher.count(simpleMappedFieldType().termQuery(2595432181354L, mockContext())), equalTo(0));
|
assertThat(searcher.count(simpleMappedFieldType().termQuery(2595432181354L, mockContext())), equalTo(0));
|
||||||
assertThat(
|
assertThat(
|
||||||
searcher.count(build("add_days", Map.of("days", 1)).termQuery("2020-07-23T15:36:21.354Z", mockContext())),
|
searcher.count(
|
||||||
|
build("add_days", Map.of("days", 1), OnScriptError.FAIL).termQuery("2020-07-23T15:36:21.354Z", mockContext())
|
||||||
|
),
|
||||||
equalTo(1)
|
equalTo(1)
|
||||||
);
|
);
|
||||||
checkBadDate(() -> searcher.count(simpleMappedFieldType().termQuery("2020-07-22(-■_■)15:36:21.354Z", mockContext())));
|
checkBadDate(() -> searcher.count(simpleMappedFieldType().termQuery("2020-07-22(-■_■)15:36:21.354Z", mockContext())));
|
||||||
|
@ -462,7 +468,11 @@ public class DateScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeTest
|
||||||
}
|
}
|
||||||
|
|
||||||
private DateScriptFieldType coolFormattedFieldType() {
|
private DateScriptFieldType coolFormattedFieldType() {
|
||||||
return build(simpleMappedFieldType().script, DateFormatter.forPattern("yyyy-MM-dd(-■_■)HH:mm:ss.SSSz||epoch_millis"));
|
return build(
|
||||||
|
simpleMappedFieldType().script,
|
||||||
|
DateFormatter.forPattern("yyyy-MM-dd(-■_■)HH:mm:ss.SSSz||epoch_millis"),
|
||||||
|
OnScriptError.FAIL
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -470,21 +480,22 @@ public class DateScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeTest
|
||||||
return "date";
|
return "date";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DateScriptFieldType build(String code) {
|
private DateScriptFieldType build(String code) {
|
||||||
return build(code, Map.of());
|
return build(code, Map.of(), OnScriptError.FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DateScriptFieldType build(String code, Map<String, Object> params) {
|
protected DateScriptFieldType build(String code, Map<String, Object> params, OnScriptError onScriptError) {
|
||||||
return build(new Script(ScriptType.INLINE, "test", code, params), DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER);
|
return build(new Script(ScriptType.INLINE, "test", code, params), DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER, onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DateFieldScript.Factory factory(Script script) {
|
private static DateFieldScript.Factory factory(Script script) {
|
||||||
return switch (script.getIdOrCode()) {
|
return switch (script.getIdOrCode()) {
|
||||||
case "read_timestamp" -> (fieldName, params, lookup, formatter) -> ctx -> new DateFieldScript(
|
case "read_timestamp" -> (fieldName, params, lookup, formatter, onScriptError) -> ctx -> new DateFieldScript(
|
||||||
fieldName,
|
fieldName,
|
||||||
params,
|
params,
|
||||||
lookup,
|
lookup,
|
||||||
formatter,
|
formatter,
|
||||||
|
onScriptError,
|
||||||
ctx
|
ctx
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -495,11 +506,12 @@ public class DateScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
case "add_days" -> (fieldName, params, lookup, formatter) -> ctx -> new DateFieldScript(
|
case "add_days" -> (fieldName, params, lookup, formatter, onScriptError) -> ctx -> new DateFieldScript(
|
||||||
fieldName,
|
fieldName,
|
||||||
params,
|
params,
|
||||||
lookup,
|
lookup,
|
||||||
formatter,
|
formatter,
|
||||||
|
onScriptError,
|
||||||
ctx
|
ctx
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -512,17 +524,30 @@ public class DateScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
case "loop" -> (fieldName, params, lookup, formatter) -> {
|
case "loop" -> (fieldName, params, lookup, formatter, onScriptError) -> {
|
||||||
// Indicate that this script wants the field call "test", which *is* the name of this field
|
// Indicate that this script wants the field call "test", which *is* the name of this field
|
||||||
lookup.forkAndTrackFieldReferences("test");
|
lookup.forkAndTrackFieldReferences("test");
|
||||||
throw new IllegalStateException("shoud have thrown on the line above");
|
throw new IllegalStateException("should have thrown on the line above");
|
||||||
|
};
|
||||||
|
case "error" -> (fieldName, params, lookup, formatter, onScriptError) -> ctx -> new DateFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
lookup,
|
||||||
|
formatter,
|
||||||
|
onScriptError,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
throw new RuntimeException("test error");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
default -> throw new IllegalArgumentException("unsupported script [" + script.getIdOrCode() + "]");
|
default -> throw new IllegalArgumentException("unsupported script [" + script.getIdOrCode() + "]");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DateScriptFieldType build(Script script, DateFormatter dateTimeFormatter) {
|
private static DateScriptFieldType build(Script script, DateFormatter dateTimeFormatter, OnScriptError onScriptError) {
|
||||||
return new DateScriptFieldType("test", factory(script), dateTimeFormatter, script, emptyMap());
|
return new DateScriptFieldType("test", factory(script), dateTimeFormatter, script, emptyMap(), onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long randomDate() {
|
private static long randomDate() {
|
||||||
|
|
|
@ -26,12 +26,13 @@ public class DateScriptMapperTests extends MapperScriptTestCase<DateFieldScript.
|
||||||
String fieldName,
|
String fieldName,
|
||||||
Map<String, Object> params,
|
Map<String, Object> params,
|
||||||
SearchLookup searchLookup,
|
SearchLookup searchLookup,
|
||||||
DateFormatter formatter
|
DateFormatter formatter,
|
||||||
|
OnScriptError onScriptError
|
||||||
) {
|
) {
|
||||||
return new DateFieldScript.LeafFactory() {
|
return new DateFieldScript.LeafFactory() {
|
||||||
@Override
|
@Override
|
||||||
public DateFieldScript newInstance(LeafReaderContext ctx) {
|
public DateFieldScript newInstance(LeafReaderContext ctx) {
|
||||||
return new DateFieldScript(fieldName, params, searchLookup, formatter, ctx) {
|
return new DateFieldScript(fieldName, params, searchLookup, formatter, OnScriptError.FAIL, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
executor.accept(this);
|
executor.accept(this);
|
||||||
|
|
|
@ -2604,7 +2604,8 @@ public class DocumentParserTests extends MapperServiceTestCase {
|
||||||
protected RuntimeField createChildRuntimeField(
|
protected RuntimeField createChildRuntimeField(
|
||||||
MappingParserContext parserContext,
|
MappingParserContext parserContext,
|
||||||
String parentName,
|
String parentName,
|
||||||
Function<SearchLookup, CompositeFieldScript.LeafFactory> parentScriptFactory
|
Function<SearchLookup, CompositeFieldScript.LeafFactory> parentScriptFactory,
|
||||||
|
OnScriptError onScriptError
|
||||||
) {
|
) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,13 @@ public class DoubleFieldMapperTests extends NumberFieldMapperTests {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DoubleFieldScript.Factory emptyFieldScript() {
|
protected DoubleFieldScript.Factory emptyFieldScript() {
|
||||||
return (fieldName, params, searchLookup) -> ctx -> new DoubleFieldScript(fieldName, params, searchLookup, ctx) {
|
return (fieldName, params, searchLookup, onScriptError) -> ctx -> new DoubleFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
searchLookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {}
|
public void execute() {}
|
||||||
};
|
};
|
||||||
|
@ -113,7 +119,13 @@ public class DoubleFieldMapperTests extends NumberFieldMapperTests {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DoubleFieldScript.Factory nonEmptyFieldScript() {
|
protected DoubleFieldScript.Factory nonEmptyFieldScript() {
|
||||||
return (fieldName, params, searchLookup) -> ctx -> new DoubleFieldScript(fieldName, params, searchLookup, ctx) {
|
return (fieldName, params, searchLookup, onScriptError) -> ctx -> new DoubleFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
searchLookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emit(1.0);
|
emit(1.0);
|
||||||
|
|
|
@ -31,10 +31,11 @@ import java.util.Map;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
public class DoubleFieldScriptTests extends FieldScriptTestCase<DoubleFieldScript.Factory> {
|
public class DoubleFieldScriptTests extends FieldScriptTestCase<DoubleFieldScript.Factory> {
|
||||||
public static final DoubleFieldScript.Factory DUMMY = (fieldName, params, lookup) -> ctx -> new DoubleFieldScript(
|
public static final DoubleFieldScript.Factory DUMMY = (fieldName, params, lookup, onScriptError) -> ctx -> new DoubleFieldScript(
|
||||||
fieldName,
|
fieldName,
|
||||||
params,
|
params,
|
||||||
lookup,
|
lookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
ctx
|
ctx
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -66,6 +67,7 @@ public class DoubleFieldScriptTests extends FieldScriptTestCase<DoubleFieldScrip
|
||||||
"test",
|
"test",
|
||||||
Map.of(),
|
Map.of(),
|
||||||
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
||||||
|
OnScriptError.FAIL,
|
||||||
reader.leaves().get(0)
|
reader.leaves().get(0)
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -100,7 +102,8 @@ public class DoubleFieldScriptTests extends FieldScriptTestCase<DoubleFieldScrip
|
||||||
DoubleFieldScript.LeafFactory leafFactory = fromSource().newFactory(
|
DoubleFieldScript.LeafFactory leafFactory = fromSource().newFactory(
|
||||||
"field",
|
"field",
|
||||||
Collections.emptyMap(),
|
Collections.emptyMap(),
|
||||||
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider())
|
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
||||||
|
OnScriptError.FAIL
|
||||||
);
|
);
|
||||||
DoubleFieldScript doubleFieldScript = leafFactory.newInstance(reader.leaves().get(0));
|
DoubleFieldScript doubleFieldScript = leafFactory.newInstance(reader.leaves().get(0));
|
||||||
List<Double> results = new ArrayList<>();
|
List<Double> results = new ArrayList<>();
|
||||||
|
|
|
@ -64,7 +64,7 @@ public class DoubleScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeTe
|
||||||
List<Double> results = new ArrayList<>();
|
List<Double> results = new ArrayList<>();
|
||||||
try (DirectoryReader reader = iw.getReader()) {
|
try (DirectoryReader reader = iw.getReader()) {
|
||||||
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
||||||
DoubleScriptFieldType ft = build("add_param", Map.of("param", 1));
|
DoubleScriptFieldType ft = build("add_param", Map.of("param", 1), OnScriptError.FAIL);
|
||||||
DoubleScriptFieldData ifd = ft.fielddataBuilder(mockFielddataContext()).build(null, null);
|
DoubleScriptFieldData ifd = ft.fielddataBuilder(mockFielddataContext()).build(null, null);
|
||||||
searcher.search(new MatchAllDocsQuery(), new Collector() {
|
searcher.search(new MatchAllDocsQuery(), new Collector() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -190,7 +190,10 @@ public class DoubleScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeTe
|
||||||
assertThat(searcher.count(simpleMappedFieldType().termQuery("1", mockContext())), equalTo(1));
|
assertThat(searcher.count(simpleMappedFieldType().termQuery("1", mockContext())), equalTo(1));
|
||||||
assertThat(searcher.count(simpleMappedFieldType().termQuery(1, mockContext())), equalTo(1));
|
assertThat(searcher.count(simpleMappedFieldType().termQuery(1, mockContext())), equalTo(1));
|
||||||
assertThat(searcher.count(simpleMappedFieldType().termQuery(1.1, mockContext())), equalTo(0));
|
assertThat(searcher.count(simpleMappedFieldType().termQuery(1.1, mockContext())), equalTo(0));
|
||||||
assertThat(searcher.count(build("add_param", Map.of("param", 1)).termQuery(2, mockContext())), equalTo(1));
|
assertThat(
|
||||||
|
searcher.count(build("add_param", Map.of("param", 1), OnScriptError.FAIL).termQuery(2, mockContext())),
|
||||||
|
equalTo(1)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -223,12 +226,12 @@ public class DoubleScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeTe
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DoubleScriptFieldType simpleMappedFieldType() {
|
protected DoubleScriptFieldType simpleMappedFieldType() {
|
||||||
return build("read_foo", Map.of());
|
return build("read_foo", Map.of(), OnScriptError.FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MappedFieldType loopFieldType() {
|
protected MappedFieldType loopFieldType() {
|
||||||
return build("loop", Map.of());
|
return build("loop", Map.of(), OnScriptError.FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -236,13 +239,20 @@ public class DoubleScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeTe
|
||||||
return "double";
|
return "double";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DoubleScriptFieldType build(String code, Map<String, Object> params) {
|
protected DoubleScriptFieldType build(String code, Map<String, Object> params, OnScriptError onScriptError) {
|
||||||
return build(new Script(ScriptType.INLINE, "test", code, params));
|
Script script = new Script(ScriptType.INLINE, "test", code, params);
|
||||||
|
return new DoubleScriptFieldType("test", factory(script), script, emptyMap(), onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DoubleFieldScript.Factory factory(Script script) {
|
private static DoubleFieldScript.Factory factory(Script script) {
|
||||||
return switch (script.getIdOrCode()) {
|
return switch (script.getIdOrCode()) {
|
||||||
case "read_foo" -> (fieldName, params, lookup) -> (ctx) -> new DoubleFieldScript(fieldName, params, lookup, ctx) {
|
case "read_foo" -> (fieldName, params, lookup, onScriptError) -> (ctx) -> new DoubleFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
lookup,
|
||||||
|
onScriptError,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
for (Object foo : (List<?>) lookup.source().source().get("foo")) {
|
for (Object foo : (List<?>) lookup.source().source().get("foo")) {
|
||||||
|
@ -250,7 +260,13 @@ public class DoubleScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeTe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
case "add_param" -> (fieldName, params, lookup) -> (ctx) -> new DoubleFieldScript(fieldName, params, lookup, ctx) {
|
case "add_param" -> (fieldName, params, lookup, onScriptError) -> (ctx) -> new DoubleFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
lookup,
|
||||||
|
onScriptError,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
for (Object foo : (List<?>) lookup.source().source().get("foo")) {
|
for (Object foo : (List<?>) lookup.source().source().get("foo")) {
|
||||||
|
@ -258,16 +274,24 @@ public class DoubleScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeTe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
case "loop" -> (fieldName, params, lookup) -> {
|
case "loop" -> (fieldName, params, lookup, onScriptError) -> {
|
||||||
// Indicate that this script wants the field call "test", which *is* the name of this field
|
// Indicate that this script wants the field call "test", which *is* the name of this field
|
||||||
lookup.forkAndTrackFieldReferences("test");
|
lookup.forkAndTrackFieldReferences("test");
|
||||||
throw new IllegalStateException("shoud have thrown on the line above");
|
throw new IllegalStateException("should have thrown on the line above");
|
||||||
|
};
|
||||||
|
case "error" -> (fieldName, params, lookup, onScriptError) -> ctx -> new DoubleFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
lookup,
|
||||||
|
onScriptError,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
throw new RuntimeException("test error");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
default -> throw new IllegalArgumentException("unsupported script [" + script.getIdOrCode() + "]");
|
default -> throw new IllegalArgumentException("unsupported script [" + script.getIdOrCode() + "]");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DoubleScriptFieldType build(Script script) {
|
|
||||||
return new DoubleScriptFieldType("test", factory(script), script, emptyMap());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,11 +21,16 @@ public class DoubleScriptMapperTests extends MapperScriptTestCase<DoubleFieldScr
|
||||||
private static DoubleFieldScript.Factory factory(Consumer<DoubleFieldScript> executor) {
|
private static DoubleFieldScript.Factory factory(Consumer<DoubleFieldScript> executor) {
|
||||||
return new DoubleFieldScript.Factory() {
|
return new DoubleFieldScript.Factory() {
|
||||||
@Override
|
@Override
|
||||||
public DoubleFieldScript.LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup) {
|
public DoubleFieldScript.LeafFactory newFactory(
|
||||||
|
String fieldName,
|
||||||
|
Map<String, Object> params,
|
||||||
|
SearchLookup searchLookup,
|
||||||
|
OnScriptError onScriptError
|
||||||
|
) {
|
||||||
return new DoubleFieldScript.LeafFactory() {
|
return new DoubleFieldScript.LeafFactory() {
|
||||||
@Override
|
@Override
|
||||||
public DoubleFieldScript newInstance(LeafReaderContext ctx) {
|
public DoubleFieldScript newInstance(LeafReaderContext ctx) {
|
||||||
return new DoubleFieldScript(fieldName, params, searchLookup, ctx) {
|
return new DoubleFieldScript(fieldName, params, searchLookup, OnScriptError.FAIL, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
executor.accept(this);
|
executor.accept(this);
|
||||||
|
|
|
@ -26,10 +26,11 @@ import java.util.Map;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
public class GeoPointFieldScriptTests extends FieldScriptTestCase<GeoPointFieldScript.Factory> {
|
public class GeoPointFieldScriptTests extends FieldScriptTestCase<GeoPointFieldScript.Factory> {
|
||||||
public static final GeoPointFieldScript.Factory DUMMY = (fieldName, params, lookup) -> ctx -> new GeoPointFieldScript(
|
public static final GeoPointFieldScript.Factory DUMMY = (fieldName, params, lookup, onScriptError) -> ctx -> new GeoPointFieldScript(
|
||||||
fieldName,
|
fieldName,
|
||||||
params,
|
params,
|
||||||
lookup,
|
lookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
ctx
|
ctx
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -61,6 +62,7 @@ public class GeoPointFieldScriptTests extends FieldScriptTestCase<GeoPointFieldS
|
||||||
"test",
|
"test",
|
||||||
Map.of(),
|
Map.of(),
|
||||||
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
||||||
|
OnScriptError.FAIL,
|
||||||
reader.leaves().get(0)
|
reader.leaves().get(0)
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -64,7 +64,7 @@ public class GeoPointScriptFieldTypeTests extends AbstractNonTextScriptFieldType
|
||||||
List<Object> results = new ArrayList<>();
|
List<Object> results = new ArrayList<>();
|
||||||
try (DirectoryReader reader = iw.getReader()) {
|
try (DirectoryReader reader = iw.getReader()) {
|
||||||
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
||||||
GeoPointScriptFieldType ft = build("fromLatLon", Map.of());
|
GeoPointScriptFieldType ft = build("fromLatLon", Map.of(), OnScriptError.FAIL);
|
||||||
GeoPointScriptFieldData ifd = ft.fielddataBuilder(mockFielddataContext()).build(null, null);
|
GeoPointScriptFieldData ifd = ft.fielddataBuilder(mockFielddataContext()).build(null, null);
|
||||||
searcher.search(new MatchAllDocsQuery(), new Collector() {
|
searcher.search(new MatchAllDocsQuery(), new Collector() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -213,12 +213,12 @@ public class GeoPointScriptFieldTypeTests extends AbstractNonTextScriptFieldType
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected GeoPointScriptFieldType simpleMappedFieldType() {
|
protected GeoPointScriptFieldType simpleMappedFieldType() {
|
||||||
return build("fromLatLon", Map.of());
|
return build("fromLatLon", Map.of(), OnScriptError.FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MappedFieldType loopFieldType() {
|
protected MappedFieldType loopFieldType() {
|
||||||
return build("loop", Map.of());
|
return build("loop", Map.of(), OnScriptError.FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -226,29 +226,44 @@ public class GeoPointScriptFieldTypeTests extends AbstractNonTextScriptFieldType
|
||||||
return "geo_point";
|
return "geo_point";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GeoPointScriptFieldType build(String code, Map<String, Object> params) {
|
protected GeoPointScriptFieldType build(String code, Map<String, Object> params, OnScriptError onScriptError) {
|
||||||
return build(new Script(ScriptType.INLINE, "test", code, params));
|
Script script = new Script(ScriptType.INLINE, "test", code, params);
|
||||||
|
return new GeoPointScriptFieldType("test", factory(script), script, emptyMap(), onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GeoPointFieldScript.Factory factory(Script script) {
|
private static GeoPointFieldScript.Factory factory(Script script) {
|
||||||
return switch (script.getIdOrCode()) {
|
return switch (script.getIdOrCode()) {
|
||||||
case "fromLatLon" -> (fieldName, params, lookup) -> (ctx) -> new GeoPointFieldScript(fieldName, params, lookup, ctx) {
|
case "fromLatLon" -> (fieldName, params, lookup, onScriptError) -> (ctx) -> new GeoPointFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
lookup,
|
||||||
|
onScriptError,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
Map<?, ?> foo = (Map<?, ?>) lookup.source().source().get("foo");
|
Map<?, ?> foo = (Map<?, ?>) lookup.source().source().get("foo");
|
||||||
emit(((Number) foo.get("lat")).doubleValue(), ((Number) foo.get("lon")).doubleValue());
|
emit(((Number) foo.get("lat")).doubleValue(), ((Number) foo.get("lon")).doubleValue());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
case "loop" -> (fieldName, params, lookup) -> {
|
case "loop" -> (fieldName, params, lookup, onScriptError) -> {
|
||||||
// Indicate that this script wants the field call "test", which *is* the name of this field
|
// Indicate that this script wants the field call "test", which *is* the name of this field
|
||||||
lookup.forkAndTrackFieldReferences("test");
|
lookup.forkAndTrackFieldReferences("test");
|
||||||
throw new IllegalStateException("shoud have thrown on the line above");
|
throw new IllegalStateException("should have thrown on the line above");
|
||||||
|
};
|
||||||
|
case "error" -> (fieldName, params, lookup, onScriptError) -> ctx -> new GeoPointFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
lookup,
|
||||||
|
onScriptError,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
throw new RuntimeException("test error");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
default -> throw new IllegalArgumentException("unsupported script [" + script.getIdOrCode() + "]");
|
default -> throw new IllegalArgumentException("unsupported script [" + script.getIdOrCode() + "]");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GeoPointScriptFieldType build(Script script) {
|
|
||||||
return new GeoPointScriptFieldType("test", factory(script), script, emptyMap());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,11 +21,16 @@ public class GeoPointScriptMapperTests extends MapperScriptTestCase<GeoPointFiel
|
||||||
private static GeoPointFieldScript.Factory factory(Consumer<GeoPointFieldScript.Emit> executor) {
|
private static GeoPointFieldScript.Factory factory(Consumer<GeoPointFieldScript.Emit> executor) {
|
||||||
return new GeoPointFieldScript.Factory() {
|
return new GeoPointFieldScript.Factory() {
|
||||||
@Override
|
@Override
|
||||||
public GeoPointFieldScript.LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup) {
|
public GeoPointFieldScript.LeafFactory newFactory(
|
||||||
|
String fieldName,
|
||||||
|
Map<String, Object> params,
|
||||||
|
SearchLookup searchLookup,
|
||||||
|
OnScriptError onScriptError
|
||||||
|
) {
|
||||||
return new GeoPointFieldScript.LeafFactory() {
|
return new GeoPointFieldScript.LeafFactory() {
|
||||||
@Override
|
@Override
|
||||||
public GeoPointFieldScript newInstance(LeafReaderContext ctx) {
|
public GeoPointFieldScript newInstance(LeafReaderContext ctx) {
|
||||||
return new GeoPointFieldScript(fieldName, params, searchLookup, ctx) {
|
return new GeoPointFieldScript(fieldName, params, searchLookup, OnScriptError.FAIL, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
executor.accept(new Emit(this));
|
executor.accept(new Emit(this));
|
||||||
|
|
|
@ -128,7 +128,7 @@ public class IndexTimeScriptTests extends MapperServiceTestCase {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected <T> T compileScript(Script script, ScriptContext<T> context) {
|
protected <T> T compileScript(Script script, ScriptContext<T> context) {
|
||||||
if (context.factoryClazz == LongFieldScript.Factory.class) {
|
if (context.factoryClazz == LongFieldScript.Factory.class) {
|
||||||
return (T) (LongFieldScript.Factory) (n, p, l) -> ctx -> new TestLongFieldScript(
|
return (T) (LongFieldScript.Factory) (n, p, l, onScriptError) -> ctx -> new TestLongFieldScript(
|
||||||
n,
|
n,
|
||||||
p,
|
p,
|
||||||
l,
|
l,
|
||||||
|
@ -137,7 +137,7 @@ public class IndexTimeScriptTests extends MapperServiceTestCase {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (context.factoryClazz == DoubleFieldScript.Factory.class) {
|
if (context.factoryClazz == DoubleFieldScript.Factory.class) {
|
||||||
return (T) (DoubleFieldScript.Factory) (n, p, l) -> ctx -> new TestDoubleFieldScript(
|
return (T) (DoubleFieldScript.Factory) (n, p, l, onScriptError) -> ctx -> new TestDoubleFieldScript(
|
||||||
n,
|
n,
|
||||||
p,
|
p,
|
||||||
l,
|
l,
|
||||||
|
@ -195,7 +195,7 @@ public class IndexTimeScriptTests extends MapperServiceTestCase {
|
||||||
LeafReaderContext ctx,
|
LeafReaderContext ctx,
|
||||||
Consumer<TestLongFieldScript> executor
|
Consumer<TestLongFieldScript> executor
|
||||||
) {
|
) {
|
||||||
super(fieldName, params, searchLookup, ctx);
|
super(fieldName, params, searchLookup, OnScriptError.FAIL, ctx);
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ public class IndexTimeScriptTests extends MapperServiceTestCase {
|
||||||
LeafReaderContext ctx,
|
LeafReaderContext ctx,
|
||||||
Consumer<TestDoubleFieldScript> executor
|
Consumer<TestDoubleFieldScript> executor
|
||||||
) {
|
) {
|
||||||
super(fieldName, params, searchLookup, ctx);
|
super(fieldName, params, searchLookup, OnScriptError.FAIL, ctx);
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -388,7 +388,13 @@ public class IpFieldMapperTests extends MapperTestCase {
|
||||||
return new IngestScriptSupport() {
|
return new IngestScriptSupport() {
|
||||||
@Override
|
@Override
|
||||||
protected IpFieldScript.Factory emptyFieldScript() {
|
protected IpFieldScript.Factory emptyFieldScript() {
|
||||||
return (fieldName, params, searchLookup) -> ctx -> new IpFieldScript(fieldName, params, searchLookup, ctx) {
|
return (fieldName, params, searchLookup, onScriptError) -> ctx -> new IpFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
searchLookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {}
|
public void execute() {}
|
||||||
};
|
};
|
||||||
|
@ -396,7 +402,13 @@ public class IpFieldMapperTests extends MapperTestCase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IpFieldScript.Factory nonEmptyFieldScript() {
|
protected IpFieldScript.Factory nonEmptyFieldScript() {
|
||||||
return (fieldName, params, searchLookup) -> ctx -> new IpFieldScript(fieldName, params, searchLookup, ctx) {
|
return (fieldName, params, searchLookup, onScriptError) -> ctx -> new IpFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
searchLookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emit("192.168.0.1");
|
emit("192.168.0.1");
|
||||||
|
|
|
@ -32,10 +32,11 @@ import java.util.Map;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
public class IpFieldScriptTests extends FieldScriptTestCase<IpFieldScript.Factory> {
|
public class IpFieldScriptTests extends FieldScriptTestCase<IpFieldScript.Factory> {
|
||||||
public static final IpFieldScript.Factory DUMMY = (fieldName, params, lookup) -> ctx -> new IpFieldScript(
|
public static final IpFieldScript.Factory DUMMY = (fieldName, params, lookup, onScriptError) -> ctx -> new IpFieldScript(
|
||||||
fieldName,
|
fieldName,
|
||||||
params,
|
params,
|
||||||
lookup,
|
lookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
ctx
|
ctx
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -67,6 +68,7 @@ public class IpFieldScriptTests extends FieldScriptTestCase<IpFieldScript.Factor
|
||||||
"test",
|
"test",
|
||||||
Map.of(),
|
Map.of(),
|
||||||
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
||||||
|
OnScriptError.FAIL,
|
||||||
reader.leaves().get(0)
|
reader.leaves().get(0)
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -101,7 +103,8 @@ public class IpFieldScriptTests extends FieldScriptTestCase<IpFieldScript.Factor
|
||||||
IpFieldScript.LeafFactory leafFactory = fromSource().newFactory(
|
IpFieldScript.LeafFactory leafFactory = fromSource().newFactory(
|
||||||
"field",
|
"field",
|
||||||
Collections.emptyMap(),
|
Collections.emptyMap(),
|
||||||
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider())
|
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
||||||
|
OnScriptError.FAIL
|
||||||
);
|
);
|
||||||
IpFieldScript ipFieldScript = leafFactory.newInstance(reader.leaves().get(0));
|
IpFieldScript ipFieldScript = leafFactory.newInstance(reader.leaves().get(0));
|
||||||
List<InetAddress> results = new ArrayList<>();
|
List<InetAddress> results = new ArrayList<>();
|
||||||
|
|
|
@ -66,7 +66,7 @@ public class IpScriptFieldTypeTests extends AbstractScriptFieldTypeTestCase {
|
||||||
List<Object> results = new ArrayList<>();
|
List<Object> results = new ArrayList<>();
|
||||||
try (DirectoryReader reader = iw.getReader()) {
|
try (DirectoryReader reader = iw.getReader()) {
|
||||||
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
||||||
IpScriptFieldType ft = build("append_param", Map.of("param", ".1"));
|
IpScriptFieldType ft = build("append_param", Map.of("param", ".1"), OnScriptError.FAIL);
|
||||||
BinaryScriptFieldData ifd = ft.fielddataBuilder(mockFielddataContext()).build(null, null);
|
BinaryScriptFieldData ifd = ft.fielddataBuilder(mockFielddataContext()).build(null, null);
|
||||||
DocValueFormat format = ft.docValueFormat(null, null);
|
DocValueFormat format = ft.docValueFormat(null, null);
|
||||||
searcher.search(new MatchAllDocsQuery(), new Collector() {
|
searcher.search(new MatchAllDocsQuery(), new Collector() {
|
||||||
|
@ -198,7 +198,7 @@ public class IpScriptFieldTypeTests extends AbstractScriptFieldTypeTestCase {
|
||||||
iw.addDocument(List.of(new StoredField("_source", new BytesRef("{\"foo\": [\"200.0.0\"]}"))));
|
iw.addDocument(List.of(new StoredField("_source", new BytesRef("{\"foo\": [\"200.0.0\"]}"))));
|
||||||
try (DirectoryReader reader = iw.getReader()) {
|
try (DirectoryReader reader = iw.getReader()) {
|
||||||
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
||||||
IpScriptFieldType fieldType = build("append_param", Map.of("param", ".1"));
|
IpScriptFieldType fieldType = build("append_param", Map.of("param", ".1"), OnScriptError.FAIL);
|
||||||
assertThat(searcher.count(fieldType.termQuery("192.168.0.1", mockContext())), equalTo(1));
|
assertThat(searcher.count(fieldType.termQuery("192.168.0.1", mockContext())), equalTo(1));
|
||||||
assertThat(searcher.count(fieldType.termQuery("192.168.0.7", mockContext())), equalTo(0));
|
assertThat(searcher.count(fieldType.termQuery("192.168.0.7", mockContext())), equalTo(0));
|
||||||
assertThat(searcher.count(fieldType.termQuery("192.168.0.0/16", mockContext())), equalTo(2));
|
assertThat(searcher.count(fieldType.termQuery("192.168.0.0/16", mockContext())), equalTo(2));
|
||||||
|
@ -240,12 +240,12 @@ public class IpScriptFieldTypeTests extends AbstractScriptFieldTypeTestCase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IpScriptFieldType simpleMappedFieldType() {
|
protected IpScriptFieldType simpleMappedFieldType() {
|
||||||
return build("read_foo", Map.of());
|
return build("read_foo", Map.of(), OnScriptError.FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MappedFieldType loopFieldType() {
|
protected MappedFieldType loopFieldType() {
|
||||||
return build("loop", Map.of());
|
return build("loop", Map.of(), OnScriptError.FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -253,13 +253,20 @@ public class IpScriptFieldTypeTests extends AbstractScriptFieldTypeTestCase {
|
||||||
return "ip";
|
return "ip";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IpScriptFieldType build(String code, Map<String, Object> params) {
|
protected IpScriptFieldType build(String code, Map<String, Object> params, OnScriptError onScriptError) {
|
||||||
return build(new Script(ScriptType.INLINE, "test", code, params));
|
Script script = new Script(ScriptType.INLINE, "test", code, params);
|
||||||
|
return new IpScriptFieldType("test", factory(script), script, emptyMap(), onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IpFieldScript.Factory factory(Script script) {
|
private static IpFieldScript.Factory factory(Script script) {
|
||||||
return switch (script.getIdOrCode()) {
|
return switch (script.getIdOrCode()) {
|
||||||
case "read_foo" -> (fieldName, params, lookup) -> (ctx) -> new IpFieldScript(fieldName, params, lookup, ctx) {
|
case "read_foo" -> (fieldName, params, lookup, onScriptError) -> (ctx) -> new IpFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
lookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
for (Object foo : (List<?>) lookup.source().source().get("foo")) {
|
for (Object foo : (List<?>) lookup.source().source().get("foo")) {
|
||||||
|
@ -267,7 +274,13 @@ public class IpScriptFieldTypeTests extends AbstractScriptFieldTypeTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
case "append_param" -> (fieldName, params, lookup) -> (ctx) -> new IpFieldScript(fieldName, params, lookup, ctx) {
|
case "append_param" -> (fieldName, params, lookup, onScriptError) -> (ctx) -> new IpFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
lookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
for (Object foo : (List<?>) lookup.source().source().get("foo")) {
|
for (Object foo : (List<?>) lookup.source().source().get("foo")) {
|
||||||
|
@ -275,16 +288,24 @@ public class IpScriptFieldTypeTests extends AbstractScriptFieldTypeTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
case "loop" -> (fieldName, params, lookup) -> {
|
case "loop" -> (fieldName, params, lookup, onScriptError) -> {
|
||||||
// Indicate that this script wants the field call "test", which *is* the name of this field
|
// Indicate that this script wants the field call "test", which *is* the name of this field
|
||||||
lookup.forkAndTrackFieldReferences("test");
|
lookup.forkAndTrackFieldReferences("test");
|
||||||
throw new IllegalStateException("shoud have thrown on the line above");
|
throw new IllegalStateException("should have thrown on the line above");
|
||||||
|
};
|
||||||
|
case "error" -> (fieldName, params, lookup, onScriptError) -> ctx -> new IpFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
lookup,
|
||||||
|
onScriptError,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
throw new RuntimeException("test error");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
default -> throw new IllegalArgumentException("unsupported script [" + script.getIdOrCode() + "]");
|
default -> throw new IllegalArgumentException("unsupported script [" + script.getIdOrCode() + "]");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IpScriptFieldType build(Script script) {
|
|
||||||
return new IpScriptFieldType("test", factory(script), script, emptyMap());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,11 +21,16 @@ public class IpScriptMapperTests extends MapperScriptTestCase<IpFieldScript.Fact
|
||||||
private static IpFieldScript.Factory factory(Consumer<IpFieldScript> executor) {
|
private static IpFieldScript.Factory factory(Consumer<IpFieldScript> executor) {
|
||||||
return new IpFieldScript.Factory() {
|
return new IpFieldScript.Factory() {
|
||||||
@Override
|
@Override
|
||||||
public IpFieldScript.LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup) {
|
public IpFieldScript.LeafFactory newFactory(
|
||||||
|
String fieldName,
|
||||||
|
Map<String, Object> params,
|
||||||
|
SearchLookup searchLookup,
|
||||||
|
OnScriptError onScriptError
|
||||||
|
) {
|
||||||
return new IpFieldScript.LeafFactory() {
|
return new IpFieldScript.LeafFactory() {
|
||||||
@Override
|
@Override
|
||||||
public IpFieldScript newInstance(LeafReaderContext ctx) {
|
public IpFieldScript newInstance(LeafReaderContext ctx) {
|
||||||
return new IpFieldScript(fieldName, params, searchLookup, ctx) {
|
return new IpFieldScript(fieldName, params, searchLookup, OnScriptError.FAIL, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
executor.accept(this);
|
executor.accept(this);
|
||||||
|
|
|
@ -729,7 +729,13 @@ public class KeywordFieldMapperTests extends MapperTestCase {
|
||||||
return new IngestScriptSupport() {
|
return new IngestScriptSupport() {
|
||||||
@Override
|
@Override
|
||||||
protected StringFieldScript.Factory emptyFieldScript() {
|
protected StringFieldScript.Factory emptyFieldScript() {
|
||||||
return (fieldName, params, searchLookup) -> ctx -> new StringFieldScript(fieldName, params, searchLookup, ctx) {
|
return (fieldName, params, searchLookup, onScriptError) -> ctx -> new StringFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
searchLookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {}
|
public void execute() {}
|
||||||
};
|
};
|
||||||
|
@ -737,7 +743,13 @@ public class KeywordFieldMapperTests extends MapperTestCase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected StringFieldScript.Factory nonEmptyFieldScript() {
|
protected StringFieldScript.Factory nonEmptyFieldScript() {
|
||||||
return (fieldName, params, searchLookup) -> ctx -> new StringFieldScript(fieldName, params, searchLookup, ctx) {
|
return (fieldName, params, searchLookup, onScriptError) -> ctx -> new StringFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
searchLookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emit("foo");
|
emit("foo");
|
||||||
|
|
|
@ -60,7 +60,7 @@ public class KeywordScriptFieldTypeTests extends AbstractScriptFieldTypeTestCase
|
||||||
List<String> results = new ArrayList<>();
|
List<String> results = new ArrayList<>();
|
||||||
try (DirectoryReader reader = iw.getReader()) {
|
try (DirectoryReader reader = iw.getReader()) {
|
||||||
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
||||||
KeywordScriptFieldType ft = build("append_param", Map.of("param", "-suffix"));
|
KeywordScriptFieldType ft = build("append_param", Map.of("param", "-suffix"), OnScriptError.FAIL);
|
||||||
StringScriptFieldData ifd = ft.fielddataBuilder(mockFielddataContext()).build(null, null);
|
StringScriptFieldData ifd = ft.fielddataBuilder(mockFielddataContext()).build(null, null);
|
||||||
searcher.search(new MatchAllDocsQuery(), new Collector() {
|
searcher.search(new MatchAllDocsQuery(), new Collector() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -287,7 +287,7 @@ public class KeywordScriptFieldTypeTests extends AbstractScriptFieldTypeTestCase
|
||||||
iw.addDocument(List.of(new StoredField("_source", new BytesRef("{\"foo\": [2]}"))));
|
iw.addDocument(List.of(new StoredField("_source", new BytesRef("{\"foo\": [2]}"))));
|
||||||
try (DirectoryReader reader = iw.getReader()) {
|
try (DirectoryReader reader = iw.getReader()) {
|
||||||
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
||||||
KeywordScriptFieldType fieldType = build("append_param", Map.of("param", "-suffix"));
|
KeywordScriptFieldType fieldType = build("append_param", Map.of("param", "-suffix"), OnScriptError.FAIL);
|
||||||
assertThat(searcher.count(fieldType.termQuery("1-suffix", mockContext())), equalTo(1));
|
assertThat(searcher.count(fieldType.termQuery("1-suffix", mockContext())), equalTo(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -299,7 +299,7 @@ public class KeywordScriptFieldTypeTests extends AbstractScriptFieldTypeTestCase
|
||||||
iw.addDocument(List.of(new StoredField("_source", new BytesRef("{\"foo\": [2]}"))));
|
iw.addDocument(List.of(new StoredField("_source", new BytesRef("{\"foo\": [2]}"))));
|
||||||
try (DirectoryReader reader = iw.getReader()) {
|
try (DirectoryReader reader = iw.getReader()) {
|
||||||
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
||||||
KeywordScriptFieldType fieldType = build("append_param", Map.of("param", "-suffix"));
|
KeywordScriptFieldType fieldType = build("append_param", Map.of("param", "-suffix"), OnScriptError.FAIL);
|
||||||
expectThrows(
|
expectThrows(
|
||||||
IllegalArgumentException.class,
|
IllegalArgumentException.class,
|
||||||
() -> {
|
() -> {
|
||||||
|
@ -375,7 +375,7 @@ public class KeywordScriptFieldTypeTests extends AbstractScriptFieldTypeTestCase
|
||||||
iw.addDocument(List.of(new StoredField("_source", new BytesRef("{\"foo\": [2]}"))));
|
iw.addDocument(List.of(new StoredField("_source", new BytesRef("{\"foo\": [2]}"))));
|
||||||
try (DirectoryReader reader = iw.getReader()) {
|
try (DirectoryReader reader = iw.getReader()) {
|
||||||
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
||||||
KeywordScriptFieldType fieldType = build("append_param", Map.of("param", "-Suffix"));
|
KeywordScriptFieldType fieldType = build("append_param", Map.of("param", "-Suffix"), OnScriptError.FAIL);
|
||||||
SearchExecutionContext searchExecutionContext = mockContext(true, fieldType);
|
SearchExecutionContext searchExecutionContext = mockContext(true, fieldType);
|
||||||
Query query = new MatchQueryBuilder("test", "1-Suffix").toQuery(searchExecutionContext);
|
Query query = new MatchQueryBuilder("test", "1-Suffix").toQuery(searchExecutionContext);
|
||||||
assertThat(searcher.count(query), equalTo(1));
|
assertThat(searcher.count(query), equalTo(1));
|
||||||
|
@ -385,12 +385,12 @@ public class KeywordScriptFieldTypeTests extends AbstractScriptFieldTypeTestCase
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected KeywordScriptFieldType simpleMappedFieldType() {
|
protected KeywordScriptFieldType simpleMappedFieldType() {
|
||||||
return build("read_foo", Map.of());
|
return build("read_foo", Map.of(), OnScriptError.FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected KeywordScriptFieldType loopFieldType() {
|
protected KeywordScriptFieldType loopFieldType() {
|
||||||
return build("loop", Map.of());
|
return build("loop", Map.of(), OnScriptError.FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -398,13 +398,20 @@ public class KeywordScriptFieldTypeTests extends AbstractScriptFieldTypeTestCase
|
||||||
return "keyword";
|
return "keyword";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static KeywordScriptFieldType build(String code, Map<String, Object> params) {
|
protected KeywordScriptFieldType build(String code, Map<String, Object> params, OnScriptError onScriptError) {
|
||||||
return build(new Script(ScriptType.INLINE, "test", code, params));
|
Script script = new Script(ScriptType.INLINE, "test", code, params);
|
||||||
|
return new KeywordScriptFieldType("test", factory(script), script, emptyMap(), onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static StringFieldScript.Factory factory(Script script) {
|
private static StringFieldScript.Factory factory(Script script) {
|
||||||
return switch (script.getIdOrCode()) {
|
return switch (script.getIdOrCode()) {
|
||||||
case "read_foo" -> (fieldName, params, lookup) -> ctx -> new StringFieldScript(fieldName, params, lookup, ctx) {
|
case "read_foo" -> (fieldName, params, lookup, onScriptError) -> ctx -> new StringFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
lookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
for (Object foo : (List<?>) lookup.source().source().get("foo")) {
|
for (Object foo : (List<?>) lookup.source().source().get("foo")) {
|
||||||
|
@ -412,7 +419,13 @@ public class KeywordScriptFieldTypeTests extends AbstractScriptFieldTypeTestCase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
case "append_param" -> (fieldName, params, lookup) -> ctx -> new StringFieldScript(fieldName, params, lookup, ctx) {
|
case "append_param" -> (fieldName, params, lookup, onScriptError) -> ctx -> new StringFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
lookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
for (Object foo : (List<?>) lookup.source().source().get("foo")) {
|
for (Object foo : (List<?>) lookup.source().source().get("foo")) {
|
||||||
|
@ -420,16 +433,24 @@ public class KeywordScriptFieldTypeTests extends AbstractScriptFieldTypeTestCase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
case "loop" -> (fieldName, params, lookup) -> {
|
case "loop" -> (fieldName, params, lookup, onScriptError) -> {
|
||||||
// Indicate that this script wants the field call "test", which *is* the name of this field
|
// Indicate that this script wants the field call "test", which *is* the name of this field
|
||||||
lookup.forkAndTrackFieldReferences("test");
|
lookup.forkAndTrackFieldReferences("test");
|
||||||
throw new IllegalStateException("shoud have thrown on the line above");
|
throw new IllegalStateException("should have thrown on the line above");
|
||||||
|
};
|
||||||
|
case "error" -> (fieldName, params, lookup, onScriptError) -> ctx -> new StringFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
lookup,
|
||||||
|
onScriptError,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
throw new RuntimeException("test error");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
default -> throw new IllegalArgumentException("unsupported script [" + script.getIdOrCode() + "]");
|
default -> throw new IllegalArgumentException("unsupported script [" + script.getIdOrCode() + "]");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static KeywordScriptFieldType build(Script script) {
|
|
||||||
return new KeywordScriptFieldType("test", factory(script), script, emptyMap());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,11 +22,16 @@ public class KeywordScriptMapperTests extends MapperScriptTestCase<StringFieldSc
|
||||||
private static StringFieldScript.Factory factory(Consumer<StringFieldScript> executor) {
|
private static StringFieldScript.Factory factory(Consumer<StringFieldScript> executor) {
|
||||||
return new StringFieldScript.Factory() {
|
return new StringFieldScript.Factory() {
|
||||||
@Override
|
@Override
|
||||||
public StringFieldScript.LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup) {
|
public StringFieldScript.LeafFactory newFactory(
|
||||||
|
String fieldName,
|
||||||
|
Map<String, Object> params,
|
||||||
|
SearchLookup searchLookup,
|
||||||
|
OnScriptError onScriptError
|
||||||
|
) {
|
||||||
return new StringFieldScript.LeafFactory() {
|
return new StringFieldScript.LeafFactory() {
|
||||||
@Override
|
@Override
|
||||||
public StringFieldScript newInstance(LeafReaderContext ctx) {
|
public StringFieldScript newInstance(LeafReaderContext ctx) {
|
||||||
return new StringFieldScript(fieldName, params, searchLookup, ctx) {
|
return new StringFieldScript(fieldName, params, searchLookup, OnScriptError.FAIL, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
executor.accept(this);
|
executor.accept(this);
|
||||||
|
|
|
@ -132,7 +132,13 @@ public class LongFieldMapperTests extends WholeNumberFieldMapperTests {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected LongFieldScript.Factory emptyFieldScript() {
|
protected LongFieldScript.Factory emptyFieldScript() {
|
||||||
return (fieldName, params, searchLookup) -> ctx -> new LongFieldScript(fieldName, params, searchLookup, ctx) {
|
return (fieldName, params, searchLookup, onScriptError) -> ctx -> new LongFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
searchLookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {}
|
public void execute() {}
|
||||||
};
|
};
|
||||||
|
@ -140,7 +146,13 @@ public class LongFieldMapperTests extends WholeNumberFieldMapperTests {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected LongFieldScript.Factory nonEmptyFieldScript() {
|
protected LongFieldScript.Factory nonEmptyFieldScript() {
|
||||||
return (fieldName, params, searchLookup) -> ctx -> new LongFieldScript(fieldName, params, searchLookup, ctx) {
|
return (fieldName, params, searchLookup, onScriptError) -> ctx -> new LongFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
searchLookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emit(1);
|
emit(1);
|
||||||
|
|
|
@ -31,10 +31,11 @@ import java.util.Map;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
public class LongFieldScriptTests extends FieldScriptTestCase<LongFieldScript.Factory> {
|
public class LongFieldScriptTests extends FieldScriptTestCase<LongFieldScript.Factory> {
|
||||||
public static final LongFieldScript.Factory DUMMY = (fieldName, params, lookup) -> ctx -> new LongFieldScript(
|
public static final LongFieldScript.Factory DUMMY = (fieldName, params, lookup, onScriptError) -> ctx -> new LongFieldScript(
|
||||||
fieldName,
|
fieldName,
|
||||||
params,
|
params,
|
||||||
lookup,
|
lookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
ctx
|
ctx
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -66,6 +67,7 @@ public class LongFieldScriptTests extends FieldScriptTestCase<LongFieldScript.Fa
|
||||||
"test",
|
"test",
|
||||||
Map.of(),
|
Map.of(),
|
||||||
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
||||||
|
OnScriptError.FAIL,
|
||||||
reader.leaves().get(0)
|
reader.leaves().get(0)
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -100,7 +102,8 @@ public class LongFieldScriptTests extends FieldScriptTestCase<LongFieldScript.Fa
|
||||||
LongFieldScript.LeafFactory leafFactory = fromSource().newFactory(
|
LongFieldScript.LeafFactory leafFactory = fromSource().newFactory(
|
||||||
"field",
|
"field",
|
||||||
Collections.emptyMap(),
|
Collections.emptyMap(),
|
||||||
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider())
|
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
||||||
|
OnScriptError.FAIL
|
||||||
);
|
);
|
||||||
LongFieldScript longFieldScript = leafFactory.newInstance(reader.leaves().get(0));
|
LongFieldScript longFieldScript = leafFactory.newInstance(reader.leaves().get(0));
|
||||||
List<Long> results = new ArrayList<>();
|
List<Long> results = new ArrayList<>();
|
||||||
|
|
|
@ -76,7 +76,7 @@ public class LongScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeTest
|
||||||
List<Long> results = new ArrayList<>();
|
List<Long> results = new ArrayList<>();
|
||||||
try (DirectoryReader reader = iw.getReader()) {
|
try (DirectoryReader reader = iw.getReader()) {
|
||||||
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
||||||
LongScriptFieldType ft = build("add_param", Map.of("param", 1));
|
LongScriptFieldType ft = build("add_param", Map.of("param", 1), OnScriptError.FAIL);
|
||||||
LongScriptFieldData ifd = ft.fielddataBuilder(mockFielddataContext()).build(null, null);
|
LongScriptFieldData ifd = ft.fielddataBuilder(mockFielddataContext()).build(null, null);
|
||||||
searcher.search(new MatchAllDocsQuery(), new Collector() {
|
searcher.search(new MatchAllDocsQuery(), new Collector() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -132,7 +132,8 @@ public class LongScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeTest
|
||||||
iw.addDocument(List.of(new StoredField("_source", new BytesRef("{\"timestamp\": [1595432181356]}"))));
|
iw.addDocument(List.of(new StoredField("_source", new BytesRef("{\"timestamp\": [1595432181356]}"))));
|
||||||
try (DirectoryReader reader = iw.getReader()) {
|
try (DirectoryReader reader = iw.getReader()) {
|
||||||
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
IndexSearcher searcher = newUnthreadedSearcher(reader);
|
||||||
LongScriptFieldData ifd = build("millis_ago", Map.of()).fielddataBuilder(mockFielddataContext()).build(null, null);
|
LongScriptFieldData ifd = build("millis_ago", Map.of(), OnScriptError.FAIL).fielddataBuilder(mockFielddataContext())
|
||||||
|
.build(null, null);
|
||||||
SortField sf = ifd.sortField(null, MultiValueMode.MIN, null, false);
|
SortField sf = ifd.sortField(null, MultiValueMode.MIN, null, false);
|
||||||
TopFieldDocs docs = searcher.search(new MatchAllDocsQuery(), 3, new Sort(sf));
|
TopFieldDocs docs = searcher.search(new MatchAllDocsQuery(), 3, new Sort(sf));
|
||||||
assertThat(readSource(reader, docs.scoreDocs[0].doc), equalTo("{\"timestamp\": [1595432181356]}"));
|
assertThat(readSource(reader, docs.scoreDocs[0].doc), equalTo("{\"timestamp\": [1595432181356]}"));
|
||||||
|
@ -222,7 +223,10 @@ public class LongScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeTest
|
||||||
assertThat(searcher.count(simpleMappedFieldType().termQuery("1", mockContext())), equalTo(1));
|
assertThat(searcher.count(simpleMappedFieldType().termQuery("1", mockContext())), equalTo(1));
|
||||||
assertThat(searcher.count(simpleMappedFieldType().termQuery(1, mockContext())), equalTo(1));
|
assertThat(searcher.count(simpleMappedFieldType().termQuery(1, mockContext())), equalTo(1));
|
||||||
assertThat(searcher.count(simpleMappedFieldType().termQuery(1.1, mockContext())), equalTo(0));
|
assertThat(searcher.count(simpleMappedFieldType().termQuery(1.1, mockContext())), equalTo(0));
|
||||||
assertThat(searcher.count(build("add_param", Map.of("param", 1)).termQuery(2, mockContext())), equalTo(1));
|
assertThat(
|
||||||
|
searcher.count(build("add_param", Map.of("param", 1), OnScriptError.FAIL).termQuery(2, mockContext())),
|
||||||
|
equalTo(1)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,12 +259,12 @@ public class LongScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeTest
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected LongScriptFieldType simpleMappedFieldType() {
|
protected LongScriptFieldType simpleMappedFieldType() {
|
||||||
return build("read_foo", Map.of());
|
return build("read_foo", Map.of(), OnScriptError.FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected LongScriptFieldType loopFieldType() {
|
protected LongScriptFieldType loopFieldType() {
|
||||||
return build("loop", Map.of());
|
return build("loop", Map.of(), OnScriptError.FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -268,14 +272,21 @@ public class LongScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeTest
|
||||||
return "long";
|
return "long";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LongScriptFieldType build(String code, Map<String, Object> params) {
|
protected LongScriptFieldType build(String code, Map<String, Object> params, OnScriptError onScriptError) {
|
||||||
return build(new Script(ScriptType.INLINE, "test", code, params));
|
Script script = new Script(ScriptType.INLINE, "test", code, params);
|
||||||
|
return new LongScriptFieldType("test", factory(script), script, emptyMap(), onScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LongFieldScript.Factory factory(Script script) {
|
private static LongFieldScript.Factory factory(Script script) {
|
||||||
switch (script.getIdOrCode()) {
|
switch (script.getIdOrCode()) {
|
||||||
case "read_foo":
|
case "read_foo":
|
||||||
return (fieldName, params, lookup) -> (ctx) -> new LongFieldScript(fieldName, params, lookup, ctx) {
|
return (fieldName, params, lookup, onScriptError) -> (ctx) -> new LongFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
lookup,
|
||||||
|
onScriptError,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
for (Object foo : (List<?>) lookup.source().source().get("foo")) {
|
for (Object foo : (List<?>) lookup.source().source().get("foo")) {
|
||||||
|
@ -284,7 +295,13 @@ public class LongScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeTest
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
case "add_param":
|
case "add_param":
|
||||||
return (fieldName, params, lookup) -> (ctx) -> new LongFieldScript(fieldName, params, lookup, ctx) {
|
return (fieldName, params, lookup, onScriptError) -> (ctx) -> new LongFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
lookup,
|
||||||
|
onScriptError,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
for (Object foo : (List<?>) lookup.source().source().get("foo")) {
|
for (Object foo : (List<?>) lookup.source().source().get("foo")) {
|
||||||
|
@ -295,7 +312,13 @@ public class LongScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeTest
|
||||||
case "millis_ago":
|
case "millis_ago":
|
||||||
// Painless actually call System.currentTimeMillis. We could mock the time but this works fine too.
|
// Painless actually call System.currentTimeMillis. We could mock the time but this works fine too.
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
return (fieldName, params, lookup) -> (ctx) -> new LongFieldScript(fieldName, params, lookup, ctx) {
|
return (fieldName, params, lookup, onScriptError) -> (ctx) -> new LongFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
lookup,
|
||||||
|
onScriptError,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
for (Object timestamp : (List<?>) lookup.source().source().get("timestamp")) {
|
for (Object timestamp : (List<?>) lookup.source().source().get("timestamp")) {
|
||||||
|
@ -304,17 +327,26 @@ public class LongScriptFieldTypeTests extends AbstractNonTextScriptFieldTypeTest
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
case "loop":
|
case "loop":
|
||||||
return (fieldName, params, lookup) -> {
|
return (fieldName, params, lookup, onScriptError) -> {
|
||||||
// Indicate that this script wants the field call "test", which *is* the name of this field
|
// Indicate that this script wants the field call "test", which *is* the name of this field
|
||||||
lookup.forkAndTrackFieldReferences("test");
|
lookup.forkAndTrackFieldReferences("test");
|
||||||
throw new IllegalStateException("shoud have thrown on the line above");
|
throw new IllegalStateException("should have thrown on the line above");
|
||||||
|
};
|
||||||
|
case "error":
|
||||||
|
return (fieldName, params, lookup, onScriptError) -> ctx -> new LongFieldScript(
|
||||||
|
fieldName,
|
||||||
|
params,
|
||||||
|
lookup,
|
||||||
|
onScriptError,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
throw new RuntimeException("test error");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("unsupported script [" + script.getIdOrCode() + "]");
|
throw new IllegalArgumentException("unsupported script [" + script.getIdOrCode() + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LongScriptFieldType build(Script script) {
|
|
||||||
return new LongScriptFieldType("test", factory(script), script, emptyMap());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,11 +21,16 @@ public class LongScriptMapperTests extends MapperScriptTestCase<LongFieldScript.
|
||||||
private static LongFieldScript.Factory factory(Consumer<LongFieldScript> executor) {
|
private static LongFieldScript.Factory factory(Consumer<LongFieldScript> executor) {
|
||||||
return new LongFieldScript.Factory() {
|
return new LongFieldScript.Factory() {
|
||||||
@Override
|
@Override
|
||||||
public LongFieldScript.LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup) {
|
public LongFieldScript.LeafFactory newFactory(
|
||||||
|
String fieldName,
|
||||||
|
Map<String, Object> params,
|
||||||
|
SearchLookup searchLookup,
|
||||||
|
OnScriptError onScriptError
|
||||||
|
) {
|
||||||
return new LongFieldScript.LeafFactory() {
|
return new LongFieldScript.LeafFactory() {
|
||||||
@Override
|
@Override
|
||||||
public LongFieldScript newInstance(LeafReaderContext ctx) {
|
public LongFieldScript newInstance(LeafReaderContext ctx) {
|
||||||
return new LongFieldScript(fieldName, params, searchLookup, ctx) {
|
return new LongFieldScript(fieldName, params, searchLookup, OnScriptError.FAIL, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
executor.accept(this);
|
executor.accept(this);
|
||||||
|
|
|
@ -30,10 +30,11 @@ import java.util.Map;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
public class StringFieldScriptTests extends FieldScriptTestCase<StringFieldScript.Factory> {
|
public class StringFieldScriptTests extends FieldScriptTestCase<StringFieldScript.Factory> {
|
||||||
public static final StringFieldScript.Factory DUMMY = (fieldName, params, lookup) -> ctx -> new StringFieldScript(
|
public static final StringFieldScript.Factory DUMMY = (fieldName, params, lookup, onScriptError) -> ctx -> new StringFieldScript(
|
||||||
fieldName,
|
fieldName,
|
||||||
params,
|
params,
|
||||||
lookup,
|
lookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
ctx
|
ctx
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -65,6 +66,7 @@ public class StringFieldScriptTests extends FieldScriptTestCase<StringFieldScrip
|
||||||
"test",
|
"test",
|
||||||
Map.of(),
|
Map.of(),
|
||||||
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
||||||
|
OnScriptError.FAIL,
|
||||||
reader.leaves().get(0)
|
reader.leaves().get(0)
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -91,6 +93,7 @@ public class StringFieldScriptTests extends FieldScriptTestCase<StringFieldScrip
|
||||||
"test",
|
"test",
|
||||||
Map.of(),
|
Map.of(),
|
||||||
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
||||||
|
OnScriptError.FAIL,
|
||||||
reader.leaves().get(0)
|
reader.leaves().get(0)
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -130,7 +133,8 @@ public class StringFieldScriptTests extends FieldScriptTestCase<StringFieldScrip
|
||||||
StringFieldScript.LeafFactory leafFactory = fromSource().newFactory(
|
StringFieldScript.LeafFactory leafFactory = fromSource().newFactory(
|
||||||
"field",
|
"field",
|
||||||
Collections.emptyMap(),
|
Collections.emptyMap(),
|
||||||
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider())
|
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
||||||
|
OnScriptError.FAIL
|
||||||
);
|
);
|
||||||
StringFieldScript stringFieldScript = leafFactory.newInstance(reader.leaves().get(0));
|
StringFieldScript stringFieldScript = leafFactory.newInstance(reader.leaves().get(0));
|
||||||
stringFieldScript.runForDoc(0);
|
stringFieldScript.runForDoc(0);
|
||||||
|
@ -159,7 +163,8 @@ public class StringFieldScriptTests extends FieldScriptTestCase<StringFieldScrip
|
||||||
StringFieldScript.LeafFactory leafFactory = fromSource().newFactory(
|
StringFieldScript.LeafFactory leafFactory = fromSource().newFactory(
|
||||||
"field",
|
"field",
|
||||||
Collections.emptyMap(),
|
Collections.emptyMap(),
|
||||||
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider())
|
new SearchLookup(field -> null, (ft, lookup, fdt) -> null, new SourceLookup.ReaderSourceProvider()),
|
||||||
|
OnScriptError.FAIL
|
||||||
);
|
);
|
||||||
StringFieldScript stringFieldScript = leafFactory.newInstance(reader.leaves().get(0));
|
StringFieldScript stringFieldScript = leafFactory.newInstance(reader.leaves().get(0));
|
||||||
stringFieldScript.runForDoc(0);
|
stringFieldScript.runForDoc(0);
|
||||||
|
|
|
@ -13,6 +13,7 @@ import org.apache.lucene.index.DirectoryReader;
|
||||||
import org.apache.lucene.store.Directory;
|
import org.apache.lucene.store.Directory;
|
||||||
import org.apache.lucene.tests.index.RandomIndexWriter;
|
import org.apache.lucene.tests.index.RandomIndexWriter;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
|
import org.elasticsearch.index.mapper.OnScriptError;
|
||||||
import org.elasticsearch.search.lookup.SearchLookup;
|
import org.elasticsearch.search.lookup.SearchLookup;
|
||||||
import org.elasticsearch.search.lookup.SourceLookup;
|
import org.elasticsearch.search.lookup.SourceLookup;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
@ -33,6 +34,7 @@ public class CompositeFieldScriptTests extends ESTestCase {
|
||||||
"composite",
|
"composite",
|
||||||
Collections.emptyMap(),
|
Collections.emptyMap(),
|
||||||
new SearchLookup(field -> null, (ft, lookup, ftd) -> null, new SourceLookup.ReaderSourceProvider()),
|
new SearchLookup(field -> null, (ft, lookup, ftd) -> null, new SourceLookup.ReaderSourceProvider()),
|
||||||
|
OnScriptError.FAIL,
|
||||||
reader.leaves().get(0)
|
reader.leaves().get(0)
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -64,6 +66,7 @@ public class CompositeFieldScriptTests extends ESTestCase {
|
||||||
"composite",
|
"composite",
|
||||||
Collections.emptyMap(),
|
Collections.emptyMap(),
|
||||||
new SearchLookup(field -> null, (ft, lookup, ftd) -> null, new SourceLookup.ReaderSourceProvider()),
|
new SearchLookup(field -> null, (ft, lookup, ftd) -> null, new SourceLookup.ReaderSourceProvider()),
|
||||||
|
OnScriptError.FAIL,
|
||||||
reader.leaves().get(0)
|
reader.leaves().get(0)
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -77,6 +80,7 @@ public class CompositeFieldScriptTests extends ESTestCase {
|
||||||
"composite.leaf",
|
"composite.leaf",
|
||||||
Collections.emptyMap(),
|
Collections.emptyMap(),
|
||||||
new SearchLookup(field -> null, (ft, lookup, ftd) -> null, new SourceLookup.ReaderSourceProvider()),
|
new SearchLookup(field -> null, (ft, lookup, ftd) -> null, new SourceLookup.ReaderSourceProvider()),
|
||||||
|
OnScriptError.FAIL,
|
||||||
reader.leaves().get(0)
|
reader.leaves().get(0)
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -27,6 +27,7 @@ import org.elasticsearch.index.mapper.LuceneDocument;
|
||||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.NumberFieldMapper;
|
import org.elasticsearch.index.mapper.NumberFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.NumberFieldMapper.NumberType;
|
import org.elasticsearch.index.mapper.NumberFieldMapper.NumberType;
|
||||||
|
import org.elasticsearch.index.mapper.OnScriptError;
|
||||||
import org.elasticsearch.script.LongFieldScript;
|
import org.elasticsearch.script.LongFieldScript;
|
||||||
import org.elasticsearch.script.Script;
|
import org.elasticsearch.script.Script;
|
||||||
import org.elasticsearch.script.StringFieldScript;
|
import org.elasticsearch.script.StringFieldScript;
|
||||||
|
@ -599,7 +600,7 @@ public class RangeAggregatorTests extends AggregatorTestCase {
|
||||||
public void testRuntimeFieldTopLevelQueryNotOptimized() throws IOException {
|
public void testRuntimeFieldTopLevelQueryNotOptimized() throws IOException {
|
||||||
long totalDocs = (long) RangeAggregator.DOCS_PER_RANGE_TO_USE_FILTERS * 4;
|
long totalDocs = (long) RangeAggregator.DOCS_PER_RANGE_TO_USE_FILTERS * 4;
|
||||||
SearchLookup lookup = new SearchLookup(s -> null, (ft, l, ftd) -> null, new SourceLookup.ReaderSourceProvider());
|
SearchLookup lookup = new SearchLookup(s -> null, (ft, l, ftd) -> null, new SourceLookup.ReaderSourceProvider());
|
||||||
StringFieldScript.LeafFactory scriptFactory = ctx -> new StringFieldScript("dummy", Map.of(), lookup, ctx) {
|
StringFieldScript.LeafFactory scriptFactory = ctx -> new StringFieldScript("dummy", Map.of(), lookup, OnScriptError.FAIL, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emit("cat");
|
emit("cat");
|
||||||
|
@ -641,13 +642,19 @@ public class RangeAggregatorTests extends AggregatorTestCase {
|
||||||
*/
|
*/
|
||||||
public void testRuntimeFieldRangesNotOptimized() throws IOException {
|
public void testRuntimeFieldRangesNotOptimized() throws IOException {
|
||||||
long totalDocs = (long) RangeAggregator.DOCS_PER_RANGE_TO_USE_FILTERS * 4;
|
long totalDocs = (long) RangeAggregator.DOCS_PER_RANGE_TO_USE_FILTERS * 4;
|
||||||
LongFieldScript.Factory scriptFactory = (fieldName, params, l) -> ctx -> new LongFieldScript(fieldName, Map.of(), l, ctx) {
|
LongFieldScript.Factory scriptFactory = (fieldName, params, l, onScriptError) -> ctx -> new LongFieldScript(
|
||||||
|
fieldName,
|
||||||
|
Map.of(),
|
||||||
|
l,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emit((long) getDoc().get(NUMBER_FIELD_NAME).get(0));
|
emit((long) getDoc().get(NUMBER_FIELD_NAME).get(0));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
MappedFieldType dummyFt = new LongScriptFieldType("dummy", scriptFactory, new Script("test"), Map.of());
|
MappedFieldType dummyFt = new LongScriptFieldType("dummy", scriptFactory, new Script("test"), Map.of(), OnScriptError.FAIL);
|
||||||
MappedFieldType numberFt = new NumberFieldMapper.NumberFieldType(NUMBER_FIELD_NAME, NumberFieldMapper.NumberType.INTEGER);
|
MappedFieldType numberFt = new NumberFieldMapper.NumberFieldType(NUMBER_FIELD_NAME, NumberFieldMapper.NumberType.INTEGER);
|
||||||
debugTestCase(
|
debugTestCase(
|
||||||
new RangeAggregationBuilder("r").field("dummy").addRange(0, 1).addRange(1, 2).addRange(2, 3),
|
new RangeAggregationBuilder("r").field("dummy").addRange(0, 1).addRange(1, 2).addRange(2, 3),
|
||||||
|
|
|
@ -60,6 +60,7 @@ import org.elasticsearch.index.mapper.NumberFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.NumberFieldMapper.NumberFieldType;
|
import org.elasticsearch.index.mapper.NumberFieldMapper.NumberFieldType;
|
||||||
import org.elasticsearch.index.mapper.NumberFieldMapper.NumberType;
|
import org.elasticsearch.index.mapper.NumberFieldMapper.NumberType;
|
||||||
import org.elasticsearch.index.mapper.ObjectMapper;
|
import org.elasticsearch.index.mapper.ObjectMapper;
|
||||||
|
import org.elasticsearch.index.mapper.OnScriptError;
|
||||||
import org.elasticsearch.index.mapper.ProvidedIdFieldMapper;
|
import org.elasticsearch.index.mapper.ProvidedIdFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.RangeFieldMapper;
|
import org.elasticsearch.index.mapper.RangeFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.RangeType;
|
import org.elasticsearch.index.mapper.RangeType;
|
||||||
|
@ -1994,7 +1995,7 @@ public class TermsAggregatorTests extends AggregatorTestCase {
|
||||||
public void testRuntimeFieldTopLevelNotOptimized() throws IOException {
|
public void testRuntimeFieldTopLevelNotOptimized() throws IOException {
|
||||||
long totalDocs = 500;
|
long totalDocs = 500;
|
||||||
SearchLookup lookup = new SearchLookup(s -> null, (ft, l, ftd) -> null, new SourceLookup.ReaderSourceProvider());
|
SearchLookup lookup = new SearchLookup(s -> null, (ft, l, ftd) -> null, new SourceLookup.ReaderSourceProvider());
|
||||||
StringFieldScript.LeafFactory scriptFactory = ctx -> new StringFieldScript("dummy", Map.of(), lookup, ctx) {
|
StringFieldScript.LeafFactory scriptFactory = ctx -> new StringFieldScript("dummy", Map.of(), lookup, OnScriptError.FAIL, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emit("cat");
|
emit("cat");
|
||||||
|
@ -2043,10 +2044,11 @@ public class TermsAggregatorTests extends AggregatorTestCase {
|
||||||
*/
|
*/
|
||||||
public void testRuntimeFieldTermsNotOptimized() throws IOException {
|
public void testRuntimeFieldTermsNotOptimized() throws IOException {
|
||||||
long totalDocs = 500;
|
long totalDocs = 500;
|
||||||
StringFieldScript.Factory scriptFactory = (fieldName, params, lookup) -> ctx -> new StringFieldScript(
|
StringFieldScript.Factory scriptFactory = (fieldName, params, lookup, onScriptError) -> ctx -> new StringFieldScript(
|
||||||
fieldName,
|
fieldName,
|
||||||
Map.of(),
|
Map.of(),
|
||||||
lookup,
|
lookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
ctx
|
ctx
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -2056,7 +2058,7 @@ public class TermsAggregatorTests extends AggregatorTestCase {
|
||||||
};
|
};
|
||||||
BytesRef[] values = new BytesRef[] { new BytesRef("stuff"), new BytesRef("more_stuff"), new BytesRef("other_stuff"), };
|
BytesRef[] values = new BytesRef[] { new BytesRef("stuff"), new BytesRef("more_stuff"), new BytesRef("other_stuff"), };
|
||||||
MappedFieldType keywordFt = new KeywordFieldType("k", true, true, Collections.emptyMap());
|
MappedFieldType keywordFt = new KeywordFieldType("k", true, true, Collections.emptyMap());
|
||||||
MappedFieldType dummyFt = new KeywordScriptFieldType("dummy", scriptFactory, new Script("test"), Map.of());
|
MappedFieldType dummyFt = new KeywordScriptFieldType("dummy", scriptFactory, new Script("test"), Map.of(), OnScriptError.FAIL);
|
||||||
debugTestCase(new TermsAggregationBuilder("t").field("dummy"), new MatchAllDocsQuery(), iw -> {
|
debugTestCase(new TermsAggregationBuilder("t").field("dummy"), new MatchAllDocsQuery(), iw -> {
|
||||||
for (int d = 0; d < totalDocs; d++) {
|
for (int d = 0; d < totalDocs; d++) {
|
||||||
BytesRef value = values[d % values.length];
|
BytesRef value = values[d % values.length];
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.apache.lucene.util.BytesRef;
|
||||||
import org.elasticsearch.common.geo.GeoPoint;
|
import org.elasticsearch.common.geo.GeoPoint;
|
||||||
import org.elasticsearch.common.geo.GeoUtils;
|
import org.elasticsearch.common.geo.GeoUtils;
|
||||||
import org.elasticsearch.index.mapper.GeoPointScriptFieldType;
|
import org.elasticsearch.index.mapper.GeoPointScriptFieldType;
|
||||||
|
import org.elasticsearch.index.mapper.OnScriptError;
|
||||||
import org.elasticsearch.script.AbstractLongFieldScript;
|
import org.elasticsearch.script.AbstractLongFieldScript;
|
||||||
import org.elasticsearch.script.GeoPointFieldScript;
|
import org.elasticsearch.script.GeoPointFieldScript;
|
||||||
import org.elasticsearch.script.Script;
|
import org.elasticsearch.script.Script;
|
||||||
|
@ -88,6 +89,7 @@ public class GeoPointScriptFieldDistanceFeatureQueryTests extends AbstractScript
|
||||||
"test",
|
"test",
|
||||||
Map.of(),
|
Map.of(),
|
||||||
searchLookup,
|
searchLookup,
|
||||||
|
OnScriptError.FAIL,
|
||||||
ctx
|
ctx
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -17,6 +17,7 @@ import org.apache.lucene.search.TopDocs;
|
||||||
import org.apache.lucene.store.Directory;
|
import org.apache.lucene.store.Directory;
|
||||||
import org.apache.lucene.tests.index.RandomIndexWriter;
|
import org.apache.lucene.tests.index.RandomIndexWriter;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
|
import org.elasticsearch.index.mapper.OnScriptError;
|
||||||
import org.elasticsearch.script.AbstractLongFieldScript;
|
import org.elasticsearch.script.AbstractLongFieldScript;
|
||||||
import org.elasticsearch.script.DateFieldScript;
|
import org.elasticsearch.script.DateFieldScript;
|
||||||
import org.elasticsearch.script.Script;
|
import org.elasticsearch.script.Script;
|
||||||
|
@ -75,6 +76,7 @@ public class LongScriptFieldDistanceFeatureQueryTests extends AbstractScriptFiel
|
||||||
Map.of(),
|
Map.of(),
|
||||||
searchLookup,
|
searchLookup,
|
||||||
null,
|
null,
|
||||||
|
OnScriptError.FAIL,
|
||||||
ctx
|
ctx
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -15,6 +15,7 @@ import org.apache.lucene.search.Rescorer;
|
||||||
import org.apache.lucene.search.Scorable;
|
import org.apache.lucene.search.Scorable;
|
||||||
import org.apache.lucene.search.SortField;
|
import org.apache.lucene.search.SortField;
|
||||||
import org.elasticsearch.common.util.Maps;
|
import org.elasticsearch.common.util.Maps;
|
||||||
|
import org.elasticsearch.index.mapper.OnScriptError;
|
||||||
import org.elasticsearch.index.query.IntervalFilterScript;
|
import org.elasticsearch.index.query.IntervalFilterScript;
|
||||||
import org.elasticsearch.index.similarity.ScriptedSimilarity.Doc;
|
import org.elasticsearch.index.similarity.ScriptedSimilarity.Doc;
|
||||||
import org.elasticsearch.index.similarity.ScriptedSimilarity.Field;
|
import org.elasticsearch.index.similarity.ScriptedSimilarity.Field;
|
||||||
|
@ -269,7 +270,13 @@ public class MockScriptEngine implements ScriptEngine {
|
||||||
IntervalFilterScript.Factory factory = mockCompiled::createIntervalFilterScript;
|
IntervalFilterScript.Factory factory = mockCompiled::createIntervalFilterScript;
|
||||||
return context.factoryClazz.cast(factory);
|
return context.factoryClazz.cast(factory);
|
||||||
} else if (context.instanceClazz.equals(BooleanFieldScript.class)) {
|
} else if (context.instanceClazz.equals(BooleanFieldScript.class)) {
|
||||||
BooleanFieldScript.Factory booleanFieldScript = (f, p, s) -> ctx -> new BooleanFieldScript(f, p, s, ctx) {
|
BooleanFieldScript.Factory booleanFieldScript = (f, p, s, onScriptError) -> ctx -> new BooleanFieldScript(
|
||||||
|
f,
|
||||||
|
p,
|
||||||
|
s,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emit(true);
|
emit(true);
|
||||||
|
@ -277,7 +284,13 @@ public class MockScriptEngine implements ScriptEngine {
|
||||||
};
|
};
|
||||||
return context.factoryClazz.cast(booleanFieldScript);
|
return context.factoryClazz.cast(booleanFieldScript);
|
||||||
} else if (context.instanceClazz.equals(StringFieldScript.class)) {
|
} else if (context.instanceClazz.equals(StringFieldScript.class)) {
|
||||||
StringFieldScript.Factory stringFieldScript = (f, p, s) -> ctx -> new StringFieldScript(f, p, s, ctx) {
|
StringFieldScript.Factory stringFieldScript = (f, p, s, onScriptError) -> ctx -> new StringFieldScript(
|
||||||
|
f,
|
||||||
|
p,
|
||||||
|
s,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emit("test");
|
emit("test");
|
||||||
|
@ -285,7 +298,13 @@ public class MockScriptEngine implements ScriptEngine {
|
||||||
};
|
};
|
||||||
return context.factoryClazz.cast(stringFieldScript);
|
return context.factoryClazz.cast(stringFieldScript);
|
||||||
} else if (context.instanceClazz.equals(LongFieldScript.class)) {
|
} else if (context.instanceClazz.equals(LongFieldScript.class)) {
|
||||||
LongFieldScript.Factory longFieldScript = (f, p, s) -> ctx -> new LongFieldScript(f, p, s, ctx) {
|
LongFieldScript.Factory longFieldScript = (f, p, s, onScriptError) -> ctx -> new LongFieldScript(
|
||||||
|
f,
|
||||||
|
p,
|
||||||
|
s,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emit(1L);
|
emit(1L);
|
||||||
|
@ -293,7 +312,13 @@ public class MockScriptEngine implements ScriptEngine {
|
||||||
};
|
};
|
||||||
return context.factoryClazz.cast(longFieldScript);
|
return context.factoryClazz.cast(longFieldScript);
|
||||||
} else if (context.instanceClazz.equals(DoubleFieldScript.class)) {
|
} else if (context.instanceClazz.equals(DoubleFieldScript.class)) {
|
||||||
DoubleFieldScript.Factory doubleFieldScript = (f, p, s) -> ctx -> new DoubleFieldScript(f, p, s, ctx) {
|
DoubleFieldScript.Factory doubleFieldScript = (f, p, s, onScriptError) -> ctx -> new DoubleFieldScript(
|
||||||
|
f,
|
||||||
|
p,
|
||||||
|
s,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emit(1.2D);
|
emit(1.2D);
|
||||||
|
@ -301,7 +326,14 @@ public class MockScriptEngine implements ScriptEngine {
|
||||||
};
|
};
|
||||||
return context.factoryClazz.cast(doubleFieldScript);
|
return context.factoryClazz.cast(doubleFieldScript);
|
||||||
} else if (context.instanceClazz.equals(DateFieldScript.class)) {
|
} else if (context.instanceClazz.equals(DateFieldScript.class)) {
|
||||||
DateFieldScript.Factory dateFieldScript = (f, p, s, formatter) -> ctx -> new DateFieldScript(f, p, s, formatter, ctx) {
|
DateFieldScript.Factory dateFieldScript = (f, p, s, formatter, onScriptError) -> ctx -> new DateFieldScript(
|
||||||
|
f,
|
||||||
|
p,
|
||||||
|
s,
|
||||||
|
formatter,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emit(123L);
|
emit(123L);
|
||||||
|
@ -309,7 +341,7 @@ public class MockScriptEngine implements ScriptEngine {
|
||||||
};
|
};
|
||||||
return context.factoryClazz.cast(dateFieldScript);
|
return context.factoryClazz.cast(dateFieldScript);
|
||||||
} else if (context.instanceClazz.equals(IpFieldScript.class)) {
|
} else if (context.instanceClazz.equals(IpFieldScript.class)) {
|
||||||
IpFieldScript.Factory ipFieldScript = (f, p, s) -> ctx -> new IpFieldScript(f, p, s, ctx) {
|
IpFieldScript.Factory ipFieldScript = (f, p, s, onScriptError) -> ctx -> new IpFieldScript(f, p, s, OnScriptError.FAIL, ctx) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emit("127.0.0.1");
|
emit("127.0.0.1");
|
||||||
|
@ -317,7 +349,13 @@ public class MockScriptEngine implements ScriptEngine {
|
||||||
};
|
};
|
||||||
return context.factoryClazz.cast(ipFieldScript);
|
return context.factoryClazz.cast(ipFieldScript);
|
||||||
} else if (context.instanceClazz.equals(GeoPointFieldScript.class)) {
|
} else if (context.instanceClazz.equals(GeoPointFieldScript.class)) {
|
||||||
GeoPointFieldScript.Factory geoPointFieldScript = (f, p, s) -> ctx -> new GeoPointFieldScript(f, p, s, ctx) {
|
GeoPointFieldScript.Factory geoPointFieldScript = (f, p, s, onScriptError) -> ctx -> new GeoPointFieldScript(
|
||||||
|
f,
|
||||||
|
p,
|
||||||
|
s,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emit(1.2D, 1.2D);
|
emit(1.2D, 1.2D);
|
||||||
|
@ -325,7 +363,13 @@ public class MockScriptEngine implements ScriptEngine {
|
||||||
};
|
};
|
||||||
return context.factoryClazz.cast(geoPointFieldScript);
|
return context.factoryClazz.cast(geoPointFieldScript);
|
||||||
} else if (context.instanceClazz.equals(CompositeFieldScript.class)) {
|
} else if (context.instanceClazz.equals(CompositeFieldScript.class)) {
|
||||||
CompositeFieldScript.Factory objectFieldScript = (f, p, s) -> ctx -> new CompositeFieldScript(f, p, s, ctx) {
|
CompositeFieldScript.Factory objectFieldScript = (f, p, s, onScriptError) -> ctx -> new CompositeFieldScript(
|
||||||
|
f,
|
||||||
|
p,
|
||||||
|
s,
|
||||||
|
OnScriptError.FAIL,
|
||||||
|
ctx
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
emit("field1", "value1");
|
emit("field1", "value1");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue