Accessing input value FEEL filter expression

Hi, I am playing around with DMN engine and FEEL expressions. Per the documentation here for Unary test expressions can use ? to represent the input value in expressions e.g.

ends with(?, "@camunda.com")

Can a ? be used in a filter expression as well ? e.g. is the following allowed ?

count(?[list contains([\"A\",\"B\",\"C\",\"D\"], item)])

When I try to do this I get a runtime error. However if I use the input variable name this works (e.g. here packages is the input name in the decision table).

count(packages[list contains([\"A\",\"B\",\"C\",\"D\"], item)])

Can ? be used as a placeholder for the input variable in filter expressions? If not are there any other alternative placeholders?

Hi @venkyvb :wave:

Where do you use this expression?
It doesn’t look like a unary-test that is used for an input entry.

Please share your DMN.

Best regards,
Philipp

Thanks for the response @Philipp_Ossler !!
Here is the DMN which has the actual input value (packages) in the FEEL filter expression. This works:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<definitions id="definition_countTest1" name="definition_countTest1" namespace="http://camunda.org/schema/1.0/dmn" xmlns="http://www.omg.org/spec/DMN/20151101/dmn.xsd">
  <decision id="decision_countTest1" name="decision_countTest1">
    <decisionTable hitPolicy="UNIQUE" id="decisionTable_84113164-d700-4946-9e84-140f0dc76221">
      <input id="input_ecab2024-cae1-4c5d-8fd3-ce40d045e58f" label="packages">
        <inputExpression id="inputExpression_34d159d9-f8ec-4f76-9ebd-3e405b84880c" typeRef="string">
          <text>packages</text>
        </inputExpression>
      </input>
      <input id="input_5cbbe120-aa01-4208-8318-421f743f1277" label="term">
        <inputExpression id="inputExpression_9bd3f966-1cf9-4ab4-94e3-56e2d92bc468" typeRef="long">
          <text>term</text>
        </inputExpression>
      </input>
      <output id="output_c10cf44c-89de-421e-8408-75eb625630ec" label="bundle" name="bundle" typeRef="string"/>
      <rule id="rule_fd8f89da-5a2e-4e50-a3b7-cb4d5eb6da6b">
        <inputEntry id="inputEntry_5bbeb617-99da-4432-b3a6-3932549217d7">
          <text>count(packages[list contains(["P1","P2","P3","P4"], item)]) = 1</text>
        </inputEntry>
        <inputEntry id="inputEntry_6028eab6-df35-406a-bc35-091c30cd9a0f">
          <text>&gt;=24</text>
        </inputEntry>
        <outputEntry id="outputEntry_ad0e5aee-4e84-4ed5-a9c0-d81f7b2b620d">
          <text>"B1"</text>
        </outputEntry>
      </rule>
      <rule id="rule_eced9637-2add-48a9-bade-74168146f638">
        <inputEntry id="inputEntry_f99be31c-c4c1-43d0-b433-d35edb215ca5">
          <text>count(packages[list contains(["P1","P2","P3","P4"], item)]) = 2</text>
        </inputEntry>
        <inputEntry id="inputEntry_1698b701-58d7-4543-96f6-674ecebf89aa">
          <text>&gt;=24</text>
        </inputEntry>
        <outputEntry id="outputEntry_0dad1582-0b56-4145-9001-3d8ffd4e897b">
          <text>"B2"</text>
        </outputEntry>
      </rule>
    </decisionTable>
  </decision>
</definitions>

But if I change the expression to count(?[list contains(["P1","P2","P3","P4"], item)]) = 1, then I get a runtime error.

Exception in thread "main" org.camunda.bpm.dmn.feel.impl.FeelException: FEEL/SCALA-01008 Error while evaluating expression: failed to evaluate expression 'count(?[list contains(["P1","P2","P3","P4"], item)]) = 1': expect List but found 'ValString([P1, P2])'
        at org.camunda.bpm.dmn.feel.impl.scala.ScalaFeelLogger.evaluationException(ScalaFeelLogger.java:77)
        at org.camunda.bpm.dmn.feel.impl.scala.ScalaFeelEngine.evaluateSimpleUnaryTests(ScalaFeelEngine.java:115)
        at org.camunda.bpm.dmn.engine.impl.evaluation.DecisionTableEvaluationHandler.evaluateFeelSimpleUnaryTests(DecisionTableEvaluationHandler.java:246)
        at org.camunda.bpm.dmn.engine.impl.evaluation.DecisionTableEvaluationHandler.evaluateInputEntry(DecisionTableEvaluationHandler.java:203)
        at org.camunda.bpm.dmn.engine.impl.evaluation.DecisionTableEvaluationHandler.isConditionApplicable(DecisionTableEvaluationHandler.java:145)
        at org.camunda.bpm.dmn.engine.impl.evaluation.DecisionTableEvaluationHandler.evaluateInputForAvailableRules(DecisionTableEvaluationHandler.java:137)
        at org.camunda.bpm.dmn.engine.impl.evaluation.DecisionTableEvaluationHandler.evaluateDecisionTable(DecisionTableEvaluationHandler.java:111)
        at org.camunda.bpm.dmn.engine.impl.evaluation.DecisionTableEvaluationHandler.evaluate(DecisionTableEvaluationHandler.java:81)
        at org.camunda.bpm.dmn.engine.impl.DefaultDmnDecisionContext.evaluateDecision(DefaultDmnDecisionContext.java:85)
        at org.camunda.bpm.dmn.engine.impl.DefaultDmnEngine.evaluateDecisionTable(DefaultDmnEngine.java:115)
        at org.camunda.bpm.dmn.engine.impl.DefaultDmnEngine.evaluateDecisionTable(DefaultDmnEngine.java:105)

Here is the corresponding DMN (where ? is used):

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<definitions id="definition_countTest1" name="definition_countTest1" namespace="http://camunda.org/schema/1.0/dmn" xmlns="http://www.omg.org/spec/DMN/20151101/dmn.xsd">
  <decision id="decision_countTest1" name="decision_countTest1">
    <decisionTable hitPolicy="UNIQUE" id="decisionTable_c6875a44-7492-4e5b-868c-9d58dd9d18e4">
      <input id="input_eb2c3e84-9144-4540-8d97-2a6bdaa35f81" label="packages">
        <inputExpression id="inputExpression_87f0d243-7608-4555-be4d-2f347f6b95d8" typeRef="string">
          <text>packages</text>
        </inputExpression>
      </input>
      <input id="input_a31351b0-8578-4abc-bf38-97b442ee29cd" label="term">
        <inputExpression id="inputExpression_a26994c4-64f4-4402-bbc1-b710e0297371" typeRef="long">
          <text>term</text>
        </inputExpression>
      </input>
      <output id="output_6c2a010d-c633-4da6-b384-32aee7e720f1" label="bundle" name="bundle" typeRef="string"/>
      <rule id="rule_f8b9b777-cd24-44e7-a518-20a6bb5cfacd">
        <inputEntry id="inputEntry_7bc80029-dfc4-484c-bb2d-d5444bb9df60">
          <text>count(?[list contains(["P1","P2","P3","P4"], item)]) = 1</text>
        </inputEntry>
        <inputEntry id="inputEntry_1b8bcd0f-f470-40c7-b92b-5e5e83c5a32f">
          <text>&gt;=24</text>
        </inputEntry>
        <outputEntry id="outputEntry_fcc0e9cf-2329-4360-b31e-8e4d7f6b5219">
          <text>"B1"</text>
        </outputEntry>
      </rule>
      <rule id="rule_993194bb-a7aa-48e9-a149-4741f8856752">
        <inputEntry id="inputEntry_1ea691a9-c87f-49ae-bab7-41312e9605ef">
          <text>count(?[list contains(["P1","P2","P3","P4"], item)]) = 2</text>
        </inputEntry>
        <inputEntry id="inputEntry_b9885aba-2ca2-48d7-8fdc-4b284ddb6c52">
          <text>&gt;=24</text>
        </inputEntry>
        <outputEntry id="outputEntry_05bcd623-5891-4178-9fb5-9f85f9546b7c">
          <text>"B2"</text>
        </outputEntry>
      </rule>
    </decisionTable>
  </decision>
</definitions>

Thanks for sharing.

The failure message gives a hint that the input value is a string. And it is true.

The type definition of the input is set to string. So, the list is converted to a string before it is passed as the input value.

Set the type to list (or something else) to disable the type conversion.

The expression works if the variable packages is referenced directly because it doesn’t use the converted input value.

Does this help you?

Awesome, that helps !! I missed that. When I change the InputType to list it works.
Thank you !!

One follow-up though, when I use the list I get the warning
WARNING: DMN-01006 Unsupported type 'list' for clause. Values of this clause will not transform into another type.
Is there a way to address this warning?

You could implement and register a custom data type. In the transformer, you could check if the value is of the given type.

However, it would be nice if all FEEL data types would be supported by default. Feel free to create an issue.

Thanks for the input. Will open an issue.

Question around a different variant of the FEEL expression - instead of doing a count check e.g. count(?[list contains(["P1","P2","P3","P4"], item)]) = 1, I would like to do a simple list contains, but would like to check against each item in the input. I tried the following variations and none of these seem to work. e.g. list contains(["P1","P2","P3","P4"], ?). Similar to the count where ? is used to bind the input value, is there a way to check against the input values with the list contains ?

Of course a workaround would be to use count > 0 like this count(?[list contains(["P1","P2","P3","P4"], item)]) > 0 as a proxy for contains :slight_smile: . Wondering if there is a better way of doing this with just list contains.

The list contains() function expects a single item as second argument.

Assuming that you have an input like ["P1","P2"] (a list of two string values) then you could use the following unary-tests expression to check if the list contains one of the given elements:

some x in ? satisfies list contains(["P1","P2","P3","P4"], x)

Does this help you?

1 Like

A follow-up question. I have the following unary-test expression

some x in ? satisfies list contains(["P1","P2","P3","P4"], x)

Say the input is [“P1”, “P5”, “P6”]. Since there is a match the expression evaluates to true.
In the output, if I want to send the list of input entries that matched the expression, in this example [“P1”], how can this be done using FEEL expression ? (from the docs it seems like we can use FEEL for output expressions as well, however it is not clear as to how we can access the input values to populate the results).

Hi @venkyvb :wave:

Assuming that you have a decision table and want to return the list as an output.

You could use a filter expression on the variable that is used in the input expression.
Assuming that the variable is called input:

input[list contains(["P1","P2","P3","P4"], item)]

The expression returns ["P1"].

Does this help you?

1 Like

@Philipp_Ossler :wave: - Just tested this and it works perfectly :+1: !! Thank you for the suggestion.