You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by en...@apache.org on 2026/04/17 03:44:56 UTC
(doris) branch master updated: [fix](fe) Fix view columns losing colUniqueId in lazy materialization (#62533)
This is an automated email from the ASF dual-hosted git repository.
englefly pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 742c046ac17 [fix](fe) Fix view columns losing colUniqueId in lazy materialization (#62533)
742c046ac17 is described below
commit 742c046ac17acd5d0ad6b3f096c2db432a62a450
Author: minghong <zh...@selectdb.com>
AuthorDate: Fri Apr 17 11:44:48 2026 +0800
[fix](fe) Fix view columns losing colUniqueId in lazy materialization (#62533)
### What problem does this PR solve?
When querying columns through a view with TopN + lazy materialization,
SlotReference.withOneLevelTableAndColumnAndQualifier() incorrectly
replaced
originalColumn with the view's Column object (which has uniqueId=-1).
This caused colUniqueId=-1 in the physical plan, making BE unable to
find
the column during the two-phase read (lazy materialize) fetch, resulting
in
"returned block with row count 0 not match request row id count" error.
The fix preserves the original base table Column (which carries the
correct
uniqueId) instead of overwriting it with the view's Column.
---
.../doris/nereids/trees/expressions/Alias.java | 2 +-
.../nereids/trees/expressions/SlotReference.java | 2 +-
.../nereids/trees/expressions/ExpressionTest.java | 17 +++++
.../query_p0/topn_lazy/lazy_materialize_view.out | 13 ++++
.../suites/mysql_compatibility_p0/metadata.groovy | 4 +-
.../topn_lazy/lazy_materialize_view.groovy | 84 ++++++++++++++++++++++
6 files changed, 118 insertions(+), 4 deletions(-)
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Alias.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Alias.java
index cc0ed1d2447..edb416014a6 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Alias.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Alias.java
@@ -99,7 +99,7 @@ public class Alias extends NamedExpression implements UnaryExpression {
slotReference != null ? ((SlotReference) child()).getOriginalTable().orElse(null) : null,
slotReference != null ? slotReference.getOriginalColumn().orElse(null) : null,
slotReference != null ? ((SlotReference) child()).getOneLevelTable().orElse(null) : null,
- slotReference != null ? slotReference.getOriginalColumn().orElse(null) : null,
+ slotReference != null ? slotReference.getOneLevelColumn().orElse(null) : null,
slotReference != null ? slotReference.getSubPath() : ImmutableList.of(), Optional.empty()
);
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/SlotReference.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/SlotReference.java
index cd8488318ce..77df137e97c 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/SlotReference.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/SlotReference.java
@@ -340,7 +340,7 @@ public class SlotReference extends Slot {
@Override
public Slot withOneLevelTableAndColumnAndQualifier(TableIf oneLevelTable, Column column, List<String> qualifier) {
return new SlotReference(exprId, name, dataType, nullable, qualifier,
- originalTable, column, oneLevelTable, column,
+ originalTable, originalColumn, oneLevelTable, column,
subPath, indexInSqlString);
}
diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionTest.java
index cb43efb0b31..43ba8a637a1 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionTest.java
@@ -17,6 +17,8 @@
package org.apache.doris.nereids.trees.expressions;
+import org.apache.doris.catalog.Column;
+import org.apache.doris.catalog.PrimitiveType;
import org.apache.doris.nereids.trees.expressions.functions.scalar.CurrentDate;
import org.apache.doris.nereids.trees.expressions.functions.scalar.DaysAdd;
import org.apache.doris.nereids.trees.expressions.functions.scalar.UnixTimestamp;
@@ -26,6 +28,7 @@ import org.apache.doris.nereids.trees.expressions.literal.StringLiteral;
import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral;
import org.apache.doris.nereids.types.IntegerType;
+import com.google.common.collect.ImmutableList;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -66,4 +69,18 @@ public class ExpressionTest {
new UnixTimestamp(), new IntegerLiteral(2)).containsNondeterministic());
}
+
+ @Test
+ public void testAliasToSlotKeepsOneLevelColumn() {
+ SlotReference slotReference = new SlotReference(new ExprId(1), "k1", IntegerType.INSTANCE, true,
+ ImmutableList.of("test", "view_metadata"), null, new Column("k1", PrimitiveType.INT),
+ null, new Column("vk1", PrimitiveType.INT));
+
+ SlotReference aliasSlot = (SlotReference) new Alias(slotReference, "c2").toSlot();
+
+ Assertions.assertTrue(aliasSlot.getOriginalColumn().isPresent());
+ Assertions.assertTrue(aliasSlot.getOneLevelColumn().isPresent());
+ Assertions.assertEquals("k1", aliasSlot.getOriginalColumn().get().getName());
+ Assertions.assertEquals("vk1", aliasSlot.getOneLevelColumn().get().getName());
+ }
}
diff --git a/regression-test/data/query_p0/topn_lazy/lazy_materialize_view.out b/regression-test/data/query_p0/topn_lazy/lazy_materialize_view.out
new file mode 100644
index 00000000000..90b9d05460f
--- /dev/null
+++ b/regression-test/data/query_p0/topn_lazy/lazy_materialize_view.out
@@ -0,0 +1,13 @@
+-- This file is automatically generated. You should know what you did if you want to edit this
+-- !view_lazy --
+aaa
+bbb
+
+-- !chain_view_lazy --
+aaa
+bbb
+
+-- !view_lazy_filter --
+bbb 200
+ccc 300
+
diff --git a/regression-test/suites/mysql_compatibility_p0/metadata.groovy b/regression-test/suites/mysql_compatibility_p0/metadata.groovy
index f6b303dbfd6..284347a6b97 100644
--- a/regression-test/suites/mysql_compatibility_p0/metadata.groovy
+++ b/regression-test/suites/mysql_compatibility_p0/metadata.groovy
@@ -63,8 +63,8 @@ suite ("metadata") {
println viewMeta
assertEquals("c1", viewMeta.getColumnName(1))
- assertEquals("vk1", viewMeta.getColumnName(2))
- assertEquals("vk1", viewMeta.getColumnName(3))
+ assertEquals("vk1", viewMeta.getColumnName(2),"viewMeta.getColumnName(2)")
+ assertEquals("vk1", viewMeta.getColumnName(3), "viewMeta.getColumnName(3)")
assertEquals("k2", viewMeta.getColumnName(4))
assertEquals("k2", viewMeta.getColumnName(5))
assertEquals("c4", viewMeta.getColumnName(6))
diff --git a/regression-test/suites/query_p0/topn_lazy/lazy_materialize_view.groovy b/regression-test/suites/query_p0/topn_lazy/lazy_materialize_view.groovy
new file mode 100644
index 00000000000..8e58ddaa7cb
--- /dev/null
+++ b/regression-test/suites/query_p0/topn_lazy/lazy_materialize_view.groovy
@@ -0,0 +1,84 @@
+// 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.
+
+suite("lazy_materialize_view") {
+ sql """
+ set enable_two_phase_read_opt = true;
+ set topn_opt_limit_threshold = 1000;
+ set topn_lazy_materialization_threshold = -1;
+ """
+
+ sql "drop table if exists lazy_mat_view_t"
+ sql """
+ CREATE TABLE lazy_mat_view_t (
+ k1 INT NOT NULL,
+ k2 INT NOT NULL,
+ v1 VARCHAR(100) NULL,
+ v2 INT NULL
+ )
+ DUPLICATE KEY(k1)
+ DISTRIBUTED BY HASH(k1) BUCKETS 1
+ PROPERTIES (
+ "replication_num" = "1"
+ );
+ """
+
+ sql """
+ insert into lazy_mat_view_t values
+ (1, 10, 'aaa', 100),
+ (2, 20, 'bbb', 200),
+ (3, 30, 'ccc', 300);
+ """
+
+ sql "sync"
+
+ sql "drop view if exists lazy_mat_view_v1"
+ sql "CREATE VIEW lazy_mat_view_v1 AS SELECT * FROM lazy_mat_view_t"
+
+ sql "drop view if exists lazy_mat_view_v2"
+ sql "CREATE VIEW lazy_mat_view_v2 AS SELECT * FROM lazy_mat_view_v1"
+
+ // lazy materialization through a single-level view
+ explain {
+ sql "select v1 from lazy_mat_view_v1 order by k1 limit 2"
+ contains "OPT TWO PHASE"
+ }
+
+ order_qt_view_lazy """
+ select v1 from lazy_mat_view_v1 order by k1 limit 2
+ """
+
+ // lazy materialization through a chained view (v2 -> v1 -> t)
+ explain {
+ sql "select v1 from lazy_mat_view_v2 order by k1 limit 2"
+ contains "OPT TWO PHASE"
+ }
+
+ order_qt_chain_view_lazy """
+ select v1 from lazy_mat_view_v2 order by k1 limit 2
+ """
+
+ // lazy materialization through view with filter
+ explain {
+ sql "select v1, v2 from lazy_mat_view_v1 where k2 > 10 order by k1 limit 2"
+ contains "OPT TWO PHASE"
+ }
+
+ order_qt_view_lazy_filter """
+ select v1, v2 from lazy_mat_view_v1 where k2 > 10 order by k1 limit 2
+ """
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org