support scoped params with unscoped op fields

This commit is contained in:
Jonathan Shook 2022-03-02 10:01:23 -06:00
parent 98c5042d5a
commit 5c3306a168
4 changed files with 87 additions and 9 deletions

View File

@ -18,6 +18,7 @@
package io.nosqlbench.engine.api.activityconfig.rawyaml;
import io.nosqlbench.nb.api.errors.BasicError;
import io.nosqlbench.nb.api.errors.OpConfigError;
import java.util.*;
@ -41,12 +42,15 @@ public class RawStmtDef extends RawStmtFields {
@SuppressWarnings("unchecked")
public RawStmtDef(String defaultName, Map<String, Object> map) {
setFieldsByReflection(map);
if (this.getName() == null || this.getName().isEmpty()) {
this.setName(defaultName);
}
}
public void setFieldsByReflection(Map<String, Object> map) {
checkForUnintendedJsonMap(map, new ArrayList<>());
super.setFieldsByReflection(map);
HashSet<String> found = new HashSet<>();
for (String opName : opFieldSynonyms) {
if (map.containsKey(opName)) {
@ -67,14 +71,19 @@ public class RawStmtDef extends RawStmtFields {
boolean _params = !getParams().isEmpty();
boolean _op = op != null;
if (!_op && !_params) {
LinkedHashMap<String, Object> newop = new LinkedHashMap<>();
newop.putAll(map);
if (_op) {
if (_params) {
if (map.size() > 0) {
throw new OpConfigError("If you have scoped op and params, you may not have dangling fields.");
}
} else { // no params. Op was a scoped field and there are dangling fields, so assume they belong to params
getParams().putAll(map);
map.clear();
}
} else { // no op, so assume all remaining fields belong to the op
LinkedHashMap<String, Object> newop = new LinkedHashMap<>(map);
setOp(newop);
map.clear();
} else if (_op) {
getParams().putAll(map);
map.clear();
}
}
@ -105,4 +114,23 @@ public class RawStmtDef extends RawStmtFields {
}
return super.getName();
}
private void checkForUnintendedJsonMap(Object m, List<String> path) {
if (m instanceof Map) {
((Map)m).forEach((k,v) -> {
if (v == null) {
throw new OpConfigError("A map key '" + k.toString() + "' with a null value was encountered. This is not" +
" allowed, and may be the result of using an unquoted binding, like {" + k + "}. You can simply wrap this in quotes" +
" like \"{"+ k +"\"} to avoid interpreting this as a JSON map." +
(path.size()>0 ? String.join(".",path):""));
} else {
if (v instanceof Map) {
path.add(k.toString());
checkForUnintendedJsonMap(v, path);
}
}
});
}
}
}

View File

@ -146,6 +146,56 @@ ops:
]
```
### Anonymous fields may include scoped params
*yaml:*
```yaml
ops:
op1:
field1: select * from ks1.tb1;
field2: field 2 value
params:
paramname1: paramvalue1
```
*json:*
```json5
{
"ops": {
"op1": {
"field1": "select * from ks1.tb1;",
"field2": "field 2 value",
"params": {
"paramname1": "paramvalue1"
}
}
}
}
```
*ops:*
```json5
[
{
"name": "block0--op1",
"op": {
"field1": "select * from ks1.tb1;",
"field2": "field 2 value"
},
params: {
"paramname1": "paramvalue1"
},
"tags": {
"block": "block0",
"name": "block0--op1"
}
}
]
```
### Scoped op fields allow dangling param values
*yaml:*

View File

@ -74,7 +74,7 @@ public class StmtDetailOverrideTest {
assertThat(s.getTags()).containsEntry("tname1", "tval1");
assertThat(s.getTags()).containsEntry("global_tag1", "tag value");
assertThat(s.getBindings()).hasSize(3);
assertThat(s.getParams()).hasSize(3);
assertThat(s.getParams()).hasSize(2);
s = stmts.get(3);
assertThat(s.getName()).isEqualTo("testblock1--s4");

View File

@ -15,7 +15,7 @@ blocks:
global_param1: anothervalue
tags:
tname1: tval1
freeparam1: "free parameter value"
# freeparam1: "free parameter value"
- name: s4
stmt: statement 4