Example:
There is some inconsistency in the behavior of singleton list conversion for equalities and inequalities.
I'm using the programatic api in package: org.kie:kie-dmn-core:7.61.0.Final
Example code:
List<Map<String, Object>> myList = ImmutableList.of(
ImmutableMap.of("name", "name1", "value", BigDecimal.ONE),
ImmutableMap.of("name", "name2", "value", new BigDecimal(2)),
ImmutableMap.of("name", "name3", "value", new BigDecimal(3))
);
EvaluationContext evalContext = ((FEELImpl) feel).newEvaluationContext(
Collections.emptyList(), Collections.emptyMap());
evalContext.setValue("MY_LIST", myList);
// null because of EvalHelper.compare(). Should singleton list be converted in this case?
System.out.println(feel.evaluate("MY_LIST[name=\"name2\"].value >= 1", evalContext));
// true because of EvalHelper.isEqual(). This method does the conversion and returns true for 2 = 2.
System.out.println(feel.evaluate("MY_LIST[name=\"name2\"].value >= 2", evalContext));
// true because of EvalHelper.isEqual(). Same reason as above.
System.out.println(feel.evaluate("MY_LIST[name=\"name2\"].value = 2", evalContext));
// true because of manual conversion to first element
System.out.println(feel.evaluate("MY_LIST[name=\"name2\"].value[1] >= 1", evalContext));
---
Discussion:
Conversion of a singleton list to the value of the single element ([a] -> a) should take place any time a list is
not expected, as stated in the DMN 1.3 spec:
a singleton list L, when used in an expression where a list is not expected, behaves as if L[1] is written
Also, inequalities are not supported for list types as stated:
The other comparison operators are defined only for the
datatypes listed in Table 54 (does not include list type)
Since lists are not expected in inequalities, when a singleton list is compared to a value, should the singleton list be converted to its first element? There is ambiguity in DMN spec in regards to this, as it also states:
e1 and e2 must both be of the
same kind/datatype (is this pre or post conversion?)
Why is it converted for the equals scenario?
See call stack :
InfixOpNode.evaluate (case: GTE) ->
EvalHelper.compare() ->
EvalHelper.isEqual()
Thank you!!