Skip to content

Commit 76428ca

Browse files
authored
ide: inlay hints for select in insert stmt (#845)
1 parent 0a7a274 commit 76428ca

4 files changed

Lines changed: 74 additions & 8 deletions

File tree

crates/squawk_ide/src/inlay_hints.rs

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,9 @@ fn inlay_hint_insert(
8888
binder: &Binder,
8989
insert: ast::Insert,
9090
) -> Option<()> {
91-
let values = insert.values()?;
92-
let row_list = values.row_list()?;
9391
let create_table = resolve::resolve_insert_create_table(root, binder, &insert);
9492

95-
let columns: Vec<(Name, Option<TextRange>)> = if let Some(column_list) = insert.column_list() {
93+
let columns = if let Some(column_list) = insert.column_list() {
9694
// `insert into t(a, b, c) values (1, 2, 3)`
9795
column_list
9896
.columns()
@@ -124,6 +122,11 @@ fn inlay_hint_insert(
124122
.collect()
125123
};
126124

125+
let Some(values) = insert.values() else {
126+
return inlay_hint_insert_select(hints, columns, insert.stmt()?);
127+
};
128+
let row_list = values.row_list()?;
129+
127130
for row in row_list.rows() {
128131
for ((column_name, target), expr) in columns.iter().zip(row.exprs()) {
129132
let expr_start = expr.syntax().text_range().start();
@@ -139,6 +142,53 @@ fn inlay_hint_insert(
139142
Some(())
140143
}
141144

145+
fn inlay_hint_insert_select(
146+
hints: &mut Vec<InlayHint>,
147+
columns: Vec<(Name, Option<TextRange>)>,
148+
stmt: ast::Stmt,
149+
) -> Option<()> {
150+
let target_list = match stmt {
151+
ast::Stmt::Select(select) => select.select_clause()?.target_list(),
152+
ast::Stmt::SelectInto(select_into) => select_into.select_clause()?.target_list(),
153+
ast::Stmt::ParenSelect(paren_select) => {
154+
target_list_from_select_variant(paren_select.select()?)
155+
}
156+
_ => None,
157+
}?;
158+
159+
for ((column_name, target), target_expr) in columns.iter().zip(target_list.targets()) {
160+
let expr = target_expr.expr()?;
161+
let expr_start = expr.syntax().text_range().start();
162+
hints.push(InlayHint {
163+
position: expr_start,
164+
label: format!("{}: ", column_name),
165+
kind: InlayHintKind::Parameter,
166+
target: *target,
167+
});
168+
}
169+
170+
Some(())
171+
}
172+
173+
fn target_list_from_select_variant(select: ast::SelectVariant) -> Option<ast::TargetList> {
174+
let mut current = select;
175+
for _ in 0..100 {
176+
match current {
177+
ast::SelectVariant::Select(select) => {
178+
return select.select_clause()?.target_list();
179+
}
180+
ast::SelectVariant::SelectInto(select_into) => {
181+
return select_into.select_clause()?.target_list();
182+
}
183+
ast::SelectVariant::ParenSelect(paren_select) => {
184+
current = paren_select.select()?;
185+
}
186+
_ => return None,
187+
}
188+
}
189+
None
190+
}
191+
142192
#[cfg(test)]
143193
mod test {
144194
use crate::inlay_hints::inlay_hints;
@@ -348,4 +398,17 @@ insert into t values (1, 2, 3);
348398
╰╴ ─── ───
349399
");
350400
}
401+
402+
#[test]
403+
fn insert_select() {
404+
assert_snapshot!(check_inlay_hints("
405+
create table t (a int, b int);
406+
insert into t select 1, 2;
407+
"), @r"
408+
inlay hints:
409+
╭▸
410+
3 │ insert into t select a: 1, b: 2;
411+
╰╴ ─── ───
412+
");
413+
}
351414
}

crates/squawk_ide/src/resolve.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1791,8 +1791,7 @@ fn resolve_cte_column(
17911791
}
17921792

17931793
if let ast::WithQuery::Table(table) = query {
1794-
let relation_name = table.relation_name()?;
1795-
let path = relation_name.path()?;
1794+
let path = table.relation_name()?.path()?;
17961795
let (table_name, schema) = extract_table_schema_from_path(&path)?;
17971796

17981797
if schema.is_none()
@@ -1975,8 +1974,7 @@ fn resolve_subquery_column_ptr(
19751974
}
19761975

19771976
if let ast::SelectVariant::Table(table) = select_variant {
1978-
let relation_name = table.relation_name()?;
1979-
let path = relation_name.path()?;
1977+
let path = table.relation_name()?.path()?;
19801978
let (table_name, schema) = extract_table_schema_from_path(&path)?;
19811979

19821980
if schema.is_none()

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

Lines changed: 4 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: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1644,7 +1644,8 @@ SelectVariant =
16441644

16451645
CompoundSelect =
16461646
lhs:SelectVariant
1647-
('union' | 'intersect' | 'except')
1647+
('union' | 'intersect' | 'except' )
1648+
'all'?
16481649
rhs:SelectVariant
16491650

16501651
SelectInto =

0 commit comments

Comments
 (0)