painless: remove input, support params instead

This commit is contained in:
Robert Muir 2016-05-11 21:32:10 -04:00
parent 3b66d40f7c
commit 25dd64250b
13 changed files with 39 additions and 39 deletions

View File

@ -72,7 +72,7 @@ PUT hockey/player/_bulk?refresh
[float]
=== 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.
@ -85,7 +85,7 @@ GET hockey/_search
"script_score": {
"script": {
"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": {
"script": {
"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
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]
----------------------------------------------------------------
@ -131,7 +131,7 @@ GET hockey/_search
"order": "asc",
"script": {
"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]
=== 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:
@ -163,7 +163,7 @@ GET hockey/_search
----------------------------------------------------------------
// 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]
----------------------------------------------------------------
@ -171,7 +171,7 @@ POST hockey/player/1/_update
{
"script": {
"lang": "painless",
"inline": "input.ctx._source.last = input.last",
"inline": "ctx._source.last = params.last",
"params": {
"last": "hockey"
}
@ -189,7 +189,7 @@ POST hockey/player/1/_update
{
"script": {
"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": {
"last": "gaudreau",
"nick": "hockey"

View File

@ -94,10 +94,10 @@ class Analyzer extends PainlessParserBaseVisitor<Void> {
utility.incrementScope();
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
metadata.inputValueSlot = utility.addVariable(null, "input", definition.smapType).slot;
// input map of parameters passed to the script.
metadata.paramsValueSlot = utility.addVariable(null, "params", definition.smapType).slot;
// scorer parameter passed to the script. internal use only.
metadata.scorerValueSlot = utility.addVariable(null, "#scorer", definition.objectType).slot;
// doc parameter passed to the script.

View File

@ -49,5 +49,5 @@ public abstract class Executable {
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
* 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

View File

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

View File

@ -100,11 +100,11 @@ public class BasicExpressionTests extends ScriptTestCase {
*/
public void testBoxing() {
// return
assertEquals(4, exec("return input.get(\"x\");", Collections.singletonMap("x", 4)));
assertEquals(4, exec("return params.get(\"x\");", Collections.singletonMap("x", 4)));
// 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
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() {

View File

@ -46,12 +46,12 @@ public class ScriptEngineTests extends ScriptTestCase {
obj1.put("l", Arrays.asList("2", "1"));
vars.put("obj1", obj1);
Object value = exec("return input.get(\"obj1\");", vars);
Object value = exec("return params['obj1'];", vars);
obj1 = (Map<String, Object>)value;
assertEquals("value1", obj1.get("prop1"));
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);
}
@ -65,15 +65,15 @@ public class ScriptEngineTests extends ScriptTestCase {
obj1.put("obj2", obj2);
vars.put("l", Arrays.asList("1", "2", "3", obj1));
assertEquals(4, exec("return ((List)input.get(\"l\")).size();", vars));
assertEquals("1", exec("return ((List)input.get(\"l\")).get(0);", vars));
assertEquals(4, exec("return params.l.size();", 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;
assertEquals("value1", obj1.get("prop1"));
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() {
@ -82,7 +82,7 @@ public class ScriptEngineTests extends ScriptTestCase {
vars.put("ctx", ctx);
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,
"testChangingVarsCrossExecution1", "painless", compiledScript), vars);
@ -97,7 +97,7 @@ public class ScriptEngineTests extends ScriptTestCase {
public void testChangingVarsCrossExecution2() {
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,
"testChangingVarsCrossExecution2", "painless", compiledScript), vars);

View File

@ -26,7 +26,7 @@ import java.util.Collections;
public class WhenThingsGoWrongTests extends ScriptTestCase {
public void testNullPointer() {
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"
body:
lang: painless
script: "ctx._source.foo = input.bar"
script: "ctx._source.foo = params.bar"
params: { bar: 'xxx' }
- match: { _index: test_1 }

View File

@ -5,7 +5,7 @@
put_script:
id: "1"
lang: "painless"
body: { "script": "_score * doc[\"myParent.weight\"].value" }
body: { "script": "_score * doc['myParent.weight'].value" }
- match: { acknowledged: true }
- do:
@ -15,7 +15,7 @@
- match: { found: true }
- match: { lang: painless }
- match: { _id: "1" }
- match: { "script": "_score * doc[\"myParent.weight\"].value" }
- match: { "script": "_score * doc['myParent.weight'].value" }
- do:
catch: missing
@ -44,11 +44,11 @@
put_script:
id: "1"
lang: "painless"
body: { "script": "_score * foo bar + doc[\"myParent.weight\"].value" }
body: { "script": "_score * foo bar + doc['myParent.weight'].value" }
- do:
catch: /Unable.to.parse.*/
put_script:
id: "1"
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:
bar:
script:
inline: "doc['foo'].value + input.x;"
inline: "doc['foo'].value + params.x;"
lang: painless
params:
x: "bbb"

View File

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

View File

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