Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions crates/squawk_ide/src/classify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ pub(crate) fn classify_name_ref(name_ref: &ast::NameRef) -> Option<NameRefClass>
let mut in_returning_clause = false;
let mut in_when_clause = false;
let mut in_special_sql_fn = false;
let mut in_conflict_target = false;

// TODO: can we combine this if and the one that follows?
if let Some(parent) = name_ref.syntax().parent()
Expand Down Expand Up @@ -347,6 +348,7 @@ pub(crate) fn classify_name_ref(name_ref: &ast::NameRef) -> Option<NameRefClass>
|| ast::AlterTable::can_cast(ancestor.kind())
|| ast::OnTable::can_cast(ancestor.kind())
|| ast::AttachPartition::can_cast(ancestor.kind())
|| ast::DetachPartition::can_cast(ancestor.kind())
|| ast::Table::can_cast(ancestor.kind())
|| ast::Inherits::can_cast(ancestor.kind())
|| ast::PartitionOf::can_cast(ancestor.kind())
Expand Down Expand Up @@ -379,7 +381,7 @@ pub(crate) fn classify_name_ref(name_ref: &ast::NameRef) -> Option<NameRefClass>
return Some(NameRefClass::Database);
}
}
if ast::DropIndex::can_cast(ancestor.kind()) {
if ast::DropIndex::can_cast(ancestor.kind()) || ast::UsingIndex::can_cast(ancestor.kind()) {
return Some(NameRefClass::Index);
}
if ast::DropType::can_cast(ancestor.kind()) || ast::DropDomain::can_cast(ancestor.kind()) {
Expand Down Expand Up @@ -542,7 +544,7 @@ pub(crate) fn classify_name_ref(name_ref: &ast::NameRef) -> Option<NameRefClass>
if ast::Call::can_cast(ancestor.kind()) {
return Some(NameRefClass::CallProcedure);
}
if ast::DropSchema::can_cast(ancestor.kind()) {
if ast::DropSchema::can_cast(ancestor.kind()) || ast::SetSchema::can_cast(ancestor.kind()) {
return Some(NameRefClass::Schema);
}
if ast::CreateIndex::can_cast(ancestor.kind()) {
Expand Down Expand Up @@ -625,8 +627,16 @@ pub(crate) fn classify_name_ref(name_ref: &ast::NameRef) -> Option<NameRefClass>
if ast::PartitionItem::can_cast(ancestor.kind()) {
in_partition_item = true;
}
if ast::ConflictIndexItem::can_cast(ancestor.kind()) {
in_conflict_target = true;
}
if ast::Insert::can_cast(ancestor.kind()) {
if in_returning_clause || in_column_list {
if in_returning_clause
|| in_column_list
|| in_set_clause
|| in_where_clause
|| in_conflict_target
{
return Some(NameRefClass::InsertColumn);
}
return Some(NameRefClass::Table);
Expand All @@ -640,10 +650,9 @@ pub(crate) fn classify_name_ref(name_ref: &ast::NameRef) -> Option<NameRefClass>
if ast::SetClause::can_cast(ancestor.kind()) {
in_set_clause = true;
}
if ast::UsingClause::can_cast(ancestor.kind()) {
in_using_clause = true;
}
if ast::UsingOnClause::can_cast(ancestor.kind()) {
if ast::UsingClause::can_cast(ancestor.kind())
|| ast::UsingOnClause::can_cast(ancestor.kind())
{
in_using_clause = true;
}
if ast::ReturningClause::can_cast(ancestor.kind()) {
Expand Down
160 changes: 160 additions & 0 deletions crates/squawk_ide/src/goto_definition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1402,6 +1402,31 @@ create table bar(
");
}

#[test]
fn goto_alter_table_foreign_key_local_column() {
assert_snapshot!(goto("
create table t (
id bigserial primary key
);

create table u (
id bigserial primary key,
t_id bigint
);

alter table u
add constraint fooo_fkey
foreign key (t_id$0) references t (id);
"), @r"
╭▸
8 │ t_id bigint
│ ──── 2. destination
13 │ foreign key (t_id) references t (id);
╰╴ ─ 1. source
");
}

#[test]
fn goto_check_constraint_column() {
assert_snapshot!(goto("
Expand Down Expand Up @@ -6658,6 +6683,99 @@ alter table users$0 drop column email;
");
}

#[test]
fn goto_alter_table_add_constraint_using_index() {
assert_snapshot!(goto("
create table u(id int);
create index my_index on u (id);
alter table u add constraint uq unique using index my_in$0dex;
"), @r"
╭▸
3 │ create index my_index on u (id);
│ ──────── 2. destination
4 │ alter table u add constraint uq unique using index my_index;
╰╴ ─ 1. source
");
}

#[test]
fn goto_alter_table_owner_to_role() {
assert_snapshot!(goto("
create role reader;
create table t(id int);
alter table t owner to read$0er;
"), @r"
╭▸
2 │ create role reader;
│ ────── 2. destination
3 │ create table t(id int);
4 │ alter table t owner to reader;
╰╴ ─ 1. source
");
}

#[test]
fn goto_alter_table_set_tablespace() {
assert_snapshot!(goto("
create tablespace ts location '/tmp/ts';
create table t(id int);
alter table t set tablespace t$0s;
"), @r"
╭▸
2 │ create tablespace ts location '/tmp/ts';
│ ── 2. destination
3 │ create table t(id int);
4 │ alter table t set tablespace ts;
╰╴ ─ 1. source
");
}

#[test]
fn goto_alter_table_set_schema() {
assert_snapshot!(goto("
create schema foo;
create table t(id int);
alter table t set schema fo$0o;
"), @r"
╭▸
2 │ create schema foo;
│ ─── 2. destination
3 │ create table t(id int);
4 │ alter table t set schema foo;
╰╴ ─ 1. source
");
}

#[test]
fn goto_alter_table_attach_partition() {
assert_snapshot!(goto("
create table parent (id int) partition by range (id);
create table child (id int);
alter table parent attach partition ch$0ild for values from (1) to (10);
"), @r"
╭▸
3 │ create table child (id int);
│ ───── 2. destination
4 │ alter table parent attach partition child for values from (1) to (10);
╰╴ ─ 1. source
");
}

#[test]
fn goto_alter_table_detach_partition() {
assert_snapshot!(goto("
create table parent (id int) partition by range (id);
create table child partition of parent for values from (1) to (10);
alter table parent detach partition ch$0ild;
"), @r"
╭▸
3 │ create table child partition of parent for values from (1) to (10);
│ ───── 2. destination
4 │ alter table parent detach partition child;
╰╴ ─ 1. source
");
}

#[test]
fn goto_comment_on_table() {
assert_snapshot!(goto("
Expand Down Expand Up @@ -7031,6 +7149,48 @@ insert into t as f values (1, 2) returning f.a$0;"
");
}

#[test]
fn goto_insert_on_conflict_target_column() {
assert_snapshot!(goto("
create table t(c text);
insert into t values ('c') on conflict (c$0) do nothing;"
), @r"
╭▸
2 │ create table t(c text);
│ ─ 2. destination
3 │ insert into t values ('c') on conflict (c) do nothing;
╰╴ ─ 1. source
");
}

#[test]
fn goto_insert_on_conflict_set_column() {
assert_snapshot!(goto("
create table t(c text, d text);
insert into t values ('c', 'd') on conflict (c) do update set c$0 = excluded.c;"
), @r"
╭▸
2 │ create table t(c text, d text);
│ ─ 2. destination
3 │ insert into t values ('c', 'd') on conflict (c) do update set c = excluded.c;
╰╴ ─ 1. source
");
}

#[test]
fn goto_insert_on_conflict_excluded_column() {
assert_snapshot!(goto("
create table t(c text, d text);
insert into t values ('c', 'd') on conflict (c) do update set c = excluded.c$0;"
), @r"
╭▸
2 │ create table t(c text, d text);
│ ─ 2. destination
3 │ insert into t values ('c', 'd') on conflict (c) do update set c = excluded.c;
╰╴ ─ 1. source
");
}

#[test]
fn goto_delete_from_alias() {
assert_snapshot!(goto("
Expand Down
23 changes: 14 additions & 9 deletions crates/squawk_ide/src/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,9 @@ pub(crate) fn resolve_name_ref_ptrs(
resolve_view_name_ptr(binder, &table_name, &schema, position).map(|ptr| smallvec![ptr])
}
NameRefClass::Index => {
let path = find_containing_path(name_ref)?;
let (index_name, schema) = extract_table_schema_from_path(&path)?;
let position = name_ref.syntax().text_range().start();
resolve_index_name_ptr(binder, &index_name, &schema, position).map(|ptr| smallvec![ptr])
let index_name = Name::from_node(name_ref);
resolve_index_name_ptr(binder, &index_name, &None, position).map(|ptr| smallvec![ptr])
}
NameRefClass::Type => {
let (type_name, schema) = if let Some(parent) = name_ref.syntax().parent()
Expand Down Expand Up @@ -220,13 +219,19 @@ pub(crate) fn resolve_name_ref_ptrs(
resolve_column_for_path(binder, root, &path, column_name).map(|ptr| smallvec![ptr])
}
NameRefClass::ConstraintColumn => {
let create_table = name_ref
.syntax()
.ancestors()
.find_map(ast::CreateTableLike::cast)?;
let column_name = Name::from_node(name_ref);
find_column_in_create_table(binder, root, &create_table, &column_name)
.map(|ptr| smallvec![ptr])
for ancestor in name_ref.syntax().ancestors() {
if let Some(create_table) = ast::CreateTableLike::cast(ancestor.clone()) {
return find_column_in_create_table(binder, root, &create_table, &column_name)
.map(|ptr| smallvec![ptr]);
}
if let Some(alter_table) = ast::AlterTable::cast(ancestor) {
let table_path = alter_table.relation_name()?.path()?;
return resolve_column_for_path(binder, root, &table_path, column_name)
.map(|ptr| smallvec![ptr]);
}
}
None
}
NameRefClass::PolicyColumn => {
let on_table_path = name_ref.syntax().ancestors().find_map(|n| {
Expand Down
Loading