Skip to content

Commit 5eb5114

Browse files
authored
ide: support hover for delete, insert, and select targets (#773)
1 parent 5714d63 commit 5eb5114

File tree

3 files changed

+353
-13
lines changed

3 files changed

+353
-13
lines changed

crates/squawk_ide/src/goto_definition.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,4 +1340,61 @@ create table users(id int, email text);
13401340
╰╴ ───── 2. destination
13411341
");
13421342
}
1343+
1344+
#[test]
1345+
fn goto_select_column() {
1346+
assert_snapshot!(goto("
1347+
create table users(id int, email text);
1348+
select id$0 from users;
1349+
"), @r"
1350+
╭▸
1351+
2 │ create table users(id int, email text);
1352+
│ ── 2. destination
1353+
3 │ select id from users;
1354+
╰╴ ─ 1. source
1355+
");
1356+
}
1357+
1358+
#[test]
1359+
fn goto_select_column_second() {
1360+
assert_snapshot!(goto("
1361+
create table users(id int, email text);
1362+
select id, email$0 from users;
1363+
"), @r"
1364+
╭▸
1365+
2 │ create table users(id int, email text);
1366+
│ ───── 2. destination
1367+
3 │ select id, email from users;
1368+
╰╴ ─ 1. source
1369+
");
1370+
}
1371+
1372+
#[test]
1373+
fn goto_select_column_with_schema() {
1374+
assert_snapshot!(goto("
1375+
create table public.users(id int, email text);
1376+
select email$0 from public.users;
1377+
"), @r"
1378+
╭▸
1379+
2 │ create table public.users(id int, email text);
1380+
│ ───── 2. destination
1381+
3 │ select email from public.users;
1382+
╰╴ ─ 1. source
1383+
");
1384+
}
1385+
1386+
#[test]
1387+
fn goto_select_column_with_search_path() {
1388+
assert_snapshot!(goto("
1389+
set search_path to foo;
1390+
create table foo.users(id int, email text);
1391+
select id$0 from users;
1392+
"), @r"
1393+
╭▸
1394+
3 │ create table foo.users(id int, email text);
1395+
│ ── 2. destination
1396+
4 │ select id from users;
1397+
╰╴ ─ 1. source
1398+
");
1399+
}
13431400
}

crates/squawk_ide/src/hover.rs

Lines changed: 246 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ pub fn hover(file: &ast::SourceFile, offset: TextSize) -> Option<String> {
1515
return hover_column(file, &name_ref, &binder);
1616
}
1717

18+
if is_select_column(&name_ref) {
19+
return hover_column(file, &name_ref, &binder);
20+
}
21+
1822
if is_table_ref(&name_ref) {
1923
return hover_table(file, &name_ref, &binder);
2024
}
@@ -68,27 +72,28 @@ fn hover_column(
6872
name_ref: &ast::NameRef,
6973
binder: &binder::Binder,
7074
) -> Option<String> {
71-
let column_name = name_ref.syntax().text().to_string();
72-
73-
let create_index = name_ref
74-
.syntax()
75-
.ancestors()
76-
.find_map(ast::CreateIndex::cast)?;
77-
78-
let relation_name = create_index.relation_name()?;
79-
let path = relation_name.path()?;
80-
81-
let (schema, table_name) = resolve::resolve_table_info(binder, &path)?;
82-
8375
let column_ptr = resolve::resolve_name_ref(binder, name_ref)?;
8476

8577
let root = file.syntax();
8678
let column_name_node = column_ptr.to_node(root);
8779

8880
let column = column_name_node.ancestors().find_map(ast::Column::cast)?;
89-
81+
let column_name = column.name()?.syntax().text().to_string();
9082
let ty = column.ty()?;
9183

84+
let create_table = column
85+
.syntax()
86+
.ancestors()
87+
.find_map(ast::CreateTable::cast)?;
88+
let path = create_table.path()?;
89+
let table_name = path.segment()?.name()?.syntax().text().to_string();
90+
91+
let schema = if let Some(qualifier) = path.qualifier() {
92+
qualifier.syntax().text().to_string()
93+
} else {
94+
table_schema(&create_table, binder)?
95+
};
96+
9297
Some(format!(
9398
"{schema}.{table_name}.{column_name} {}",
9499
ty.syntax().text()
@@ -216,6 +221,8 @@ fn index_schema(create_index: &ast::CreateIndex, binder: &binder::Binder) -> Opt
216221

217222
fn is_column_ref(name_ref: &ast::NameRef) -> bool {
218223
let mut in_partition_item = false;
224+
let mut in_column_list = false;
225+
let mut in_where_clause = false;
219226

220227
for ancestor in name_ref.syntax().ancestors() {
221228
if ast::PartitionItem::can_cast(ancestor.kind()) {
@@ -224,12 +231,26 @@ fn is_column_ref(name_ref: &ast::NameRef) -> bool {
224231
if ast::CreateIndex::can_cast(ancestor.kind()) {
225232
return in_partition_item;
226233
}
234+
if ast::ColumnList::can_cast(ancestor.kind()) {
235+
in_column_list = true;
236+
}
237+
if ast::Insert::can_cast(ancestor.kind()) {
238+
return in_column_list;
239+
}
240+
if ast::WhereClause::can_cast(ancestor.kind()) {
241+
in_where_clause = true;
242+
}
243+
if ast::Delete::can_cast(ancestor.kind()) {
244+
return in_where_clause;
245+
}
227246
}
228247
false
229248
}
230249

231250
fn is_table_ref(name_ref: &ast::NameRef) -> bool {
232251
let mut in_partition_item = false;
252+
let mut in_column_list = false;
253+
let mut in_where_clause = false;
233254

234255
for ancestor in name_ref.syntax().ancestors() {
235256
if ast::DropTable::can_cast(ancestor.kind()) {
@@ -238,6 +259,18 @@ fn is_table_ref(name_ref: &ast::NameRef) -> bool {
238259
if ast::Table::can_cast(ancestor.kind()) {
239260
return true;
240261
}
262+
if ast::ColumnList::can_cast(ancestor.kind()) {
263+
in_column_list = true;
264+
}
265+
if ast::Insert::can_cast(ancestor.kind()) {
266+
return !in_column_list;
267+
}
268+
if ast::WhereClause::can_cast(ancestor.kind()) {
269+
in_where_clause = true;
270+
}
271+
if ast::Delete::can_cast(ancestor.kind()) {
272+
return !in_where_clause;
273+
}
241274
if ast::DropIndex::can_cast(ancestor.kind()) {
242275
return false;
243276
}
@@ -297,6 +330,23 @@ fn is_select_from_table(name_ref: &ast::NameRef) -> bool {
297330
false
298331
}
299332

333+
fn is_select_column(name_ref: &ast::NameRef) -> bool {
334+
let mut in_target_list = false;
335+
336+
for ancestor in name_ref.syntax().ancestors() {
337+
if ast::CallExpr::can_cast(ancestor.kind()) {
338+
return false;
339+
}
340+
if ast::TargetList::can_cast(ancestor.kind()) {
341+
in_target_list = true;
342+
}
343+
if ast::Select::can_cast(ancestor.kind()) && in_target_list {
344+
return true;
345+
}
346+
}
347+
false
348+
}
349+
300350
fn hover_function(
301351
file: &ast::SourceFile,
302352
name_ref: &ast::NameRef,
@@ -981,4 +1031,187 @@ select * from users$0;
9811031
╰╴ ─ hover
9821032
");
9831033
}
1034+
1035+
#[test]
1036+
fn hover_on_select_column() {
1037+
assert_snapshot!(check_hover("
1038+
create table users(id int, email text);
1039+
select id$0 from users;
1040+
"), @r"
1041+
hover: public.users.id int
1042+
╭▸
1043+
3 │ select id from users;
1044+
╰╴ ─ hover
1045+
");
1046+
}
1047+
1048+
#[test]
1049+
fn hover_on_select_column_second() {
1050+
assert_snapshot!(check_hover("
1051+
create table users(id int, email text);
1052+
select id, email$0 from users;
1053+
"), @r"
1054+
hover: public.users.email text
1055+
╭▸
1056+
3 │ select id, email from users;
1057+
╰╴ ─ hover
1058+
");
1059+
}
1060+
1061+
#[test]
1062+
fn hover_on_select_column_with_schema() {
1063+
assert_snapshot!(check_hover("
1064+
create table public.users(id int, email text);
1065+
select email$0 from public.users;
1066+
"), @r"
1067+
hover: public.users.email text
1068+
╭▸
1069+
3 │ select email from public.users;
1070+
╰╴ ─ hover
1071+
");
1072+
}
1073+
1074+
#[test]
1075+
fn hover_on_select_column_with_search_path() {
1076+
assert_snapshot!(check_hover("
1077+
set search_path to foo;
1078+
create table foo.users(id int, email text);
1079+
select id$0 from users;
1080+
"), @r"
1081+
hover: foo.users.id int
1082+
╭▸
1083+
4 │ select id from users;
1084+
╰╴ ─ hover
1085+
");
1086+
}
1087+
1088+
#[test]
1089+
fn hover_on_insert_table() {
1090+
assert_snapshot!(check_hover("
1091+
create table users(id int, email text);
1092+
insert into users$0(id, email) values (1, 'test');
1093+
"), @r"
1094+
hover: table public.users(id int, email text)
1095+
╭▸
1096+
3 │ insert into users(id, email) values (1, 'test');
1097+
╰╴ ─ hover
1098+
");
1099+
}
1100+
1101+
#[test]
1102+
fn hover_on_insert_table_with_schema() {
1103+
assert_snapshot!(check_hover("
1104+
create table public.users(id int, email text);
1105+
insert into public.users$0(id, email) values (1, 'test');
1106+
"), @r"
1107+
hover: table public.users(id int, email text)
1108+
╭▸
1109+
3 │ insert into public.users(id, email) values (1, 'test');
1110+
╰╴ ─ hover
1111+
");
1112+
}
1113+
1114+
#[test]
1115+
fn hover_on_insert_column() {
1116+
assert_snapshot!(check_hover("
1117+
create table users(id int, email text);
1118+
insert into users(id$0, email) values (1, 'test');
1119+
"), @r"
1120+
hover: public.users.id int
1121+
╭▸
1122+
3 │ insert into users(id, email) values (1, 'test');
1123+
╰╴ ─ hover
1124+
");
1125+
}
1126+
1127+
#[test]
1128+
fn hover_on_insert_column_second() {
1129+
assert_snapshot!(check_hover("
1130+
create table users(id int, email text);
1131+
insert into users(id, email$0) values (1, 'test');
1132+
"), @r"
1133+
hover: public.users.email text
1134+
╭▸
1135+
3 │ insert into users(id, email) values (1, 'test');
1136+
╰╴ ─ hover
1137+
");
1138+
}
1139+
1140+
#[test]
1141+
fn hover_on_insert_column_with_schema() {
1142+
assert_snapshot!(check_hover("
1143+
create table public.users(id int, email text);
1144+
insert into public.users(email$0) values ('test');
1145+
"), @r"
1146+
hover: public.users.email text
1147+
╭▸
1148+
3 │ insert into public.users(email) values ('test');
1149+
╰╴ ─ hover
1150+
");
1151+
}
1152+
1153+
#[test]
1154+
fn hover_on_delete_table() {
1155+
assert_snapshot!(check_hover("
1156+
create table users(id int, email text);
1157+
delete from users$0 where id = 1;
1158+
"), @r"
1159+
hover: table public.users(id int, email text)
1160+
╭▸
1161+
3 │ delete from users where id = 1;
1162+
╰╴ ─ hover
1163+
");
1164+
}
1165+
1166+
#[test]
1167+
fn hover_on_delete_table_with_schema() {
1168+
assert_snapshot!(check_hover("
1169+
create table public.users(id int, email text);
1170+
delete from public.users$0 where id = 1;
1171+
"), @r"
1172+
hover: table public.users(id int, email text)
1173+
╭▸
1174+
3 │ delete from public.users where id = 1;
1175+
╰╴ ─ hover
1176+
");
1177+
}
1178+
1179+
#[test]
1180+
fn hover_on_delete_where_column() {
1181+
assert_snapshot!(check_hover("
1182+
create table users(id int, email text);
1183+
delete from users where id$0 = 1;
1184+
"), @r"
1185+
hover: public.users.id int
1186+
╭▸
1187+
3 │ delete from users where id = 1;
1188+
╰╴ ─ hover
1189+
");
1190+
}
1191+
1192+
#[test]
1193+
fn hover_on_delete_where_column_second() {
1194+
assert_snapshot!(check_hover("
1195+
create table users(id int, email text, active boolean);
1196+
delete from users where id = 1 and email$0 = 'test';
1197+
"), @r"
1198+
hover: public.users.email text
1199+
╭▸
1200+
3 │ delete from users where id = 1 and email = 'test';
1201+
╰╴ ─ hover
1202+
");
1203+
}
1204+
1205+
#[test]
1206+
fn hover_on_delete_where_column_with_schema() {
1207+
assert_snapshot!(check_hover("
1208+
create table public.users(id int, email text);
1209+
delete from public.users where email$0 = 'test';
1210+
"), @r"
1211+
hover: public.users.email text
1212+
╭▸
1213+
3 │ delete from public.users where email = 'test';
1214+
╰╴ ─ hover
1215+
");
1216+
}
9841217
}

0 commit comments

Comments
 (0)