Skip to content

Commit 11013d1

Browse files
authored
ide: table alias goto def support (#791)
1 parent 47890ef commit 11013d1

File tree

2 files changed

+100
-1
lines changed

2 files changed

+100
-1
lines changed

crates/squawk_ide/src/goto_definition.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2452,4 +2452,56 @@ drop aggregate sum$0(bigint);
24522452
╰╴ ─ 1. source
24532453
");
24542454
}
2455+
2456+
#[test]
2457+
fn goto_table_alias_in_qualified_column() {
2458+
assert_snapshot!(goto("
2459+
create table t(a int8, b text);
2460+
select f$0.a from t as f;
2461+
"), @r"
2462+
╭▸
2463+
3 │ select f.a from t as f;
2464+
╰╴ ─ 1. source ─ 2. destination
2465+
");
2466+
}
2467+
2468+
#[test]
2469+
fn goto_column_through_table_alias() {
2470+
assert_snapshot!(goto("
2471+
create table t(a int8, b text);
2472+
select f.a$0 from t as f;
2473+
"), @r"
2474+
╭▸
2475+
2 │ create table t(a int8, b text);
2476+
│ ─ 2. destination
2477+
3 │ select f.a from t as f;
2478+
╰╴ ─ 1. source
2479+
");
2480+
}
2481+
2482+
#[test]
2483+
fn goto_cte_alias_renamed_column() {
2484+
assert_snapshot!(goto("
2485+
with t as (select 1 a, 2 b)
2486+
select f.x$0 from t as f(x);
2487+
"), @r"
2488+
╭▸
2489+
3 │ select f.x from t as f(x);
2490+
╰╴ ─ 1. source ─ 2. destination
2491+
");
2492+
}
2493+
2494+
#[test]
2495+
fn goto_cte_alias_unrenamed_column() {
2496+
assert_snapshot!(goto("
2497+
with t as (select 1 a, 2 b)
2498+
select f.b$0 from t as f(x);
2499+
"), @r"
2500+
╭▸
2501+
2 │ with t as (select 1 a, 2 b)
2502+
│ ─ 2. destination
2503+
3 │ select f.b from t as f(x);
2504+
╰╴ ─ 1. source
2505+
");
2506+
}
24552507
}

crates/squawk_ide/src/resolve.rs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,12 @@ fn resolve_select_qualified_column_table(
552552
let from_clause = select.from_clause()?;
553553
let from_item = from_clause.from_items().next()?;
554554

555+
if let Some(alias_name) = from_item.alias().and_then(|a| a.name())
556+
&& Name::from_node(&alias_name) == table_name
557+
{
558+
return Some(SyntaxNodePtr::new(alias_name.syntax()));
559+
}
560+
555561
let (table_name, schema) = if let Some(name_ref_node) = from_item.name_ref() {
556562
// `from foo`
557563
let from_table_name = Name::from_node(&name_ref_node);
@@ -618,7 +624,48 @@ fn resolve_select_qualified_column(
618624
let from_clause = select.from_clause()?;
619625
let from_item = from_clause.from_items().next()?;
620626

621-
if let Some(name_ref_node) = from_item.name_ref() {
627+
// `from t as u`
628+
// `from t as u(a, b, c)`
629+
if let Some(alias) = from_item.alias()
630+
&& let Some(alias_name) = alias.name()
631+
&& Name::from_node(&alias_name) == column_table_name
632+
{
633+
// `from t as u(a, b, c)`
634+
if let Some(column_list) = alias.column_list() {
635+
for column in column_list.columns() {
636+
if let Some(col_name) = column.name()
637+
&& Name::from_node(&col_name) == column_name
638+
{
639+
return Some(SyntaxNodePtr::new(col_name.syntax()));
640+
}
641+
}
642+
643+
// ```sql
644+
// create table t(a int, b int);
645+
// select b from t as u(x);
646+
// ^
647+
// ```
648+
if let Some(name_ref_node) = from_item.name_ref() {
649+
let cte_name = Name::from_node(&name_ref_node);
650+
return resolve_cte_column(name_ref, &cte_name, &column_name);
651+
}
652+
}
653+
654+
// `from t as u`
655+
if let Some(name_ref_node) = from_item.name_ref() {
656+
(Name::from_node(&name_ref_node), None)
657+
// `from foo.t as u`
658+
} else if let Some(from_field_expr) = from_item.field_expr() {
659+
let table_name = Name::from_node(&from_field_expr.field()?);
660+
let ast::Expr::NameRef(schema_name_ref) = from_field_expr.base()? else {
661+
return None;
662+
};
663+
let schema = Schema(Name::from_node(&schema_name_ref));
664+
(table_name, Some(schema))
665+
} else {
666+
return None;
667+
}
668+
} else if let Some(name_ref_node) = from_item.name_ref() {
622669
// `from bar`
623670
let from_table_name = Name::from_node(&name_ref_node);
624671
if from_table_name == column_table_name {

0 commit comments

Comments
 (0)