diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/statemachine/dataregion/DataRegionStateMachine.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/statemachine/dataregion/DataRegionStateMachine.java index 284926a85d64..c430be4b1741 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/statemachine/dataregion/DataRegionStateMachine.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/statemachine/dataregion/DataRegionStateMachine.java @@ -23,7 +23,6 @@ import org.apache.iotdb.commons.conf.CommonDescriptor; import org.apache.iotdb.commons.consensus.ConsensusGroupId; import org.apache.iotdb.commons.consensus.DataRegionId; -import org.apache.iotdb.commons.path.PartialPath; import org.apache.iotdb.consensus.common.DataSet; import org.apache.iotdb.consensus.common.request.IConsensusRequest; import org.apache.iotdb.consensus.common.request.IndexedConsensusRequest; @@ -34,12 +33,6 @@ import org.apache.iotdb.db.queryengine.execution.fragment.FragmentInstanceManager; import org.apache.iotdb.db.queryengine.plan.planner.plan.FragmentInstance; import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNode; -import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.DeleteDataNode; -import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.InsertMultiTabletsNode; -import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.InsertNode; -import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.InsertRowNode; -import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.InsertRowsNode; -import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.InsertTabletNode; import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.SearchNode; import org.apache.iotdb.db.storageengine.StorageEngine; import org.apache.iotdb.db.storageengine.buffer.BloomFilterCache; @@ -50,7 +43,6 @@ import org.apache.iotdb.db.storageengine.dataregion.snapshot.SnapshotTaker; import org.apache.iotdb.rpc.TSStatusCode; -import org.apache.tsfile.write.UnSupportedDataTypeException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -58,7 +50,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; public class DataRegionStateMachine extends BaseStateMachine { @@ -155,131 +146,37 @@ public void loadSnapshot(File latestSnapshotRootDir) { } protected PlanNode grabPlanNode(IndexedConsensusRequest indexedRequest) { - List insertNodes = new ArrayList<>(indexedRequest.getRequests().size()); - List deleteDataNodes = new ArrayList<>(); + List searchNodes = new ArrayList<>(); + PlanNode onlyOne = null; for (IConsensusRequest req : indexedRequest.getRequests()) { // PlanNode in IndexedConsensusRequest should always be InsertNode PlanNode planNode = getPlanNode(req); if (planNode instanceof SearchNode) { ((SearchNode) planNode).setSearchIndex(indexedRequest.getSearchIndex()); - } - if (planNode instanceof InsertNode) { - insertNodes.add((InsertNode) planNode); - } else if (planNode instanceof DeleteDataNode) { - deleteDataNodes.add((DeleteDataNode) planNode); - } else if (indexedRequest.getRequests().size() == 1) { - // If the planNode is not InsertNode, it is expected that the IndexedConsensusRequest only - // contains one request - return planNode; + searchNodes.add((SearchNode) planNode); } else { - throw new IllegalArgumentException( - "PlanNodes in IndexedConsensusRequest are not InsertNode and " - + "the size of requests are larger than 1"); + logger.warn("Unexpected PlanNode type {}, which is not SearchNode", planNode.getClass()); + if (onlyOne == null) { + onlyOne = planNode; + } else { + throw new IllegalArgumentException( + String.format( + "There are two types of PlanNode in one request: %s and %s", + onlyOne.getClass(), planNode.getClass())); + } } } - if (!insertNodes.isEmpty()) { - if (!deleteDataNodes.isEmpty()) { + if (onlyOne != null) { + if (!searchNodes.isEmpty()) { throw new IllegalArgumentException( - "One indexedRequest cannot contain InsertNode and DeleteDataNode at the same time"); + String.format( + "There are two types of PlanNode in one request: %s and SearchNode", + onlyOne.getClass())); } - return mergeInsertNodes(insertNodes); - } - return mergeDeleteDataNode(deleteDataNodes); - } - - private DeleteDataNode mergeDeleteDataNode(List deleteDataNodes) { - int size = deleteDataNodes.size(); - if (size == 0) { - throw new IllegalArgumentException("deleteDataNodes is empty"); - } - DeleteDataNode firstOne = deleteDataNodes.get(0); - if (size == 1) { - return firstOne; - } - if (!deleteDataNodes.stream() - .allMatch( - deleteDataNode -> - firstOne.getDeleteStartTime() == deleteDataNode.getDeleteStartTime() - && firstOne.getDeleteEndTime() == deleteDataNode.getDeleteEndTime())) { - throw new IllegalArgumentException( - "DeleteDataNodes which start time or end time are not same cannot be merged"); - } - List pathList = - deleteDataNodes.stream() - .flatMap(deleteDataNode -> deleteDataNode.getPathList().stream()) - // Some time the deleteDataNode list contains a path for multiple times, so use - // distinct() to clear them - .distinct() - .collect(Collectors.toList()); - return new DeleteDataNode( - firstOne.getPlanNodeId(), - pathList, - firstOne.getDeleteStartTime(), - firstOne.getDeleteEndTime()); - } - - /** - * Merge insert nodes sharing same search index ( e.g. tablet-100, tablet-100, tablet-100 will be - * merged to one multi-tablet).
- * Notice: the continuity of insert nodes sharing same search index should be protected by the - * upper layer. - * - * @exception IllegalArgumentException when insertNodes is empty - */ - protected InsertNode mergeInsertNodes(List insertNodes) { - int size = insertNodes.size(); - if (size == 0) { - throw new IllegalArgumentException("insertNodes should never be empty"); + return onlyOne; } - if (size == 1) { - return insertNodes.get(0); - } - - InsertNode result; - List index = new ArrayList<>(); - int i = 0; - switch (insertNodes.get(0).getType()) { - case INSERT_TABLET: - // merge to InsertMultiTabletsNode - List insertTabletNodes = new ArrayList<>(size); - for (InsertNode insertNode : insertNodes) { - insertTabletNodes.add((InsertTabletNode) insertNode); - index.add(i); - i++; - } - result = - new InsertMultiTabletsNode( - insertNodes.get(0).getPlanNodeId(), index, insertTabletNodes); - break; - case INSERT_ROW: - // merge to InsertRowsNode - List insertRowNodes = new ArrayList<>(size); - for (InsertNode insertNode : insertNodes) { - insertRowNodes.add((InsertRowNode) insertNode); - index.add(i); - i++; - } - result = new InsertRowsNode(insertNodes.get(0).getPlanNodeId(), index, insertRowNodes); - break; - case INSERT_ROWS: - // merge to InsertRowsNode - List list = new ArrayList<>(); - for (InsertNode insertNode : insertNodes) { - for (InsertRowNode insertRowNode : ((InsertRowsNode) insertNode).getInsertRowNodeList()) { - list.add(insertRowNode); - index.add(i); - i++; - } - } - result = new InsertRowsNode(insertNodes.get(0).getPlanNodeId(), index, list); - break; - default: - throw new UnSupportedDataTypeException( - "Unsupported node type " + insertNodes.get(0).getType()); - } - result.setSearchIndex(insertNodes.get(0).getSearchIndex()); - result.setDevicePath(insertNodes.get(0).getDevicePath()); - return result; + // searchNodes should never be empty here + return searchNodes.get(0).merge(searchNodes); } @Override diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/pipe/PipeEnrichedDeleteDataNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/pipe/PipeEnrichedDeleteDataNode.java index 57450a3cd068..8ec360e0ed15 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/pipe/PipeEnrichedDeleteDataNode.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/pipe/PipeEnrichedDeleteDataNode.java @@ -29,6 +29,8 @@ import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanVisitor; import org.apache.iotdb.db.queryengine.plan.planner.plan.node.WritePlanNode; import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.DeleteDataNode; +import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.SearchNode; +import org.apache.iotdb.db.storageengine.dataregion.wal.buffer.IWALByteBufferView; import java.io.DataOutputStream; import java.io.IOException; @@ -171,4 +173,26 @@ public List splitByPartition(IAnalysis analysis) { : new PipeEnrichedDeleteDataNode((DeleteDataNode) plan)) .collect(Collectors.toList()); } + + @Override + public void serializeToWAL(final IWALByteBufferView buffer) { + deleteDataNode.serializeToWAL(buffer); + } + + @Override + public int serializedSize() { + return deleteDataNode.serializedSize(); + } + + @Override + public SearchNode merge(List searchNodes) { + List unrichedDeleteDataNodes = + searchNodes.stream() + .map( + searchNode -> + (SearchNode) ((PipeEnrichedDeleteDataNode) searchNode).getDeleteDataNode()) + .collect(Collectors.toList()); + return new PipeEnrichedDeleteDataNode( + (DeleteDataNode) deleteDataNode.merge(unrichedDeleteDataNodes)); + } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/pipe/PipeEnrichedInsertNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/pipe/PipeEnrichedInsertNode.java index 6ea566053ac8..e152ed09bda6 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/pipe/PipeEnrichedInsertNode.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/pipe/PipeEnrichedInsertNode.java @@ -144,6 +144,11 @@ public List splitByPartition(IAnalysis analysis) { .collect(Collectors.toList()); } + @Override + public InsertNode mergeInsertNode(List insertNodes) { + return insertNode.mergeInsertNode(insertNodes); + } + @Override public TRegionReplicaSet getDataRegionReplicaSet() { return insertNode.getDataRegionReplicaSet(); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/ContinuousSameSearchIndexSeparatorNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/ContinuousSameSearchIndexSeparatorNode.java index 521f720be789..43af885e734f 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/ContinuousSameSearchIndexSeparatorNode.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/ContinuousSameSearchIndexSeparatorNode.java @@ -49,6 +49,12 @@ public ContinuousSameSearchIndexSeparatorNode(PlanNodeId id) { this.searchIndex = -1; } + @Override + public SearchNode merge(List searchNodes) { + throw new UnsupportedOperationException( + "ContinuousSameSearchIndexSeparatorNode not support merge"); + } + @Override public void serializeToWAL(IWALByteBufferView buffer) { buffer.putShort(PlanNodeType.CONTINUOUS_SAME_SEARCH_INDEX_SEPARATOR.getNodeType()); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/DeleteDataNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/DeleteDataNode.java index 86da1a528e5d..0e7eae3f9d7b 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/DeleteDataNode.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/DeleteDataNode.java @@ -323,4 +323,40 @@ private void splitPathPatternByDevice( .addAll(pathPattern.alterPrefixPath(devicePath))); } } + + @Override + public SearchNode merge(List searchNodes) { + List deleteDataNodes = + searchNodes.stream() + .map(searchNode -> (DeleteDataNode) searchNode) + .collect(Collectors.toList()); + int size = deleteDataNodes.size(); + if (size == 0) { + throw new IllegalArgumentException("deleteDataNodes is empty"); + } + DeleteDataNode firstOne = deleteDataNodes.get(0); + if (size == 1) { + return firstOne; + } + if (!deleteDataNodes.stream() + .allMatch( + deleteDataNode -> + firstOne.getDeleteStartTime() == deleteDataNode.getDeleteStartTime() + && firstOne.getDeleteEndTime() == deleteDataNode.getDeleteEndTime())) { + throw new IllegalArgumentException( + "DeleteDataNodes which start time or end time are not same cannot be merged"); + } + List pathList = + deleteDataNodes.stream() + .flatMap(deleteDataNode -> deleteDataNode.getPathList().stream()) + // Some time the deleteDataNode list contains a path for multiple times, so use + // distinct() to clear them + .distinct() + .collect(Collectors.toList()); + return new DeleteDataNode( + firstOne.getPlanNodeId(), + pathList, + firstOne.getDeleteStartTime(), + firstOne.getDeleteEndTime()); + } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertMultiTabletsNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertMultiTabletsNode.java index 430ab19c7c97..6e401b4d54bd 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertMultiTabletsNode.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertMultiTabletsNode.java @@ -98,6 +98,11 @@ public InsertMultiTabletsNode(PlanNodeId id) { insertTabletNodeList = new ArrayList<>(); } + @Override + public InsertNode mergeInsertNode(List insertNodes) { + throw new UnsupportedOperationException("InsertMultiTabletsNode not support merge"); + } + public InsertMultiTabletsNode( PlanNodeId id, List parentInsertTabletNodeIndexList, diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertNode.java index 3e373295f7a9..708b6cfc599f 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertNode.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertNode.java @@ -43,7 +43,9 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.util.Arrays; +import java.util.List; import java.util.Objects; +import java.util.stream.Collectors; public abstract class InsertNode extends SearchNode implements ComparableConsensusRequest { @@ -83,6 +85,26 @@ protected InsertNode(PlanNodeId id) { super(id); } + @Override + public final SearchNode merge(List searchNodes) { + if (searchNodes.isEmpty()) { + throw new IllegalArgumentException("insertNodes should never be empty"); + } + if (searchNodes.size() == 1) { + return searchNodes.get(0); + } + List insertNodes = + searchNodes.stream() + .map(searchNode -> (InsertNode) searchNode) + .collect(Collectors.toList()); + InsertNode result = mergeInsertNode(insertNodes); + result.setSearchIndex(insertNodes.get(0).getSearchIndex()); + result.setDevicePath(insertNodes.get(0).getDevicePath()); + return result; + } + + public abstract InsertNode mergeInsertNode(List insertNodes); + protected InsertNode( PlanNodeId id, PartialPath devicePath, diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowNode.java index 57107294f765..29a163b2ec50 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowNode.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowNode.java @@ -49,6 +49,7 @@ import java.io.DataOutputStream; import java.io.IOException; import java.nio.ByteBuffer; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -73,6 +74,17 @@ public InsertRowNode(PlanNodeId id) { super(id); } + @Override + public InsertNode mergeInsertNode(List insertNodes) { + List index = new ArrayList<>(); + List insertRowNodes = new ArrayList<>(); + for (int i = 0; i < insertNodes.size(); i++) { + insertRowNodes.add((InsertRowNode) insertNodes.get(i)); + index.add(i); + } + return new InsertRowsNode(this.getPlanNodeId(), index, insertRowNodes); + } + @TestOnly public InsertRowNode( PlanNodeId id, diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowsNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowsNode.java index 137580641282..caf86e67bab9 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowsNode.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowsNode.java @@ -73,6 +73,21 @@ public InsertRowsNode(PlanNodeId id) { insertRowNodeIndexList = new ArrayList<>(); } + @Override + public InsertNode mergeInsertNode(List insertNodes) { + List list = new ArrayList<>(); + List index = new ArrayList<>(); + int i = 0; + for (InsertNode insertNode : insertNodes) { + for (InsertRowNode insertRowNode : ((InsertRowsNode) insertNode).getInsertRowNodeList()) { + list.add(insertRowNode); + index.add(i); + i++; + } + } + return new InsertRowsNode(insertNodes.get(0).getPlanNodeId(), index, list); + } + public InsertRowsNode( PlanNodeId id, List insertRowNodeIndexList, List insertRowNodeList) { super(id); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowsOfOneDeviceNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowsOfOneDeviceNode.java index 0ec16ef69c78..021e51b69af6 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowsOfOneDeviceNode.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowsOfOneDeviceNode.java @@ -77,6 +77,11 @@ public InsertRowsOfOneDeviceNode(PlanNodeId id) { insertRowNodeList = new ArrayList<>(); } + @Override + public InsertNode mergeInsertNode(List insertNodes) { + throw new UnsupportedOperationException("InsertRowsOfOneDeviceNode not support merge"); + } + public InsertRowsOfOneDeviceNode( PlanNodeId id, List insertRowNodeIndexList, List insertRowNodeList) { super(id); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertTabletNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertTabletNode.java index 4dc8abe11b40..b00bb4a4be2d 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertTabletNode.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertTabletNode.java @@ -86,6 +86,17 @@ public InsertTabletNode(PlanNodeId id) { super(id); } + @Override + public InsertNode mergeInsertNode(List insertNodes) { + List index = new ArrayList<>(); + List insertTabletNodes = new ArrayList<>(); + for (int i = 0; i < insertNodes.size(); i++) { + insertTabletNodes.add((InsertTabletNode) insertNodes.get(i)); + index.add(i); + } + return new InsertMultiTabletsNode(this.getPlanNodeId(), index, insertTabletNodes); + } + @TestOnly public InsertTabletNode( PlanNodeId id, diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/SearchNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/SearchNode.java index c5172534298e..ecae2cd71977 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/SearchNode.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/SearchNode.java @@ -23,7 +23,7 @@ import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNodeId; import org.apache.iotdb.db.queryengine.plan.planner.plan.node.WritePlanNode; -import static org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.InsertNode.NO_CONSENSUS_INDEX; +import java.util.List; public abstract class SearchNode extends WritePlanNode { @@ -48,4 +48,6 @@ public long getSearchIndex() { public void setSearchIndex(long searchIndex) { this.searchIndex = searchIndex; } + + public abstract SearchNode merge(List searchNodes); } diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/consensus/statemachine/dataregion/DataRegionStateMachineTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/consensus/statemachine/dataregion/DataRegionStateMachineTest.java index 351fd6481d56..7a77eada418c 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/consensus/statemachine/dataregion/DataRegionStateMachineTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/consensus/statemachine/dataregion/DataRegionStateMachineTest.java @@ -72,7 +72,7 @@ public void testMergeInsertRowNodes() throws IllegalPathException { false); list.add(node); DataRegionStateMachine fakeStateMachine = new DataRegionStateMachine(null); - InsertNode mergedNode = fakeStateMachine.mergeInsertNodes(list); + InsertNode mergedNode = list.get(0).mergeInsertNode(list); Assert.assertTrue(mergedNode instanceof InsertRowsNode); } @@ -116,7 +116,7 @@ public void testMergeInsertRowsNodes() throws IllegalPathException { DataRegionStateMachine fakeStateMachine = new DataRegionStateMachine(null); list.add(insertRowsNode); list.add(insertRowsNode); - InsertNode mergedNode = fakeStateMachine.mergeInsertNodes(list); + InsertNode mergedNode = list.get(0).mergeInsertNode(list); Assert.assertTrue(mergedNode instanceof InsertRowsNode); } }