This is an automated email from the ASF dual-hosted git repository.
tkobayas pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-drools.git
The following commit(s) were added to refs/heads/main by this push:
new 78e1a3c1e08 [incubator-kie-drools-6783] Type inline-accumulate result
binding used in a result constraint (#6791)
78e1a3c1e08 is described below
commit 78e1a3c1e08c0bd09692c7d1317df0bb72546cd1
Author: Toshiya Kobayashi <[email protected]>
AuthorDate: Thu Jul 2 17:51:24 2026 +0900
[incubator-kie-drools-6783] Type inline-accumulate result binding used in a
result constraint (#6791)
* [incubator-kie-drools-6783] Type inline-accumulate result binding used in
a result constraint
A result constraint that references an inline-binding accumulate result
(e.g. "$ages : collectList($a); $ages.size > 0") failed to compile because
the
binding was left typed as Object. After building the accumulate pattern,
retype
the binding references in the result-constraint lambdas to the accumulate
function's result type, without altering the pattern object type used for
matching.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
* [incubator-kie-drools-6783] Pass accumulate result type to
ClassPatternDSL instead of post-hoc retyping
Instead of building constraint lambdas with Object type and then patching
them via replaceTypeInExprLambdaAndIndex, resolve the accumulate function's
result type in PatternAccumulateConstraint and pass it directly to
ClassPatternDSL. Guard buildFromDeclaration to not clobber a pre-set
patternType. This ensures lambdas are generated with the correct type
from the start.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI
<[email protected]>
* moved a test to a suitable test class. fix cast issue and suppress warning
---------
Co-authored-by: Daniel Clark <[email protected]>
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Co-authored-by: Copilot Autofix powered by AI
<[email protected]>
---
.../generator/visitor/pattern/ClassPatternDSL.java | 10 ++++---
.../pattern/PatternAccumulateConstraint.java | 8 ++++--
.../model/codegen/execmodel/AccumulateTest.java | 32 ++++++++++++++++++++++
3 files changed, 44 insertions(+), 6 deletions(-)
diff --git
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/ClassPatternDSL.java
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/ClassPatternDSL.java
index 28dd6612c0f..a53d69380ad 100644
---
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/ClassPatternDSL.java
+++
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/ClassPatternDSL.java
@@ -153,10 +153,12 @@ public class ClassPatternDSL extends PatternDSL {
private Optional<Expression> buildFromDeclaration(PatternDescr pattern) {
Optional<PatternSourceDescr> source =
Optional.ofNullable(pattern.getSource());
- try {
- patternType = context.getTypeResolver().resolveType(
pattern.getObjectType() );
- } catch (ClassNotFoundException e) {
- throw new RuntimeException( e );
+ if (patternType == null) {
+ try {
+ patternType = context.getTypeResolver().resolveType(
pattern.getObjectType() );
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException( e );
+ }
}
Optional<Expression> declarationSourceFrom = source.flatMap(new
FromVisitor(context, patternType)::visit);
if (declarationSourceFrom.isPresent()) {
diff --git
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternAccumulateConstraint.java
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternAccumulateConstraint.java
index 900ce748891..70d4b5ef746 100644
---
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternAccumulateConstraint.java
+++
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternAccumulateConstraint.java
@@ -30,6 +30,7 @@ import org.drools.drl.ast.descr.PatternDescr;
import org.drools.model.codegen.execmodel.PackageModel;
import org.drools.model.codegen.execmodel.generator.DrlxParseUtil;
import org.drools.model.codegen.execmodel.generator.RuleContext;
+import org.drools.model.codegen.execmodel.generator.TypedDeclarationSpec;
import org.drools.model.codegen.execmodel.generator.visitor.DSLNode;
import org.drools.mvel.parser.ast.expr.DrlNameExpr;
import org.drools.mvel.parser.printer.PrintUtil;
@@ -66,9 +67,12 @@ class PatternAccumulateConstraint implements DSLNode {
}
}
- constraintsByVar.forEach( (id, constraints) -> {
+ constraintsByVar.forEach((id, constraints) -> {
pattern.setIdentifier(id);
- new ClassPatternDSL(context, packageModel, pattern, constraints,
null).buildPattern();
+ Class<?> resultType = context.getTypedDeclarationById(id)
+ .map(TypedDeclarationSpec::getDeclarationClass)
+ .orElse(null);
+ new ClassPatternDSL(context, packageModel, pattern, constraints,
resultType).buildPattern();
});
pattern.setIdentifier(null);
}
diff --git
a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/AccumulateTest.java
b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/AccumulateTest.java
index 596b52b149c..0ca109467f1 100644
---
a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/AccumulateTest.java
+++
b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/AccumulateTest.java
@@ -4392,4 +4392,36 @@ public class AccumulateTest extends BaseModelTest {
assertThat(results.size()).isEqualTo(1);
assertThat(results.iterator().next().getValue()).isEqualTo(0);
}
+
+ @SuppressWarnings("unchecked")
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void
testResultConstraintReferencingInlineAccumulateBinding(RUN_TYPE runType) {
+ // An inline-binding accumulate whose result binding is used in a
result constraint
+ // (e.g. "$ages : collectList($a); $ages.size > 0") must compile: the
binding has to be typed
+ // against the accumulate function's result type rather than left as
Object, otherwise the
+ // result-constraint lambda fails to compile.
+ String str =
+ "import " + Person.class.getCanonicalName() + ";\n" +
+ "import " + Result.class.getCanonicalName() + ";\n" +
+ "rule R when\n" +
+ " accumulate(\n" +
+ " $p : Person( $a : age );\n" +
+ " $ages : collectList( $a );\n" +
+ " $ages.size > 0\n" +
+ " )\n" +
+ "then\n" +
+ " insert(new Result($ages));\n" +
+ "end";
+ KieSession ksession = getKieSession(runType, str);
+
+ ksession.insert(new Person("Mark", 37));
+ ksession.insert(new Person("Mario", 40));
+
+ assertThat(ksession.fireAllRules()).isEqualTo(1);
+
+ Collection<Result> results = getObjectsIntoList(ksession,
Result.class);
+ assertThat(results).hasSize(1);
+ assertThat((List<Integer>)
results.iterator().next().getValue()).containsExactlyInAnyOrder(37, 40);
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]