Skip to content

Commit e0166d3

Browse files
authored
ide: hover with update (#796)
1 parent 1e09b23 commit e0166d3

File tree

3 files changed

+186
-162
lines changed

3 files changed

+186
-162
lines changed

crates/squawk_ide/src/hover.rs

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ pub fn hover(file: &ast::SourceFile, offset: TextSize) -> Option<String> {
1010

1111
let binder = binder::bind(file);
1212

13+
// TODO: can we use the classify_name_ref_context function from goto def here?
1314
if let Some(name_ref) = ast::NameRef::cast(parent.clone()) {
1415
if is_column_ref(&name_ref) {
1516
return hover_column(file, &name_ref, &binder);
@@ -36,6 +37,10 @@ pub fn hover(file: &ast::SourceFile, offset: TextSize) -> Option<String> {
3637
return hover_table(file, &name_ref, &binder);
3738
}
3839

40+
if is_update_from_table(&name_ref) {
41+
return hover_table(file, &name_ref, &binder);
42+
}
43+
3944
if is_index_ref(&name_ref) {
4045
return hover_index(file, &name_ref, &binder);
4146
}
@@ -306,6 +311,7 @@ fn is_column_ref(name_ref: &ast::NameRef) -> bool {
306311
let mut in_partition_item = false;
307312
let mut in_column_list = false;
308313
let mut in_where_clause = false;
314+
let mut in_set_clause = false;
309315

310316
for ancestor in name_ref.syntax().ancestors() {
311317
if ast::PartitionItem::can_cast(ancestor.kind()) {
@@ -323,9 +329,15 @@ fn is_column_ref(name_ref: &ast::NameRef) -> bool {
323329
if ast::WhereClause::can_cast(ancestor.kind()) {
324330
in_where_clause = true;
325331
}
332+
if ast::SetClause::can_cast(ancestor.kind()) {
333+
in_set_clause = true;
334+
}
326335
if ast::Delete::can_cast(ancestor.kind()) {
327336
return in_where_clause;
328337
}
338+
if ast::Update::can_cast(ancestor.kind()) {
339+
return in_where_clause || in_set_clause;
340+
}
329341
}
330342
false
331343
}
@@ -334,6 +346,8 @@ fn is_table_ref(name_ref: &ast::NameRef) -> bool {
334346
let mut in_partition_item = false;
335347
let mut in_column_list = false;
336348
let mut in_where_clause = false;
349+
let mut in_set_clause = false;
350+
let mut in_from_clause = false;
337351

338352
for ancestor in name_ref.syntax().ancestors() {
339353
if ast::DropTable::can_cast(ancestor.kind()) {
@@ -351,9 +365,18 @@ fn is_table_ref(name_ref: &ast::NameRef) -> bool {
351365
if ast::WhereClause::can_cast(ancestor.kind()) {
352366
in_where_clause = true;
353367
}
368+
if ast::SetClause::can_cast(ancestor.kind()) {
369+
in_set_clause = true;
370+
}
371+
if ast::FromClause::can_cast(ancestor.kind()) {
372+
in_from_clause = true;
373+
}
354374
if ast::Delete::can_cast(ancestor.kind()) {
355375
return !in_where_clause;
356376
}
377+
if ast::Update::can_cast(ancestor.kind()) {
378+
return !in_where_clause && !in_set_clause && !in_from_clause;
379+
}
357380
if ast::DropIndex::can_cast(ancestor.kind()) {
358381
return false;
359382
}
@@ -453,6 +476,20 @@ fn is_select_from_table(name_ref: &ast::NameRef) -> bool {
453476
false
454477
}
455478

479+
fn is_update_from_table(name_ref: &ast::NameRef) -> bool {
480+
let mut in_from_clause = false;
481+
482+
for ancestor in name_ref.syntax().ancestors() {
483+
if ast::FromClause::can_cast(ancestor.kind()) {
484+
in_from_clause = true;
485+
}
486+
if ast::Update::can_cast(ancestor.kind()) && in_from_clause {
487+
return true;
488+
}
489+
}
490+
false
491+
}
492+
456493
fn is_select_column(name_ref: &ast::NameRef) -> bool {
457494
let mut in_call_expr = false;
458495
let mut in_arg_list = false;
@@ -2237,4 +2274,110 @@ drop routine foo$0(int);
22372274
╰╴ ─ hover
22382275
");
22392276
}
2277+
2278+
#[test]
2279+
fn hover_on_update_table() {
2280+
assert_snapshot!(check_hover("
2281+
create table users(id int, email text);
2282+
update users$0 set email = '[email protected]';
2283+
"), @r"
2284+
hover: table public.users(id int, email text)
2285+
╭▸
2286+
3 │ update users set email = '[email protected]';
2287+
╰╴ ─ hover
2288+
");
2289+
}
2290+
2291+
#[test]
2292+
fn hover_on_update_table_with_schema() {
2293+
assert_snapshot!(check_hover("
2294+
create table public.users(id int, email text);
2295+
update public.users$0 set email = '[email protected]';
2296+
"), @r"
2297+
hover: table public.users(id int, email text)
2298+
╭▸
2299+
3 │ update public.users set email = '[email protected]';
2300+
╰╴ ─ hover
2301+
");
2302+
}
2303+
2304+
#[test]
2305+
fn hover_on_update_set_column() {
2306+
assert_snapshot!(check_hover("
2307+
create table users(id int, email text);
2308+
update users set email$0 = '[email protected]' where id = 1;
2309+
"), @r"
2310+
hover: column public.users.email text
2311+
╭▸
2312+
3 │ update users set email = '[email protected]' where id = 1;
2313+
╰╴ ─ hover
2314+
");
2315+
}
2316+
2317+
#[test]
2318+
fn hover_on_update_set_column_with_schema() {
2319+
assert_snapshot!(check_hover("
2320+
create table public.users(id int, email text);
2321+
update public.users set email$0 = '[email protected]' where id = 1;
2322+
"), @r"
2323+
hover: column public.users.email text
2324+
╭▸
2325+
3 │ update public.users set email = '[email protected]' where id = 1;
2326+
╰╴ ─ hover
2327+
");
2328+
}
2329+
2330+
#[test]
2331+
fn hover_on_update_where_column() {
2332+
assert_snapshot!(check_hover("
2333+
create table users(id int, email text);
2334+
update users set email = '[email protected]' where id$0 = 1;
2335+
"), @r"
2336+
hover: column public.users.id int
2337+
╭▸
2338+
3 │ update users set email = '[email protected]' where id = 1;
2339+
╰╴ ─ hover
2340+
");
2341+
}
2342+
2343+
#[test]
2344+
fn hover_on_update_where_column_with_schema() {
2345+
assert_snapshot!(check_hover("
2346+
create table public.users(id int, email text);
2347+
update public.users set email = '[email protected]' where id$0 = 1;
2348+
"), @r"
2349+
hover: column public.users.id int
2350+
╭▸
2351+
3 │ update public.users set email = '[email protected]' where id = 1;
2352+
╰╴ ─ hover
2353+
");
2354+
}
2355+
2356+
#[test]
2357+
fn hover_on_update_from_table() {
2358+
assert_snapshot!(check_hover("
2359+
create table users(id int, email text);
2360+
create table messages(id int, user_id int, email text);
2361+
update users set email = messages.email from messages$0 where users.id = messages.user_id;
2362+
"), @r"
2363+
hover: table public.messages(id int, user_id int, email text)
2364+
╭▸
2365+
4 │ update users set email = messages.email from messages where users.id = messages.user_id;
2366+
╰╴ ─ hover
2367+
");
2368+
}
2369+
2370+
#[test]
2371+
fn hover_on_update_from_table_with_schema() {
2372+
assert_snapshot!(check_hover("
2373+
create table users(id int, email text);
2374+
create table public.messages(id int, user_id int, email text);
2375+
update users set email = messages.email from public.messages$0 where users.id = messages.user_id;
2376+
"), @r"
2377+
hover: table public.messages(id int, user_id int, email text)
2378+
╭▸
2379+
4 │ update users set email = messages.email from public.messages where users.id = messages.user_id;
2380+
╰╴ ─ hover
2381+
");
2382+
}
22402383
}

crates/squawk_ide/src/inlay_hints.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,22 +87,22 @@ fn inlay_hint_insert(
8787
let row_list = values.row_list()?;
8888

8989
let columns: Vec<(Name, Option<TextRange>)> = if let Some(column_list) = insert.column_list() {
90-
let table_arg_list = resolve::resolve_insert_table_columns(file, binder, &insert);
91-
90+
let create_table = resolve::resolve_insert_create_table(file, binder, &insert);
9291
column_list
9392
.columns()
9493
.filter_map(|col| {
9594
let col_name = resolve::extract_column_name(&col)?;
96-
let target = table_arg_list
95+
let target = create_table
9796
.as_ref()
98-
.and_then(|list| resolve::find_column_in_table(list, &col_name));
97+
.and_then(|x| resolve::find_column_in_create_table(x, &col_name))
98+
.map(|x| x.text_range());
9999
Some((col_name, target))
100100
})
101101
.collect()
102102
} else {
103-
let table_arg_list = resolve::resolve_insert_table_columns(file, binder, &insert)?;
104-
105-
table_arg_list
103+
let create_table = resolve::resolve_insert_create_table(file, binder, &insert)?;
104+
create_table
105+
.table_arg_list()?
106106
.args()
107107
.filter_map(|arg| {
108108
if let ast::TableArg::Column(column) = arg

0 commit comments

Comments
 (0)