Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ public PhysicalLazyMaterialize(CHILD_TYPE child,
}
outputBuilder.add(outputSlot);
lazyColumnForRel.add(originalColumn);
lazyBaseColumnIdxForRel.add(relationTable.getBaseColumnIdxByName(lazySlot.getName()));
lazyBaseColumnIdxForRel.add(relationTable.getBaseColumnIdxByName(originalColumn.getName()));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Handle repeated aliases of one physical lazy column

Project(n1, n2)
  TopN(order by id)
    Project(name AS n1, name AS n2, id)
      HiveScan(id, name)

The aliases have distinct ExprIds, so this loop appends the same originalColumn twice and sends column_descs_lists = [[name, name]] with indices [[1, 1]]. Thrift derives both slot names from the physical Column. In the phase-two positional ORC reader, slot_map consequently has one name entry; the first index erases it and the second dereferences the null inserted by slot_map["name"] (be/src/format/table/hive_reader.cpp:64-83). Parquet has the same sequence at lines 252-272. Thus this valid query can crash even after the single-alias fix. Please deduplicate fetches by relation/base column/access path and fan the value out to both output locations, or preserve unique transport identities, and add an executed duplicate-alias ORC/Parquet regression.

lazySlotLocationForRel.add(loc);
loc++;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import org.apache.doris.nereids.glue.translator.PhysicalPlanTranslator;
import org.apache.doris.nereids.glue.translator.PlanTranslatorContext;
import org.apache.doris.nereids.processor.post.PlanPostProcessors;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.physical.PhysicalLazyMaterialize;
import org.apache.doris.nereids.trees.plans.physical.PhysicalPlan;
import org.apache.doris.nereids.util.PlanChecker;
import org.apache.doris.planner.MaterializationNode;
Expand Down Expand Up @@ -117,6 +119,29 @@ public void testNestedColumnAccessPathInLazyMaterialize() throws Exception {
ColumnAccessPath.data(ImmutableList.of("user_profile", "professional", "skills"))));
}

@Test
public void testLazyBaseColumnIndexUsesOriginalColumnNameForAlias() throws Exception {
this.createTable("create table lazy_materialize_alias_tbl("
+ "sort_col int, lazy_col int) "
+ "duplicate key(sort_col) distributed by hash(sort_col) buckets 1 "
+ "properties('replication_num' = '1')");
String sql = "select lazy_col as lazy_alias from lazy_materialize_alias_tbl "
+ "order by sort_col limit 1";

PlanChecker checker = PlanChecker.from(connectContext)
.analyze(sql)
.rewrite()
.implement();
PhysicalPlan plan = checker.getPhysicalPlan();
plan = new PlanPostProcessors(checker.getCascadesContext()).process(plan);

List<PhysicalLazyMaterialize<? extends Plan>> materializeNodes = plan.collectToList(
node -> node instanceof PhysicalLazyMaterialize);
Assertions.assertEquals(1, materializeNodes.size(), plan.treeString());
Assertions.assertEquals(ImmutableList.of(ImmutableList.of(1)),
materializeNodes.get(0).getLazyBaseColumnIndices());
}

@Test
public void testLightSchemaChangeFalse() throws Exception {
this.createTable("create table tm_lsc_false (k int, v int) duplicate key(k) "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,15 @@ suite("test_hive_topn_lazy_mat", "p0,external") {
contains("row_ids: [__DORIS_GLOBAL_ROWID_COL__orc_topn_lazy_mat_table]")
}

// Output aliases must not be used to resolve physical Hive column indices.
explain {
sql "select name as lazy_alias from orc_topn_lazy_mat_table order by id limit 10;"
contains("VMaterializeNode")
contains("column_descs_lists[[`name` text NULL]]")
contains("column_idxs_lists: [[1]]")
contains("row_ids: [__DORIS_GLOBAL_ROWID_COL__orc_topn_lazy_mat_table]")
}

explain {
sql """ select a.name,length(a.name),a.value,b.*,a.* from parquet_topn_lazy_mat_table as a
join orc_topn_lazy_mat_table as b on a.id = b.id order by a.name limit 10 """
Expand Down
Loading