Skip to content

Commit d76d918

Browse files
committed
Fix target alias collection in physical planner
Update the alias collection logic to only traverse the update target branch, preventing self-join source aliases from being confused with target aliases. Add a regression test ensuring the correct assignment of src.a in the UPDATE statement for improved accuracy in query execution.
1 parent 2b5aa22 commit d76d918

1 file changed

Lines changed: 38 additions & 8 deletions

File tree

datafusion/core/src/physical_planner.rs

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2332,16 +2332,30 @@ fn collect_target_refs(
23322332
target: &TableReference,
23332333
) -> Result<Vec<TableReference>> {
23342334
let mut target_refs = vec![target.clone()];
2335-
input.apply(|node| {
2336-
if let LogicalPlan::SubqueryAlias(alias) = node
2337-
&& let LogicalPlan::TableScan(scan) = alias.input.as_ref()
2338-
&& scan.table_name.resolved_eq(target)
2339-
{
2335+
collect_target_refs_from_target_branch(input, &mut target_refs)?;
2336+
Ok(target_refs)
2337+
}
2338+
2339+
fn collect_target_refs_from_target_branch(
2340+
input: &Arc<LogicalPlan>,
2341+
target_refs: &mut Vec<TableReference>,
2342+
) -> Result<()> {
2343+
match input.as_ref() {
2344+
LogicalPlan::Projection(projection) => {
2345+
collect_target_refs_from_target_branch(&projection.input, target_refs)
2346+
}
2347+
LogicalPlan::Filter(filter) => {
2348+
collect_target_refs_from_target_branch(&filter.input, target_refs)
2349+
}
2350+
LogicalPlan::Join(join) => {
2351+
collect_target_refs_from_target_branch(&join.left, target_refs)
2352+
}
2353+
LogicalPlan::SubqueryAlias(alias) => {
23402354
target_refs.push(TableReference::bare(alias.alias.to_string()));
2355+
collect_target_refs_from_target_branch(&alias.input, target_refs)
23412356
}
2342-
Ok(TreeNodeRecursion::Continue)
2343-
})?;
2344-
Ok(target_refs)
2357+
_ => Ok(()),
2358+
}
23452359
}
23462360

23472361
fn normalize_update_assignment_expr(expr: Expr, strip_qualifiers: bool) -> Result<Expr> {
@@ -4907,6 +4921,22 @@ digraph {
49074921
);
49084922
}
49094923

4924+
#[tokio::test]
4925+
async fn test_extract_update_assignments_preserves_self_join_source_alias() {
4926+
let assignments = update_assignments_for_sql(
4927+
"UPDATE t1 AS target SET a = src.a FROM t1 AS src \
4928+
WHERE target.id = src.id",
4929+
)
4930+
.await
4931+
.unwrap();
4932+
4933+
let assignments: HashMap<_, _> = assignments.into_iter().collect();
4934+
assert_eq!(
4935+
assignments.get("a").map(ToString::to_string).as_deref(),
4936+
Some("src.a")
4937+
);
4938+
}
4939+
49104940
#[tokio::test]
49114941
async fn test_extract_update_assignments_strips_single_table_target_qualifiers() {
49124942
let assignments =

0 commit comments

Comments
 (0)