From c2a32e5dd5a036cfe3a9ee9de76074a77d74730f Mon Sep 17 00:00:00 2001 From: foxtail463 Date: Wed, 27 May 2026 10:03:46 +0800 Subject: [PATCH] [fix](fe) Preserve operative slots when deep copying logical relations (#63315) problem summary: When deep copying a `LogicalCatalogRelation`, `LogicalPlanDeepCopier#updateOperativeSlots` needs to remap the original relation's operative slots to the corresponding slots in the copied relation. Before this change, the search range was incorrectly limited by `oldOperativeSlots.size()` instead of the relation output size. If the operative slot was not located in the first `oldOperativeSlots.size()` output positions, the copier could not find the matching slot and the copied relation would lose that operative slot. For example, when a relation has multiple output slots but only one operative slot at index 1, the old logic only checked index 0 and failed to preserve the operative slot. Co-authored-by: yangtao555 --- .../nereids/trees/copier/LogicalPlanDeepCopier.java | 2 +- .../trees/copier/LogicalPlanDeepCopierTest.java | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopier.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopier.java index 33e32fe92e71bd..ba88203f849a53 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopier.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopier.java @@ -463,7 +463,7 @@ private void updateReplaceMapWithOutput(Plan oldPlan, Plan newPlan, Map oldOperativeSlots = oldRelation.getOperativeSlots(); List newOperativeSlots = new ArrayList<>(oldOperativeSlots.size()); - int outputSize = oldOperativeSlots.size(); + int outputSize = oldRelation.getOutput().size(); for (Slot opSlot : oldOperativeSlots) { int idx; for (idx = 0; idx < outputSize; idx++) { diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopierTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopierTest.java index 4ba8edfe34cd35..7389fd2b8a3cdd 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopierTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopierTest.java @@ -49,6 +49,17 @@ public void testDeepCopyOlapScan() { } } + @Test + public void testDeepCopyOlapScanWithNonFirstOperativeSlot() { + LogicalOlapScan relationPlan = PlanConstructor.newLogicalOlapScan(0, "a", 0); + relationPlan = (LogicalOlapScan) relationPlan.withOperativeSlots( + ImmutableList.of(relationPlan.getOutput().get(1))); + LogicalOlapScan aCopy = + (LogicalOlapScan) relationPlan.accept(LogicalPlanDeepCopier.INSTANCE, new DeepCopierContext()); + + Assertions.assertEquals(ImmutableList.of(aCopy.getOutput().get(1)), aCopy.getOperativeSlots()); + } + @Test public void testDeepCopyAggregateWithSourceRepeat() { LogicalOlapScan scan = PlanConstructor.newLogicalOlapScan(0, "t", 0);