diff --git a/crates/squawk_ide/src/binder.rs b/crates/squawk_ide/src/binder.rs index d0b4a645..271813e3 100644 --- a/crates/squawk_ide/src/binder.rs +++ b/crates/squawk_ide/src/binder.rs @@ -258,6 +258,7 @@ fn bind_stmt(b: &mut Binder, stmt: ast::Stmt) { ast::Stmt::CreateProcedure(create_procedure) => bind_create_procedure(b, create_procedure), ast::Stmt::CreateSchema(create_schema) => bind_create_schema(b, create_schema), ast::Stmt::CreateType(create_type) => bind_create_type(b, create_type), + ast::Stmt::CreateDomain(create_domain) => bind_create_domain(b, create_domain), ast::Stmt::CreateView(create_view) => bind_create_view(b, create_view), ast::Stmt::CreateMaterializedView(create_view) => { bind_create_materialized_view(b, create_view) @@ -494,6 +495,33 @@ fn bind_create_type(b: &mut Binder, create_type: ast::CreateType) { } } +fn bind_create_domain(b: &mut Binder, create_domain: ast::CreateDomain) { + let Some(path) = create_domain.path() else { + return; + }; + + let Some(domain_name) = item_name(&path) else { + return; + }; + + let name_ptr = path_to_ptr(&path); + + let Some(schema) = schema_name(b, &path, false) else { + return; + }; + + let type_id = b.symbols.alloc(Symbol { + kind: SymbolKind::Type, + ptr: name_ptr, + schema: Some(schema), + params: None, + table: None, + }); + + let root = b.root_scope(); + b.scopes[root].insert(domain_name, type_id); +} + fn multirange_type_from_range( b: &Binder, create_type: ast::CreateType, diff --git a/crates/squawk_ide/src/classify.rs b/crates/squawk_ide/src/classify.rs index f53d219b..272eb928 100644 --- a/crates/squawk_ide/src/classify.rs +++ b/crates/squawk_ide/src/classify.rs @@ -10,6 +10,7 @@ pub(crate) enum NameRefClass { Table, DropIndex, DropType, + DropDomain, DropView, DropMaterializedView, DropSequence, @@ -438,6 +439,9 @@ pub(crate) fn classify_name_ref(name_ref: &ast::NameRef) -> Option if ast::DropType::can_cast(ancestor.kind()) { return Some(NameRefClass::DropType); } + if ast::DropDomain::can_cast(ancestor.kind()) { + return Some(NameRefClass::DropDomain); + } if ast::DropView::can_cast(ancestor.kind()) { return Some(NameRefClass::DropView); } diff --git a/crates/squawk_ide/src/goto_definition.rs b/crates/squawk_ide/src/goto_definition.rs index d333b820..85a8ede1 100644 --- a/crates/squawk_ide/src/goto_definition.rs +++ b/crates/squawk_ide/src/goto_definition.rs @@ -1861,6 +1861,48 @@ drop type int4_range$0; "); } + #[test] + fn goto_drop_domain() { + assert_snapshot!(goto(" +create domain posint as integer check (value > 0); +drop domain posint$0; +"), @r" + ╭▸ + 2 │ create domain posint as integer check (value > 0); + │ ────── 2. destination + 3 │ drop domain posint; + ╰╴ ─ 1. source + "); + } + + #[test] + fn goto_cast_to_domain() { + assert_snapshot!(goto(" +create domain posint as integer check (value > 0); +select 1::posint$0; +"), @r" + ╭▸ + 2 │ create domain posint as integer check (value > 0); + │ ────── 2. destination + 3 │ select 1::posint; + ╰╴ ─ 1. source + "); + } + + #[test] + fn goto_drop_type_domain() { + assert_snapshot!(goto(" +create domain posint as integer check (value > 0); +drop type posint$0; +"), @r" + ╭▸ + 2 │ create domain posint as integer check (value > 0); + │ ────── 2. destination + 3 │ drop type posint; + ╰╴ ─ 1. source + "); + } + #[test] fn goto_drop_view() { assert_snapshot!(goto(" diff --git a/crates/squawk_ide/src/hover.rs b/crates/squawk_ide/src/hover.rs index 3d592724..828d0d23 100644 --- a/crates/squawk_ide/src/hover.rs +++ b/crates/squawk_ide/src/hover.rs @@ -71,7 +71,7 @@ pub fn hover(file: &ast::SourceFile, offset: TextSize) -> Option { | NameRefClass::AlterTableDropColumn => { return hover_column(root, &name_ref, &binder); } - NameRefClass::TypeReference | NameRefClass::DropType => { + NameRefClass::TypeReference | NameRefClass::DropType | NameRefClass::DropDomain => { return hover_type(root, &name_ref, &binder); } NameRefClass::CompositeTypeField => { diff --git a/crates/squawk_ide/src/resolve.rs b/crates/squawk_ide/src/resolve.rs index 36193150..2b16e987 100644 --- a/crates/squawk_ide/src/resolve.rs +++ b/crates/squawk_ide/src/resolve.rs @@ -111,7 +111,7 @@ pub(crate) fn resolve_name_ref_ptrs( let position = name_ref.syntax().text_range().start(); resolve_index_name_ptr(binder, &index_name, &schema, position).map(|ptr| smallvec![ptr]) } - NameRefClass::DropType | NameRefClass::TypeReference => { + NameRefClass::DropType | NameRefClass::DropDomain | NameRefClass::TypeReference => { let (type_name, schema) = if let Some(parent) = name_ref.syntax().parent() && let Some(field_expr) = ast::FieldExpr::cast(parent) && field_expr