diff --git a/crates/squawk_ide/src/goto_definition.rs b/crates/squawk_ide/src/goto_definition.rs index 02526360..0f0cfeb2 100644 --- a/crates/squawk_ide/src/goto_definition.rs +++ b/crates/squawk_ide/src/goto_definition.rs @@ -3243,6 +3243,79 @@ select a$0 from (select u.* from t join u on a = b); ); } + #[test] + fn goto_subquery_column_alias_list() { + assert_snapshot!(goto(" +select c$0, t.c from (select 1) t(c); +"), @r" + ╭▸ + 2 │ select c, t.c from (select 1) t(c); + ╰╴ ─ 1. source ─ 2. destination + "); + } + + #[test] + fn goto_subquery_column_alias_list_qualified() { + assert_snapshot!(goto(" +select t.c$0 from (select 1) t(c); +"), @r" + ╭▸ + 2 │ select t.c from (select 1) t(c); + ╰╴ ─ 1. source ─ 2. destination + "); + } + + #[test] + fn goto_subquery_column_alias_list_multiple() { + assert_snapshot!(goto(" +select b$0 from (select 1, 2) t(a, b); +"), @r" + ╭▸ + 2 │ select b from (select 1, 2) t(a, b); + ╰╴ ─ 1. source ─ 2. destination + "); + } + + #[test] + fn goto_cte_column_alias_list() { + assert_snapshot!(goto(" +with x as (select 1) +select c$0 from x t(c); +"), @r" + ╭▸ + 3 │ select c from x t(c); + │ ┬ ─ 2. destination + │ │ + ╰╴ 1. source + "); + } + + #[test] + fn goto_cte_column_alias_list_qualified() { + assert_snapshot!(goto(" +with x as (select 1) +select t.c$0 from x t(c); +"), @r" + ╭▸ + 3 │ select t.c from x t(c); + │ ┬ ─ 2. destination + │ │ + ╰╴ 1. source + "); + } + + #[test] + fn goto_cte_column_alias_list_multiple() { + assert_snapshot!(goto(" +with x as (select 1, 2) +select b$0 from x t(a, b); +"), @r" + ╭▸ + 3 │ select b from x t(a, b); + ╰╴ ─ 1. source ─ 2. destination + "); + } + #[test] fn goto_insert_table() { assert_snapshot!(goto(" diff --git a/crates/squawk_ide/src/resolve.rs b/crates/squawk_ide/src/resolve.rs index 46225164..03e205fe 100644 --- a/crates/squawk_ide/src/resolve.rs +++ b/crates/squawk_ide/src/resolve.rs @@ -863,6 +863,7 @@ fn resolve_select_qualified_column_ptr( &paren_select, column_name_ref, &column_name, + Some(&alias), ); } @@ -1029,7 +1030,15 @@ fn resolve_from_item_column_ptr( ) -> Option { let column_name = Name::from_node(column_name_ref); if let Some(paren_select) = from_item.paren_select() { - return resolve_subquery_column(binder, root, &paren_select, column_name_ref, &column_name); + let alias = from_item.alias(); + return resolve_subquery_column( + binder, + root, + &paren_select, + column_name_ref, + &column_name, + alias.as_ref(), + ); } if let Some(paren_expr) = from_item.paren_expr() { @@ -1042,6 +1051,18 @@ fn resolve_from_item_column_ptr( ); } + if let Some(alias) = from_item.alias() + && let Some(column_list) = alias.column_list() + { + for col in column_list.columns() { + if let Some(col_name) = col.name() + && Name::from_node(&col_name) == column_name + { + return Some(SyntaxNodePtr::new(col_name.syntax())); + } + } + } + let (table_name, schema) = table_and_schema_from_from_item(from_item)?; if schema.is_none() @@ -1912,6 +1933,7 @@ fn resolve_subquery_column( paren_select: &ast::ParenSelect, name_ref: &ast::NameRef, column_name: &Name, + alias: Option<&ast::Alias>, ) -> Option { let select_variant = paren_select.select()?; let ast::SelectVariant::Select(subquery_select) = select_variant else { @@ -1921,6 +1943,19 @@ fn resolve_subquery_column( let select_clause = subquery_select.select_clause()?; let target_list = select_clause.target_list()?; + if let Some(alias) = alias + && let Some(column_list) = alias.column_list() + { + for col in column_list.columns() { + if let Some(col_name) = col.name() + && Name::from_node(&col_name) == *column_name + { + return Some(SyntaxNodePtr::new(col_name.syntax())); + } + } + return None; + } + for target in target_list.targets() { if let Some((col_name, node)) = ColumnName::from_target(target.clone()) { if let Some(col_name_str) = col_name.to_string() @@ -2511,7 +2546,15 @@ fn resolve_column_from_paren_expr( if let Some(from_item) = paren_expr.from_item() && let Some(paren_select) = from_item.paren_select() { - return resolve_subquery_column(binder, root, &paren_select, name_ref, column_name); + let alias = from_item.alias(); + return resolve_subquery_column( + binder, + root, + &paren_select, + name_ref, + column_name, + alias.as_ref(), + ); } None