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

   When an executable-model rule contains a top-level or(...) whose branch is a
     join containing a negation (and(not(x), y)), and a later pattern carries a
     temporal after constraint, the rule throws an NPE during fact evaluation. 
The
     DRL path is unaffected (its parser expands disjunctions into separate rules
     before compilation); the bug is specific to the model→KiePackage 
compilation
     path.
   
     Symptom
   ```
     org.drools.modelcompiler.constraints.ConstraintEvaluationException:
         Error evaluating constraint '' in  and in more rules
       at LambdaConstraint.isAllowedCachedLeft(LambdaConstraint.java:222)
       at SingleBetaConstraints.isAllowedCachedLeft(...)
       at PhreakJoinNode.doLeftInserts(PhreakJoinNode.java:118)
       ...
     Caused by: java.lang.NullPointerException:
         Cannot invoke "org.drools.core.reteoo.TupleImpl.getIndex()" because
     "entry" is null
       at org.drools.core.reteoo.TupleImpl.get(TupleImpl.java:274)
       at 
TemporalConstraintEvaluator.getBetaInvocationFactHandles(TemporalConstra
     intEvaluator.java:70)
       at
     TemporalConstraintEvaluator.evaluate(TemporalConstraintEvaluator.java:50)
   ```
     Minimal reproducer (executable model, STREAM)
   ```
     // Event types with @Role(EVENT): EvE, EvC, EvD
     Variable<EvE> e1 = declarationOf(EvE.class);
     Variable<EvE> e2 = declarationOf(EvE.class);
     Variable<EvC> c  = declarationOf(EvC.class);
     Variable<EvE> et = declarationOf(EvE.class);
     Variable<EvD> d  = declarationOf(EvD.class);
   
     Rule r = rule("min-or-negjoin-after").build(
         or(
             pattern(e1).expr("e1", v -> true),
             and(not(pattern(e2).expr("e2", v -> true)),   // OR branch is a
     negated join
                 pattern(c).expr("c", v -> true))
         ),
         pattern(et).expr("et", v -> true),
         pattern(d).expr("d", v -> true).expr("d_after_et", et, after()),  //
     downstream temporal beta
         execute(() -> {})
     );
   ```
     // build STREAM KieBase, insert a few events of each type, fireAllRules() 
->
     NPE
   
     Both ingredients are required (each removed individually makes it pass):
     - a bare or(pattern, pattern) does not trigger it,
     - a lone not(...) branch does not,
     - the negated join without the OR does not,
     - the OR + negated join without the downstream after does not.
   
     Root cause
   
     When the LHS or is expanded into per-branch subrules (LogicTransformer), 
the
     shared trailing elements (here ET and D after ET) are cloned into each
     subrule, and each clone's declarations are independently rebound to its own
     subrule's patterns via Constraint.replaceDeclaration (which reassigns a 
slot
     in the evaluator's declarations[] array).
   
     TemporalConstraintEvaluator.clone() passed the original declarations array 
by
     reference (getDeclarations()) instead of copying it, so all clones shared
     one array. The last subrule's rebinding therefore clobbered the others,
     leaving the narrow branch's D after ET pointing at the wide branch's ET
     pattern (tuple index 3) — an index absent from the narrow branch's 2-deep
     tuple, so TupleImpl.get walks off the parent chain and dereferences a null
     entry.
   
     (Equal-width OR branches mask the bug, since the shared index stays valid —
     which is why a plain or(pattern, pattern) doesn't reproduce.)


-- 
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