diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/SingleDrlxParseSuccess.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/SingleDrlxParseSuccess.java index d0557abdb54..fa85133a62d 100644 --- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/SingleDrlxParseSuccess.java +++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/SingleDrlxParseSuccess.java @@ -357,8 +357,26 @@ public boolean isPredicate() { return this.isPredicate; } + /* + * This method finds out, if the parse result is a predicate enclosed in parentheses, bound to a variable. + * Example: Person($booleanVariable: (name != null)) + * This shouldn't apply to any other form of predicate. So e.g. + * Person($booleanVariable: (name != null) == "someName") should be properly generated as a constraint. + * After discussions, to align the executable model behaviour with the old non-executable model, + * such predicate is not generated as a rule constraint, and just bound to a variable. This behaviour needs more + * discussions to revisit this behaviour. + */ + private boolean isEnclosedPredicateBoundToVariable() { + final TypedExpression boundExpr = getBoundExpr(); + return boundExpr != null + && boundExpr.getExpression() instanceof EnclosedExpr + && getExprBinding() != null + && !getLeft().getExpression().equals(boundExpr.getExpression()) + && !getRight().getExpression().equals(boundExpr.getExpression()); + } + public SingleDrlxParseSuccess setIsPredicate(boolean predicate) { - this.isPredicate = predicate; + this.isPredicate = predicate && !isEnclosedPredicateBoundToVariable(); return this; } diff --git a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/BindingTest.java b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/BindingTest.java index 83e0d3411d1..9512691161f 100644 --- a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/BindingTest.java +++ b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/BindingTest.java @@ -505,4 +505,39 @@ public void testConstraintExpression() { ksession.dispose(); } } + + /** + * This test checks that a rule is not fired, when a binding is + * enclosed in parentheses. This is intentional behaviour, agreed in discussions, + * which may be revised in the future. + */ + @Test + public void testIgnoreConstraintInParentheses() { + String str = "package constraintexpression\n" + + "\n" + + "import " + Person.class.getCanonicalName() + "\n" + + "import java.util.List; \n" + + "global List booleanListGlobal; \n" + + "rule \"r1\"\n" + + "when \n" + + " $p : Person($booleanVariable: (name == null))\n" + + "then \n" + + " System.out.println($booleanVariable); \n" + + " System.out.println($p); \n" + + " booleanListGlobal.add($booleanVariable); \n " + + "end \n"; + + KieSession ksession = getKieSession(str); + try { + final List booleanListGlobal = new ArrayList<>(); + ksession.setGlobal("booleanListGlobal", booleanListGlobal); + Person person = new Person("someName"); + ksession.insert(person); + int rulesFired = ksession.fireAllRules(); + assertThat(rulesFired).isEqualTo(1); + assertThat(booleanListGlobal).isNotEmpty().containsExactly(Boolean.FALSE); + } finally { + ksession.dispose(); + } + } }