Rikkola opened a new issue, #2338:
URL: https://github.com/apache/incubator-kie-issues/issues/2338

   Evaluating a rule with two subnetwork not nodes — not(and(...)), each with 
its own correlation memory — in an event-processing (STREAM) session throws a 
NullPointerException on the right-tuple delete path. Pure mainline: plain 
PatternDSL, no sequencing or temporal constructs.
   
   Stack trace
   ```
     java.lang.NullPointerException: Cannot invoke "...TupleList.remove(...)"
         because the return value of "...TupleImpl.getMemory()" is null
       at 
PhreakSubnetworkNotExistsNode.deleteRight(PhreakSubnetworkNotExistsNode.
     java:92)
       at PhreakSubnetworkNotExistsNode.doSubNetworkNode(...)
       at PhreakNotNode.doNode(...)
   ```
   Root cause
   
   In the right-delete loop, the code dereferences the right tuple's 
memoryunconditionally:
   ```
     // don't use matches here, as it may be null, if the LT was also being
     removed.
     rightTuple.getMemory().remove(rightTuple);
   ```
   Under this topology a subnetwork right tuple whose insert was staged then 
unstaged in the same evaluation cycle reaches the delete having never entered 
the matches list, so getMemory() is null and .remove(...) NPEs.
   
   The sibling PhreakNotNode.doRightDeletes already guards this exact case ("it 
may have been staged and never actually added"); the subnetwork variant 
(PhreakSubnetworkNotExistsNode / RuleNetworkEvaluatorImpl.doSubnetwork2) does 
not — its delete loop cancels the pending right INSERT (removeInsert) but then 
falls through and addDeletes it anyway, producing a phantom delete against null 
memory. This diverges from TupleSetsImpl.addDelete, which returns after an 
INSERT/DELETE clash.
   
   Conditions (all load-bearing)
   
   Dropping any of these stops the reproduction:
   
   - STREAM (EventProcessingOption.STREAM) — CLOUD mode does not reproduce.
   - Two subnetwork not(and(...)) nodes, each with its own correlation memory.
   - Event-role facts.
   
   Reproducer
   
   PatternDSL rule, two event types, STREAM mode:
   ```
     Rule rule = rule("twoSubnetworkNots").build(
             not(and(pattern(eventA1).expr(x -> true), pattern(eventB1).expr(x 
->
     true))),
             not(and(pattern(eventA2).expr(x -> true), pattern(eventB2).expr(x 
->
     true))),
             execute(() -> { }));
   
     KieBase kieBase = KieBaseBuilder.createKieBaseFromModel(
             new ModelImpl().addRule(rule), EventProcessingOption.STREAM);
   
     KieSession ksession = kieBase.newKieSession();
     ksession.insert(new EventA(0)); ksession.fireAllRules();
     ksession.insert(new EventB(1)); ksession.fireAllRules();  // NPE here
   ```
   (Distilled from a randomized sequencing stress harness — MODEL_AFTER 
reference path, shape 46/seed 42.)
   
   Environment
   
   - Affects drools-core Phreak runtime.
   
   Suggested fix
   
   Guard the null memory in the subnetwork delete path, mirroring 
PhreakNotNode.doRightDeletes; or have doSubnetwork2's delete loop return after 
the INSERT/DELETE clash (skip the phantom addDelete) as TupleSetsImpl.addDelete 
does. A passing-condition regression test should cover two subnetwork nots in 
STREAM mode.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to