diff --git a/src/Processors/QueryPlan/Optimizations/optimizeLazyMaterialization.cpp b/src/Processors/QueryPlan/Optimizations/optimizeLazyMaterialization.cpp index a2f5275fd0f1..dcb123e82ad2 100644 --- a/src/Processors/QueryPlan/Optimizations/optimizeLazyMaterialization.cpp +++ b/src/Processors/QueryPlan/Optimizations/optimizeLazyMaterialization.cpp @@ -38,6 +38,7 @@ static void removeUsedColumnNames( String filter_name = {}) { const auto & actions_outputs = actions.getOutputs(); + NameSet passthrough_inputs; for (const auto * output_node : actions_outputs) { @@ -52,6 +53,16 @@ static void removeUsedColumnNames( if (!node) continue; + /// The lazy reader maps each source column to a single output name. If an input + /// is forwarded more than once (for example, both a column and its alias), read + /// it eagerly so all outputs contain real data and do not duplicate lazy row coordinates. + if (node->type == ActionsDAG::ActionType::INPUT && !passthrough_inputs.insert(node->result_name).second) + { + const auto it = alias_index.find(node->result_name); + if (it != alias_index.end()) + lazily_read_column_name_set.erase(it->second); + } + if (node->type == ActionsDAG::ActionType::FUNCTION || node->type == ActionsDAG::ActionType::ARRAY_JOIN || (!filter_name.empty() && filter_name == output_node->result_name)) { diff --git a/tests/queries/0_stateless/05317_aliases_and_lazy_materialization.reference b/tests/queries/0_stateless/05317_aliases_and_lazy_materialization.reference new file mode 100644 index 000000000000..538e1e60ef5c --- /dev/null +++ b/tests/queries/0_stateless/05317_aliases_and_lazy_materialization.reference @@ -0,0 +1,10 @@ +99 99 +98 98 +97 97 +96 96 +95 95 +94 94 +93 93 +92 92 +91 91 +90 90 diff --git a/tests/queries/0_stateless/05317_aliases_and_lazy_materialization.sql b/tests/queries/0_stateless/05317_aliases_and_lazy_materialization.sql new file mode 100644 index 000000000000..178ace2a6471 --- /dev/null +++ b/tests/queries/0_stateless/05317_aliases_and_lazy_materialization.sql @@ -0,0 +1,15 @@ +-- Tags: no-random-settings + +SET query_plan_optimize_lazy_materialization = 1; +SET query_plan_max_limit_for_lazy_materialization = 10; +SET enable_analyzer = 1; + +DROP TABLE IF EXISTS t_str; +CREATE TABLE t_str (id UInt64, ts DateTime, s String, s_alias String ALIAS s) +ENGINE = MergeTree ORDER BY id; +INSERT INTO t_str SELECT number, toDateTime('2026-01-01 00:00:00') + number, toString(number) FROM numbers(100); + +-- Selecting both the source column and its alias must materialize both outputs. +SELECT s, s_alias FROM t_str ORDER BY ts DESC LIMIT 10; + +DROP TABLE t_str;