Merge pull request #18287 from rmuir/input_goes_params

painless: remove input, support params instead
This commit is contained in:
Robert Muir 2016-05-11 21:45:07 -04:00
commit d3142e3416
13 changed files with 39 additions and 39 deletions

View File

@ -72,7 +72,7 @@ PUT hockey/player/_bulk?refresh
[float] [float]
=== Accessing Doc Values from Painless === Accessing Doc Values from Painless
All Painless scripts take in a `Map<String,def>` of values called `input`. Document values can be accessed through another `Map<String,def>` within the `input` variable. Document values can be accessed from a `Map<String,def>` named `doc`.
For example, the following script calculates a player's total goals. This example uses a strongly typed `int` and a `for` loop. For example, the following script calculates a player's total goals. This example uses a strongly typed `int` and a `for` loop.
@ -85,7 +85,7 @@ GET hockey/_search
"script_score": { "script_score": {
"script": { "script": {
"lang": "painless", "lang": "painless",
"inline": "int total = 0; for (int i = 0; i < input.doc['goals'].size(); ++i) { total += input.doc['goals'][i]; } return total;" "inline": "int total = 0; for (int i = 0; i < doc['goals'].length; ++i) { total += doc['goals'][i]; } return total;"
} }
} }
} }
@ -107,7 +107,7 @@ GET hockey/_search
"total_goals": { "total_goals": {
"script": { "script": {
"lang": "painless", "lang": "painless",
"inline": "int total = 0; for (int i = 0; i < input.doc['goals'].size(); ++i) { total += input.doc['goals'][i]; } return total;" "inline": "int total = 0; for (int i = 0; i < doc['goals'].length; ++i) { total += doc['goals'][i]; } return total;"
} }
} }
} }
@ -116,7 +116,7 @@ GET hockey/_search
// CONSOLE // CONSOLE
The following example uses a Painless script to sort the players by their combined first and last names. The names are accessed using The following example uses a Painless script to sort the players by their combined first and last names. The names are accessed using
`input.doc['first'].value` and `input.doc['last'].value`. `doc['first'].value` and `doc['last'].value`.
[source,js] [source,js]
---------------------------------------------------------------- ----------------------------------------------------------------
@ -131,7 +131,7 @@ GET hockey/_search
"order": "asc", "order": "asc",
"script": { "script": {
"lang": "painless", "lang": "painless",
"inline": "input.doc['first'].value + ' ' + input.doc['last'].value" "inline": "doc['first'].value + ' ' + doc['last'].value"
} }
} }
} }
@ -142,7 +142,7 @@ GET hockey/_search
[float] [float]
=== Updating Fields with Painless === Updating Fields with Painless
You can also easily update fields. You access the original source for a field as `input.ctx._source.<field-name>`. You can also easily update fields. You access the original source for a field as `ctx._source.<field-name>`.
First, let's look at the source data for a player by submitting the following request: First, let's look at the source data for a player by submitting the following request:
@ -163,7 +163,7 @@ GET hockey/_search
---------------------------------------------------------------- ----------------------------------------------------------------
// CONSOLE // CONSOLE
To change player 1's last name to `hockey`, simply set `input.ctx._source.last` to the new value: To change player 1's last name to `hockey`, simply set `ctx._source.last` to the new value:
[source,js] [source,js]
---------------------------------------------------------------- ----------------------------------------------------------------
@ -171,7 +171,7 @@ POST hockey/player/1/_update
{ {
"script": { "script": {
"lang": "painless", "lang": "painless",
"inline": "input.ctx._source.last = input.last", "inline": "ctx._source.last = params.last",
"params": { "params": {
"last": "hockey" "last": "hockey"
} }
@ -189,7 +189,7 @@ POST hockey/player/1/_update
{ {
"script": { "script": {
"lang": "painless", "lang": "painless",
"inline": "input.ctx._source.last = input.last input.ctx._source.nick = input.nick", "inline": "ctx._source.last = params.last ctx._source.nick = params.nick",
"params": { "params": {
"last": "gaudreau", "last": "gaudreau",
"nick": "hockey" "nick": "hockey"

View File

@ -94,10 +94,10 @@ class Analyzer extends PainlessParserBaseVisitor<Void> {
utility.incrementScope(); utility.incrementScope();
utility.addVariable(null, "#this", definition.execType); utility.addVariable(null, "#this", definition.execType);
// //
// reserved words parameters. // reserved words.
// //
// input map of variables passed to the script. TODO: rename to 'params' since that will be its use // input map of parameters passed to the script.
metadata.inputValueSlot = utility.addVariable(null, "input", definition.smapType).slot; metadata.paramsValueSlot = utility.addVariable(null, "params", definition.smapType).slot;
// scorer parameter passed to the script. internal use only. // scorer parameter passed to the script. internal use only.
metadata.scorerValueSlot = utility.addVariable(null, "#scorer", definition.objectType).slot; metadata.scorerValueSlot = utility.addVariable(null, "#scorer", definition.objectType).slot;
// doc parameter passed to the script. // doc parameter passed to the script.

View File

@ -49,5 +49,5 @@ public abstract class Executable {
return definition; return definition;
} }
public abstract Object execute(Map<String, Object> input, Scorer scorer, LeafDocLookup doc, Object value); public abstract Object execute(Map<String, Object> params, Scorer scorer, LeafDocLookup doc, Object value);
} }

View File

@ -408,7 +408,7 @@ class Metadata {
* Used to determine what slot the input variable is stored in. This is used in the {@link Writer} whenever * Used to determine what slot the input variable is stored in. This is used in the {@link Writer} whenever
* the input variable is accessed. * the input variable is accessed.
*/ */
int inputValueSlot = -1; int paramsValueSlot = -1;
/** /**
* Used to determine what slot the Scorer variable is stored in. This is used in the {@link Writer} to load * Used to determine what slot the Scorer variable is stored in. This is used in the {@link Writer} to load

View File

@ -162,7 +162,7 @@ class Writer extends PainlessParserBaseVisitor<Void> {
if (metadata.ctxValueUsed) { if (metadata.ctxValueUsed) {
// if the _ctx value is used, we do this once: // if the _ctx value is used, we do this once:
// final Map<String,Object> ctx = input.get("ctx"); // final Map<String,Object> ctx = input.get("ctx");
execute.visitVarInsn(Opcodes.ALOAD, metadata.inputValueSlot); execute.visitVarInsn(Opcodes.ALOAD, metadata.paramsValueSlot);
execute.push("ctx"); execute.push("ctx");
execute.invokeInterface(WriterConstants.MAP_TYPE, WriterConstants.MAP_GET); execute.invokeInterface(WriterConstants.MAP_TYPE, WriterConstants.MAP_GET);
execute.visitVarInsn(Opcodes.ASTORE, metadata.ctxValueSlot); execute.visitVarInsn(Opcodes.ASTORE, metadata.ctxValueSlot);

View File

@ -100,11 +100,11 @@ public class BasicExpressionTests extends ScriptTestCase {
*/ */
public void testBoxing() { public void testBoxing() {
// return // return
assertEquals(4, exec("return input.get(\"x\");", Collections.singletonMap("x", 4))); assertEquals(4, exec("return params.get(\"x\");", Collections.singletonMap("x", 4)));
// assignment // assignment
assertEquals(4, exec("int y = (Integer)input.get(\"x\"); return y;", Collections.singletonMap("x", 4))); assertEquals(4, exec("int y = (Integer)params.get(\"x\"); return y;", Collections.singletonMap("x", 4)));
// comparison // comparison
assertEquals(true, exec("return 5 > (Integer)input.get(\"x\");", Collections.singletonMap("x", 4))); assertEquals(true, exec("return 5 > (Integer)params.get(\"x\");", Collections.singletonMap("x", 4)));
} }
public void testBool() { public void testBool() {

View File

@ -46,12 +46,12 @@ public class ScriptEngineTests extends ScriptTestCase {
obj1.put("l", Arrays.asList("2", "1")); obj1.put("l", Arrays.asList("2", "1"));
vars.put("obj1", obj1); vars.put("obj1", obj1);
Object value = exec("return input.get(\"obj1\");", vars); Object value = exec("return params['obj1'];", vars);
obj1 = (Map<String, Object>)value; obj1 = (Map<String, Object>)value;
assertEquals("value1", obj1.get("prop1")); assertEquals("value1", obj1.get("prop1"));
assertEquals("value2", ((Map<String, Object>) obj1.get("obj2")).get("prop2")); assertEquals("value2", ((Map<String, Object>) obj1.get("obj2")).get("prop2"));
value = exec("return ((List)((Map<String, Object>)input.get(\"obj1\")).get(\"l\")).get(0);", vars); value = exec("return params.obj1.l.0;", vars);
assertEquals("2", value); assertEquals("2", value);
} }
@ -65,15 +65,15 @@ public class ScriptEngineTests extends ScriptTestCase {
obj1.put("obj2", obj2); obj1.put("obj2", obj2);
vars.put("l", Arrays.asList("1", "2", "3", obj1)); vars.put("l", Arrays.asList("1", "2", "3", obj1));
assertEquals(4, exec("return ((List)input.get(\"l\")).size();", vars)); assertEquals(4, exec("return params.l.size();", vars));
assertEquals("1", exec("return ((List)input.get(\"l\")).get(0);", vars)); assertEquals("1", exec("return params.l.0;", vars));
Object value = exec("return ((List)input.get(\"l\")).get(3);", vars); Object value = exec("return params.l.3;", vars);
obj1 = (Map<String, Object>)value; obj1 = (Map<String, Object>)value;
assertEquals("value1", obj1.get("prop1")); assertEquals("value1", obj1.get("prop1"));
assertEquals("value2", ((Map<String, Object>)obj1.get("obj2")).get("prop2")); assertEquals("value2", ((Map<String, Object>)obj1.get("obj2")).get("prop2"));
assertEquals("value1", exec("return ((Map<String, Object>)((List)input.get(\"l\")).get(3)).get(\"prop1\");", vars)); assertEquals("value1", exec("return params.l.3.prop1;", vars));
} }
public void testChangingVarsCrossExecution1() { public void testChangingVarsCrossExecution1() {
@ -82,7 +82,7 @@ public class ScriptEngineTests extends ScriptTestCase {
vars.put("ctx", ctx); vars.put("ctx", ctx);
Object compiledScript = scriptEngine.compile( Object compiledScript = scriptEngine.compile(
"return ((Map<String, Object>)input.get(\"ctx\")).get(\"value\");", Collections.emptyMap()); "return ctx.value;", Collections.emptyMap());
ExecutableScript script = scriptEngine.executable(new CompiledScript(ScriptService.ScriptType.INLINE, ExecutableScript script = scriptEngine.executable(new CompiledScript(ScriptService.ScriptType.INLINE,
"testChangingVarsCrossExecution1", "painless", compiledScript), vars); "testChangingVarsCrossExecution1", "painless", compiledScript), vars);
@ -97,7 +97,7 @@ public class ScriptEngineTests extends ScriptTestCase {
public void testChangingVarsCrossExecution2() { public void testChangingVarsCrossExecution2() {
Map<String, Object> vars = new HashMap<>(); Map<String, Object> vars = new HashMap<>();
Object compiledScript = scriptEngine.compile("return input.get(\"value\");", Collections.emptyMap()); Object compiledScript = scriptEngine.compile("return params['value'];", Collections.emptyMap());
ExecutableScript script = scriptEngine.executable(new CompiledScript(ScriptService.ScriptType.INLINE, ExecutableScript script = scriptEngine.executable(new CompiledScript(ScriptService.ScriptType.INLINE,
"testChangingVarsCrossExecution2", "painless", compiledScript), vars); "testChangingVarsCrossExecution2", "painless", compiledScript), vars);

View File

@ -26,7 +26,7 @@ import java.util.Collections;
public class WhenThingsGoWrongTests extends ScriptTestCase { public class WhenThingsGoWrongTests extends ScriptTestCase {
public void testNullPointer() { public void testNullPointer() {
expectThrows(NullPointerException.class, () -> { expectThrows(NullPointerException.class, () -> {
exec("int x = (int) ((Map) input).get(\"missing\"); return x;"); exec("int x = params['missing']; return x;");
}); });
} }

View File

@ -18,7 +18,7 @@
script: "1" script: "1"
body: body:
lang: painless lang: painless
script: "ctx._source.foo = input.bar" script: "ctx._source.foo = params.bar"
params: { bar: 'xxx' } params: { bar: 'xxx' }
- match: { _index: test_1 } - match: { _index: test_1 }

View File

@ -5,7 +5,7 @@
put_script: put_script:
id: "1" id: "1"
lang: "painless" lang: "painless"
body: { "script": "_score * doc[\"myParent.weight\"].value" } body: { "script": "_score * doc['myParent.weight'].value" }
- match: { acknowledged: true } - match: { acknowledged: true }
- do: - do:
@ -15,7 +15,7 @@
- match: { found: true } - match: { found: true }
- match: { lang: painless } - match: { lang: painless }
- match: { _id: "1" } - match: { _id: "1" }
- match: { "script": "_score * doc[\"myParent.weight\"].value" } - match: { "script": "_score * doc['myParent.weight'].value" }
- do: - do:
catch: missing catch: missing
@ -44,11 +44,11 @@
put_script: put_script:
id: "1" id: "1"
lang: "painless" lang: "painless"
body: { "script": "_score * foo bar + doc[\"myParent.weight\"].value" } body: { "script": "_score * foo bar + doc['myParent.weight'].value" }
- do: - do:
catch: /Unable.to.parse.*/ catch: /Unable.to.parse.*/
put_script: put_script:
id: "1" id: "1"
lang: "painless" lang: "painless"
body: { "script": "_score * foo bar + doc[\"myParent.weight\"].value" } body: { "script": "_score * foo bar + doc['myParent.weight'].value" }

View File

@ -28,7 +28,7 @@ setup:
script_fields: script_fields:
bar: bar:
script: script:
inline: "doc['foo'].value + input.x;" inline: "doc['foo'].value + params.x;"
lang: painless lang: painless
params: params:
x: "bbb" x: "bbb"

View File

@ -7,7 +7,7 @@
type: test type: test
id: 1 id: 1
body: body:
script: "ctx._source.foo = input.bar" script: "ctx._source.foo = params.bar"
lang: "painless" lang: "painless"
params: { bar: 'xxx' } params: { bar: 'xxx' }
upsert: { foo: baz } upsert: { foo: baz }
@ -27,7 +27,7 @@
type: test type: test
id: 1 id: 1
body: body:
script: "ctx._source.foo = input.bar" script: "ctx._source.foo = params.bar"
lang: "painless" lang: "painless"
params: { bar: 'xxx' } params: { bar: 'xxx' }
upsert: { foo: baz } upsert: { foo: baz }
@ -46,7 +46,7 @@
type: test type: test
id: 2 id: 2
body: body:
script: "ctx._source.foo = input.bar" script: "ctx._source.foo = params.bar"
lang: "painless" lang: "painless"
params: { bar: 'xxx' } params: { bar: 'xxx' }
upsert: { foo: baz } upsert: { foo: baz }

View File

@ -51,7 +51,7 @@
query: query:
script: script:
script: script:
inline: "doc['num1'].value > input.param1;" inline: "doc['num1'].value > params.param1;"
lang: painless lang: painless
params: params:
param1: 1 param1: 1
@ -76,7 +76,7 @@
query: query:
script: script:
script: script:
inline: "doc['num1'].value > input.param1;" inline: "doc['num1'].value > params.param1;"
lang: painless lang: painless
params: params:
param1: -1 param1: -1
@ -236,7 +236,7 @@
"script_score": { "script_score": {
"script": { "script": {
"lang": "painless", "lang": "painless",
"inline": "input.param1 * input.param2 * _score", "inline": "params.param1 * params.param2 * _score",
"params": { "params": {
"param1": 2, "param1": 2,
"param2": 2 "param2": 2