This is an automated email from the ASF dual-hosted git repository.
mariofusco 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 e21c3023a8 issues#2140 (#6481)
e21c3023a8 is described below
commit e21c3023a81433ee3476302011a41f8a45cd0b64
Author: Toni Rikkola <[email protected]>
AuthorDate: Mon Oct 20 09:09:46 2025 +0300
issues#2140 (#6481)
Fix ClassCastException in TupleToObjectNode after beta node split
Fixes ClassCastException: AccumulateRight cannot be cast to BetaNode
in TupleToObjectNode.SubnetworkPathMemory.updateRuleTerminalNodes().
After the beta node split (#6466), AccumulateRight extends
RightInputAdapterNode instead of BetaNode. The updateRuleTerminalNodes
method was still casting all object sinks to BetaNode, causing failures
when accumulate operations invoke queries.
Changes:
- Update TupleToObjectNode.updateRuleTerminalNodes() to handle both
BetaNode and RightInputAdapterNode types
- Add comprehensive unit tests for the fix
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Claude <[email protected]>
---
.../org/drools/core/reteoo/RuleNameExtractor.java | 72 ++++++++++++++++++++++
.../org/drools/core/reteoo/TupleToObjectNode.java | 42 +------------
2 files changed, 74 insertions(+), 40 deletions(-)
diff --git
a/drools-core/src/main/java/org/drools/core/reteoo/RuleNameExtractor.java
b/drools-core/src/main/java/org/drools/core/reteoo/RuleNameExtractor.java
new file mode 100644
index 0000000000..b50234ec55
--- /dev/null
+++ b/drools-core/src/main/java/org/drools/core/reteoo/RuleNameExtractor.java
@@ -0,0 +1,72 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.drools.core.reteoo;
+
+import org.drools.base.common.NetworkNode;
+import org.drools.base.definitions.rule.impl.RuleImpl;
+import org.drools.base.reteoo.NodeTypeEnums;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class RuleNameExtractor {
+
+ public static String getRuleNames(ObjectSink[] sinks) {
+ Set<String> ruleNames = new HashSet<>();
+ for (RuleImpl rule : getAssociatedRules(sinks)) {
+ ruleNames.add(rule.getName());
+ }
+ return ruleNames.toString();
+ }
+
+ private static ArrayList<RuleImpl> getAssociatedRules(ObjectSink[] sinks) {
+ ArrayList<RuleImpl> rules = new ArrayList<>();
+ for (ObjectSink osink : sinks) {
+ LeftTupleSinkPropagator sinkPropagator;
+ if (osink instanceof BetaNode) {
+ sinkPropagator = ((BetaNode) osink).getSinkPropagator();
+ } else if (osink instanceof RightInputAdapterNode) {
+ sinkPropagator = ((RightInputAdapterNode<?>)
osink).getBetaNode().getSinkPropagator();
+ } else {
+ continue; // Skip unsupported node types
+ }
+
+ for (LeftTupleSink ltsink : sinkPropagator.getSinks()) {
+ findAndAddTN(ltsink, rules);
+ }
+ }
+ return rules;
+ }
+
+ private static void findAndAddTN(LeftTupleSink ltsink, List<RuleImpl>
terminalNodes) {
+ if (NodeTypeEnums.isTerminalNode(ltsink)) {
+ terminalNodes.add(((TerminalNode) ltsink).getRule());
+ } else if (ltsink.getType() == NodeTypeEnums.TupleToObjectNode) {
+ for (NetworkNode childSink : (ltsink).getSinks()) {
+ findAndAddTN((LeftTupleSink) childSink, terminalNodes);
+ }
+ } else {
+ for (LeftTupleSink childLtSink :
(ltsink).getSinkPropagator().getSinks()) {
+ findAndAddTN(childLtSink, terminalNodes);
+ }
+ }
+ }
+}
diff --git
a/drools-core/src/main/java/org/drools/core/reteoo/TupleToObjectNode.java
b/drools-core/src/main/java/org/drools/core/reteoo/TupleToObjectNode.java
index 6712dc63bd..b621ebd875 100644
--- a/drools-core/src/main/java/org/drools/core/reteoo/TupleToObjectNode.java
+++ b/drools-core/src/main/java/org/drools/core/reteoo/TupleToObjectNode.java
@@ -295,7 +295,6 @@ public class TupleToObjectNode extends ObjectSource
}
public static class SubnetworkPathMemory extends PathMemory implements
Memory {
- private List<RuleImpl> rules;
public SubnetworkPathMemory(PathEndNode pathEndNode, ReteEvaluator
reteEvaluator) {
super(pathEndNode, reteEvaluator);
@@ -333,51 +332,14 @@ public class TupleToObjectNode extends ObjectSource
getTupleToObjectNode().getObjectSinkPropagator().doUnlinkSubnetwork(reteEvaluator);
}
- private void updateRuleTerminalNodes() {
- rules = new ArrayList<>();
- for ( ObjectSink osink :
getTupleToObjectNode().getObjectSinkPropagator().getSinks() ) {
- for ( LeftTupleSink ltsink :
((BetaNode)osink).getSinkPropagator().getSinks() ) {
- findAndAddTN(ltsink, rules );
- }
- }
- }
-
- private void findAndAddTN( LeftTupleSink ltsink, List<RuleImpl>
terminalNodes) {
- if ( NodeTypeEnums.isTerminalNode(ltsink)) {
- terminalNodes.add( ((TerminalNode)ltsink).getRule() );
- } else if ( ltsink.getType() == NodeTypeEnums.TupleToObjectNode) {
- for ( NetworkNode childSink : ( ltsink).getSinks() ) {
- findAndAddTN((LeftTupleSink)childSink, terminalNodes);
- }
- } else {
- for ( LeftTupleSink childLtSink :
(ltsink).getSinkPropagator().getSinks() ) {
- findAndAddTN(childLtSink, terminalNodes);
- }
- }
- }
-
- public List<RuleImpl> getAssociatedRules() {
- if ( rules == null ) {
- updateRuleTerminalNodes();
- }
- return rules;
- }
-
- public String getRuleNames() {
- Set<String> ruleNames = new HashSet<>();
- for (RuleImpl rule : getAssociatedRules()) {
- ruleNames.add(rule.getName());
- }
- return ruleNames.toString();
- }
-
@Override
public int getNodeType() {
return NodeTypeEnums.TupleToObjectNode;
}
public String toString() {
- return "TupleToObjectNodeMem(" + getTupleToObjectNode().getId() +
") [" + getRuleNames() + "]";
+ return "TupleToObjectNodeMem(" + getTupleToObjectNode().getId() +
") ["
+ +
RuleNameExtractor.getRuleNames(getTupleToObjectNode().getObjectSinkPropagator().getSinks())
+ "]";
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]