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

yiguolei pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.1 by this push:
     new 2f6b7bfe26f branch-4.1: [fix](topn) Skip TopN lazy materialization 
when light_schema_change=false #64441 (#64634)
2f6b7bfe26f is described below

commit 2f6b7bfe26fe50fddb4bfb483a0acfe71b7aef00
Author: HappenLee <[email protected]>
AuthorDate: Sat Jun 20 20:57:14 2026 +0800

    branch-4.1: [fix](topn) Skip TopN lazy materialization when 
light_schema_change=false #64441 (#64634)
    
    Cherry-picked from https://github.com/apache/doris/pull/64441
---
 .../post/materialize/LazyMaterializeTopN.java      | 12 ++++++++
 .../postprocess/TopnLazyMaterializeTest.java       | 33 ++++++++++++++++++++++
 2 files changed, 45 insertions(+)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/processor/post/materialize/LazyMaterializeTopN.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/processor/post/materialize/LazyMaterializeTopN.java
index 6105b652445..26da0c0dbba 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/processor/post/materialize/LazyMaterializeTopN.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/processor/post/materialize/LazyMaterializeTopN.java
@@ -19,6 +19,7 @@ package org.apache.doris.nereids.processor.post.materialize;
 
 import org.apache.doris.catalog.AggregateType;
 import org.apache.doris.catalog.Column;
+import org.apache.doris.catalog.OlapTable;
 import org.apache.doris.catalog.Type;
 import org.apache.doris.nereids.CascadesContext;
 import org.apache.doris.nereids.StatementContext;
@@ -125,6 +126,17 @@ public class LazyMaterializeTopN extends PlanPostProcessor 
{
         // conflict expr id
         StatementContext threadStatementContext = 
StatementScopeIdGenerator.getStatementContext();
         for (Relation relation : relationToLazySlotMap.keySet()) {
+            // TopN lazy materialization relies on BE adding a 
GLOBAL_ROWID_COL to the
+            // tablet schema. When light_schema_change=false, the table 
columns have
+            // col_unique_id=-1, which causes BE to skip the schema rebuild 
from
+            // columns_desc, so the GLOBAL_ROWID_COL is never added and the 
scan fails.
+            if (relation instanceof CatalogRelation
+                    && ((CatalogRelation) relation).getTable() instanceof 
OlapTable
+                    && !((OlapTable) ((CatalogRelation) 
relation).getTable()).getEnableLightSchemaChange()) {
+                LOG.debug("Skip TopN lazy materialization for table {} with 
light_schema_change=false",
+                        ((CatalogRelation) relation).getTable().getName());
+                return topN;
+            }
             if (relation instanceof CatalogRelation) {
                 CatalogRelation catalogRelation = (CatalogRelation) relation;
                 Column rowIdCol = new Column(Column.GLOBAL_ROWID_COL + 
catalogRelation.getTable().getName(),
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/postprocess/TopnLazyMaterializeTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/postprocess/TopnLazyMaterializeTest.java
index ea384d35bd2..159cd611676 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/postprocess/TopnLazyMaterializeTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/postprocess/TopnLazyMaterializeTest.java
@@ -24,6 +24,7 @@ import 
org.apache.doris.nereids.glue.translator.PlanTranslatorContext;
 import org.apache.doris.nereids.processor.post.PlanPostProcessors;
 import org.apache.doris.nereids.trees.plans.physical.PhysicalPlan;
 import org.apache.doris.nereids.util.PlanChecker;
+import org.apache.doris.planner.MaterializationNode;
 import org.apache.doris.planner.OlapScanNode;
 import org.apache.doris.planner.PlanFragment;
 
@@ -78,4 +79,36 @@ public class TopnLazyMaterializeTest extends SSBTestBase {
         Assertions.assertEquals(1, slots.size());
         Assertions.assertEquals("k2", slots.get(0).getColumn().getName());
     }
+
+    @Test
+    public void testLightSchemaChangeFalse() throws Exception {
+        this.createTable("create table tm_lsc_false (k int, v int) duplicate 
key(k) "
+                + "distributed by hash(k) buckets 1 "
+                + "properties('replication_num' = '1', 'light_schema_change' = 
'false')");
+        String sql = "select * from tm_lsc_false order by k limit 1";
+        PlanChecker checker = PlanChecker.from(connectContext)
+                .analyze(sql)
+                .rewrite()
+                .implement();
+        PhysicalPlan plan = checker.getPhysicalPlan();
+        plan = new 
PlanPostProcessors(checker.getCascadesContext()).process(plan);
+        PlanTranslatorContext translatorContext = new 
PlanTranslatorContext(checker.getCascadesContext());
+        PlanFragment fragment = new 
PhysicalPlanTranslator(translatorContext).translatePlan(plan);
+
+        // TopN lazy materialization should be skipped for 
light_schema_change=false,
+        // so no MaterializationNode should be created.
+        List<MaterializationNode> materializationNodes = Lists.newArrayList();
+        fragment.getPlanRoot().collect(MaterializationNode.class, 
materializationNodes);
+        Assertions.assertTrue(materializationNodes.isEmpty(),
+                "TopN lazy materialization should be skipped for 
light_schema_change=false");
+
+        // All columns should be in the scan output (no lazy pruned columns).
+        List<OlapScanNode> scanNodes = Lists.newArrayList();
+        fragment.getPlanRoot().collect(OlapScanNode.class, scanNodes);
+        Assertions.assertEquals(1, scanNodes.size());
+        List<SlotDescriptor> slots = 
scanNodes.get(0).getTupleDesc().getSlots();
+        Assertions.assertEquals(2, slots.size());
+        Assertions.assertTrue(slots.stream().anyMatch(s -> 
s.getColumn().getName().equals("k")));
+        Assertions.assertTrue(slots.stream().anyMatch(s -> 
s.getColumn().getName().equals("v")));
+    }
 }


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

Reply via email to