Uploaded image for project: 'Drools'
  1. Drools
  2. DROOLS-6064

Inconsistent behavior when accumulate function returns null

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Major Major
    • 7.53.0.Final
    • 7.50.0.Final
    • core engine
    • None
    • 2021 Week 10-12 (from Mar 8), 2021 Week 13-15 (from Mar 29)
    • 5
    • Undefined
    • NEW
    • NEW
    • ---
    • ---

      When you use accumulate and no fact matches, the behaviors are different depending on accumulate functions:

          rule "accumualte_rule_min"
            when
              accumulate( target : Target( target.getText() == "XXX" ),
                          $min : min( target.getNumber1() ) )
            then
              System.out.println("***** accumualte_rule_min: $min = " + $min);
          end
      

      min() : IntegerMinAccumulateFunction -> returns null if no fact matches
      max() : IntegerMaxAccumulateFunction -> returns null if no fact matches
      ave() : AverageAccumulateFunction -> returns null if no fact matches

      -> If the result is null, the rule won't fire.

      https://github.com/kiegroup/drools/blob/master/drools-core/src/main/java/org/drools/core/phreak/PhreakAccumulateNode.java#L620-L627

      count() : CountAccumulateFunction -> returns 0 if no fact matches
      sum() : IntegerSumAccumulateFunction -> returns 0 if no fact matches

      -> result is not null. So the rule is fired.

      min(), max() : When you have multiple functions in accumulate, MultiAccumulate is used. This returns Object[] which contains multiple results. In this case, result = Object[2] which is [null, null].

      https://github.com/kiegroup/drools/blob/master/drools-core/src/main/java/org/drools/core/rule/MultiAccumulate.java#L163-L177

      -> In this case, the result is not null. So the rule is fired with these "null" results.

      This JIRA is to make it consistent.

      Mark Proctor wrote:

      I always thought the behaviour was to propagate, regardless of the result of the accumulation. If there is a left input into the accumulation node, an accumulation of zero is still information we may need to process. If the users wishes to not propagate on an empty/null accumulation result, that should be in the guard.
      
      you can make a binding to a null field, and it works.
      I see accumulate bindings, akin to bindings on a field. they are not individual facts.
      when you insert into ksessio.insert(object) you insert a whole object, that is without relations at this stage. A field binding is a kind of relation, even if it's null - all fields are relations. What you cannot have is null without it being related to soemthing. For accumulate you have the subject (left input) you have the relation (max/min etc) you have the result - that result is a relation.
      
      It's about correctness. That an accumulate is empty or null, is still potentially interesting information.
      I think we first need to argue what is the behaviour we want. imho any accumulate binding is a relation, and we allow null relations - as it tells us something about the subject (that the relation is on).
      with regards to compatability, once we have decided on the the beheviour, we can add a kbase conf property to control the behaviour.
      anything that dosnt want null, can add a guard
      

              rhn-support-tkobayas Toshiya Kobayashi
              rhn-support-tkobayas Toshiya Kobayashi
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Created:
                Updated:
                Resolved: