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]