Skip to content

Commit 680274a

Browse files
authored
ide: goto def with insert/delete & CTE (#794)
1 parent 8654db7 commit 680274a

File tree

4 files changed

+107
-10
lines changed

4 files changed

+107
-10
lines changed

crates/squawk_ide/src/goto_definition.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3002,4 +3002,79 @@ select messages.message$0 from users left join messages on users.id = messages.u
30023002
╰╴ ─ 1. source
30033003
");
30043004
}
3005+
3006+
#[test]
3007+
fn goto_insert_select_cte_column() {
3008+
assert_snapshot!(goto("
3009+
create table users(id int, email text);
3010+
with new_data as (
3011+
select 1 as id, '[email protected]' as email
3012+
)
3013+
insert into users (id, email)
3014+
select id$0, email from new_data;
3015+
"), @r"
3016+
╭▸
3017+
4 │ select 1 as id, '[email protected]' as email
3018+
│ ── 2. destination
3019+
3020+
7 │ select id, email from new_data;
3021+
╰╴ ─ 1. source
3022+
");
3023+
}
3024+
3025+
#[test]
3026+
fn goto_insert_select_cte_column_second() {
3027+
assert_snapshot!(goto("
3028+
create table users(id int, email text);
3029+
with new_data as (
3030+
select 1 as id, '[email protected]' as email
3031+
)
3032+
insert into users (id, email)
3033+
select id, email$0 from new_data;
3034+
"), @r"
3035+
╭▸
3036+
4 │ select 1 as id, '[email protected]' as email
3037+
│ ───── 2. destination
3038+
3039+
7 │ select id, email from new_data;
3040+
╰╴ ─ 1. source
3041+
");
3042+
}
3043+
3044+
#[test]
3045+
fn goto_insert_select_cte_table() {
3046+
assert_snapshot!(goto("
3047+
create table users(id int, email text);
3048+
with new_data as (
3049+
select 1 as id, '[email protected]' as email
3050+
)
3051+
insert into users (id, email)
3052+
select id, email from new_data$0;
3053+
"), @r"
3054+
╭▸
3055+
3 │ with new_data as (
3056+
│ ──────── 2. destination
3057+
3058+
7 │ select id, email from new_data;
3059+
╰╴ ─ 1. source
3060+
");
3061+
}
3062+
3063+
#[test]
3064+
fn goto_delete_cte_column() {
3065+
assert_snapshot!(goto("
3066+
create table users(id int, email text);
3067+
with old_data as (
3068+
select 1 as id
3069+
)
3070+
delete from users where id in (select id$0 from old_data);
3071+
"), @r"
3072+
╭▸
3073+
4 │ select 1 as id
3074+
│ ── 2. destination
3075+
5 │ )
3076+
6 │ delete from users where id in (select id from old_data);
3077+
╰╴ ─ 1. source
3078+
");
3079+
}
30053080
}

crates/squawk_ide/src/resolve.rs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rowan::{TextRange, TextSize};
22
use squawk_syntax::{
3-
SyntaxNodePtr,
3+
SyntaxNode, SyntaxNodePtr,
44
ast::{self, AstNode},
55
};
66

@@ -1120,9 +1120,7 @@ pub(crate) fn find_column_in_table(
11201120
}
11211121

11221122
fn resolve_cte_table(name_ref: &ast::NameRef, cte_name: &Name) -> Option<SyntaxNodePtr> {
1123-
let select = name_ref.syntax().ancestors().find_map(ast::Select::cast)?;
1124-
let with_clause = select.with_clause()?;
1125-
1123+
let with_clause = find_parent_with_clause(name_ref.syntax())?;
11261124
for with_table in with_clause.with_tables() {
11271125
if let Some(name) = with_table.name()
11281126
&& Name::from_node(&name) == *cte_name
@@ -1134,17 +1132,26 @@ fn resolve_cte_table(name_ref: &ast::NameRef, cte_name: &Name) -> Option<SyntaxN
11341132
None
11351133
}
11361134

1135+
fn find_parent_with_clause(node: &SyntaxNode) -> Option<ast::WithClause> {
1136+
node.ancestors().find_map(|x| {
1137+
if let Some(select) = ast::Select::cast(x.clone()) {
1138+
select.with_clause()
1139+
} else if let Some(delete) = ast::Delete::cast(x.clone()) {
1140+
delete.with_clause()
1141+
} else if let Some(insert) = ast::Insert::cast(x) {
1142+
insert.with_clause()
1143+
} else {
1144+
None
1145+
}
1146+
})
1147+
}
1148+
11371149
fn resolve_cte_column(
11381150
name_ref: &ast::NameRef,
11391151
cte_name: &Name,
11401152
column_name: &Name,
11411153
) -> Option<SyntaxNodePtr> {
1142-
let select = name_ref
1143-
.syntax()
1144-
.ancestors()
1145-
.filter_map(ast::Select::cast)
1146-
.find(|s| s.with_clause().is_some())?;
1147-
let with_clause = select.with_clause()?;
1154+
let with_clause = find_parent_with_clause(name_ref.syntax())?;
11481155

11491156
for with_table in with_clause.with_tables() {
11501157
if let Some(name) = with_table.name()

crates/squawk_syntax/src/ast/generated/nodes.rs

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/squawk_syntax/src/postgresql.ungram

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,6 +1263,7 @@ Table =
12631263
'table' RelationName
12641264

12651265
Insert =
1266+
WithClause?
12661267
'insert' 'into' Path Alias? ColumnList?
12671268
('overriding' ('system' | 'user') 'value')?
12681269
('default' 'values' | Values | Stmt)
@@ -1326,6 +1327,7 @@ SetExpr =
13261327
| 'default'
13271328

13281329
Update =
1330+
WithClause?
13291331
'update'
13301332
RelationName
13311333
Alias?
@@ -1348,6 +1350,7 @@ ReturningOption =
13481350
Name
13491351

13501352
Delete =
1353+
WithClause?
13511354
'delete' 'from' RelationName Alias?
13521355
UsingClause?
13531356
(WhereClause | WhereCurrentOf)?

0 commit comments

Comments
 (0)