This is an automated email from the ASF dual-hosted git repository.

yesamer pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie.git


The following commit(s) were added to refs/heads/main by this push:
     new 9b055f0c6c9 [incubator-kie#7144] fix(drools): keep contains on a 
generic Map.get() String matching after jitting (#7145)
9b055f0c6c9 is described below

commit 9b055f0c6c94287602c4bdc9e29de4308d42ed72
Author: Andrii Tsepukh <[email protected]>
AuthorDate: Wed Sep 30 10:10:11 2026 +0200

    [incubator-kie#7144] fix(drools): keep contains on a generic Map.get() 
String matching after jitting (#7145)
    
    PatternBuilder resolves Map<K, String>.get(...) to String from the
    generics, so the build accepts `contains` on it. The interpreted MVEL
    evaluator then does a substring check on the runtime String. Once the
    constraint is jitted, ASMConditionEvaluatorJitter sees the erased
    Object type and emits EvaluatorHelper.contains(Object, Object), which
    handled only collections and arrays and returned false for a String.
    The rule matched for the first drools.jittingThreshold evaluations and
    stopped matching after that.
    
    EvaluatorHelper.contains(Object, Object) now does the same String check
    as ParseTools.containsCheck, so the jitted and interpreted evaluators
    agree.
    
    Co-authored-by: AndriiTsepukh <[email protected]>
    Co-authored-by: Claude Opus 5.5 <[email protected]>
---
 .../main/java/org/drools/mvel/EvaluatorHelper.java |  3 +++
 .../drools/mvel/integrationtests/JittingTest.java  | 30 ++++++++++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/drools-mvel/src/main/java/org/drools/mvel/EvaluatorHelper.java 
b/drools-mvel/src/main/java/org/drools/mvel/EvaluatorHelper.java
index 30958340b73..6fd17b962f3 100644
--- a/drools-mvel/src/main/java/org/drools/mvel/EvaluatorHelper.java
+++ b/drools-mvel/src/main/java/org/drools/mvel/EvaluatorHelper.java
@@ -93,6 +93,9 @@ public class EvaluatorHelper {
             return ((Collection)list).contains(item);
         } else if (list instanceof Object[]) {
             return arrayContains( ( Object[] ) list, item );
+        } else if (list instanceof String) {
+            // same check as the interpreted MVEL evaluator
+            return ((String) list).contains( String.valueOf( item ) );
         } else if (item == null) {
             return false;
         } else if (list instanceof int[]) {
diff --git 
a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/JittingTest.java
 
b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/JittingTest.java
index b66951c6c9d..528f90e292e 100644
--- 
a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/JittingTest.java
+++ 
b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/JittingTest.java
@@ -28,6 +28,7 @@ import java.util.stream.Stream;
 import org.drools.mvel.compiler.Person;
 import org.drools.mvel.integrationtests.facts.AnEnum;
 import org.drools.mvel.integrationtests.facts.FactWithEnum;
+import org.drools.mvel.integrationtests.facts.FactWithMap;
 import org.drools.testcoverage.common.util.KieBaseTestConfiguration;
 import org.drools.testcoverage.common.util.KieBaseUtil;
 import org.drools.testcoverage.common.util.KieUtil;
@@ -257,6 +258,35 @@ public class JittingTest {
         assertThat(ksession.fireAllRules()).isEqualTo(expectedFires);
     }
 
+    @ParameterizedTest(name = "KieBase type={0}")
+    @MethodSource("parameters")
+    public void testJitContainsOnStringTypedAsObject(KieBaseTestConfiguration 
kieBaseTestConfiguration) {
+        // The build resolves itemsMap.get() to String from the generics; the 
jitter sees the erased Object
+        checkJitContainsOnStringTypedAsObject(kieBaseTestConfiguration, 
"itemsMap.get(1) contains \"T80011\"", 1);
+        checkJitContainsOnStringTypedAsObject(kieBaseTestConfiguration, 
"itemsMap.get(1) contains \"T99999\"", 0);
+        checkJitContainsOnStringTypedAsObject(kieBaseTestConfiguration, 
"itemsMap.get(1) not contains \"T80011\"", 0);
+        checkJitContainsOnStringTypedAsObject(kieBaseTestConfiguration, 
"itemsMap.get(1) not contains \"T99999\"", 1);
+    }
+
+    private void 
checkJitContainsOnStringTypedAsObject(KieBaseTestConfiguration 
kieBaseTestConfiguration, String constraint, int expectedFires) {
+        String drl =
+                "import " + FactWithMap.class.getCanonicalName() + ";\n" +
+                "rule R when\n" +
+                "    FactWithMap( " + constraint + " )\n" +
+                "then\n" +
+                "end\n";
+
+        final KieModule kieModule = KieUtil.getKieModuleFromDrls("test", 
kieBaseTestConfiguration, drl);
+        final KieBase kieBase = 
KieBaseUtil.newKieBaseFromKieModuleWithAdditionalOptions(kieModule, 
kieBaseTestConfiguration, ConstraintJittingThresholdOption.get(0));
+        final KieSession ksession = kieBase.newKieSession();
+        try {
+            ksession.insert(new FactWithMap(1, 
"FAILURE.T80011,FAILURE.T80012"));
+            
assertThat(ksession.fireAllRules()).as(constraint).isEqualTo(expectedFires);
+        } finally {
+            ksession.dispose();
+        }
+    }
+
     @ParameterizedTest(name = "KieBase type={0}")
     @MethodSource("parameters")
     public void testJittingBigDecimalAdd(KieBaseTestConfiguration 
kieBaseTestConfiguration) {


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

Reply via email to