diff --git a/crates/squawk_github/Cargo.toml b/crates/squawk_github/Cargo.toml index b3498d57..e583fd40 100644 --- a/crates/squawk_github/Cargo.toml +++ b/crates/squawk_github/Cargo.toml @@ -13,6 +13,9 @@ keywords = ["bot", "github", "linter"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +doctest = false + [dependencies] jsonwebtoken.workspace = true serde_json.workspace = true diff --git a/crates/squawk_ide/Cargo.toml b/crates/squawk_ide/Cargo.toml index 8ee95cfe..d2089594 100644 --- a/crates/squawk_ide/Cargo.toml +++ b/crates/squawk_ide/Cargo.toml @@ -11,6 +11,9 @@ edition.workspace = true license.workspace = true rust-version.workspace = true +[lib] +doctest = false + [dependencies] squawk-syntax.workspace = true squawk-linter.workspace = true diff --git a/crates/squawk_ide/src/binder.rs b/crates/squawk_ide/src/binder.rs index 13077db4..1723219c 100644 --- a/crates/squawk_ide/src/binder.rs +++ b/crates/squawk_ide/src/binder.rs @@ -96,6 +96,7 @@ fn bind_stmt(b: &mut Binder, stmt: ast::Stmt) { bind_create_tablespace(b, create_tablespace) } ast::Stmt::CreateDatabase(create_database) => bind_create_database(b, create_database), + ast::Stmt::CreateServer(create_server) => bind_create_server(b, create_server), ast::Stmt::Set(set) => bind_set(b, set), _ => {} } @@ -430,6 +431,25 @@ fn bind_create_database(b: &mut Binder, create_database: ast::CreateDatabase) { b.scopes[root].insert(database_name, database_id); } +fn bind_create_server(b: &mut Binder, create_server: ast::CreateServer) { + let Some(name) = create_server.name() else { + return; + }; + + let server_name = Name::from_node(&name); + let name_ptr = SyntaxNodePtr::new(name.syntax()); + + let server_id = b.symbols.alloc(Symbol { + kind: SymbolKind::Server, + ptr: name_ptr, + schema: Schema::new("pg_foreign_server"), + params: None, + }); + + let root = b.root_scope(); + b.scopes[root].insert(server_name, server_id); +} + fn item_name(path: &ast::Path) -> Option { let segment = path.segment()?; diff --git a/crates/squawk_ide/src/classify.rs b/crates/squawk_ide/src/classify.rs index c8f51aa3..3fefdc3a 100644 --- a/crates/squawk_ide/src/classify.rs +++ b/crates/squawk_ide/src/classify.rs @@ -12,6 +12,10 @@ pub(crate) enum NameRefClass { SequenceOwnedByColumn, Tablespace, DropDatabase, + DropServer, + AlterServer, + CreateServer, + ForeignTableServerName, ForeignKeyTable, ForeignKeyColumn, ForeignKeyLocalColumn, @@ -209,6 +213,18 @@ pub(crate) fn classify_name_ref(name_ref: &ast::NameRef) -> Option if ast::DropDatabase::can_cast(ancestor.kind()) { return Some(NameRefClass::DropDatabase); } + if ast::DropServer::can_cast(ancestor.kind()) { + return Some(NameRefClass::DropServer); + } + if ast::AlterServer::can_cast(ancestor.kind()) { + return Some(NameRefClass::AlterServer); + } + if ast::CreateServer::can_cast(ancestor.kind()) { + return Some(NameRefClass::CreateServer); + } + if ast::ServerName::can_cast(ancestor.kind()) { + return Some(NameRefClass::ForeignTableServerName); + } if let Some(sequence_option) = ast::SequenceOption::cast(ancestor.clone()) && sequence_option.owned_token().is_some() && sequence_option.by_token().is_some() @@ -333,7 +349,7 @@ pub(crate) fn classify_name_ref(name_ref: &ast::NameRef) -> Option } return Some(NameRefClass::CreateIndex); } - if in_partition_item && ast::CreateTable::can_cast(ancestor.kind()) { + if in_partition_item && ast::CreateTableLike::can_cast(ancestor.kind()) { return Some(NameRefClass::PartitionByColumn); } if ast::PartitionOf::can_cast(ancestor.kind()) { @@ -421,20 +437,16 @@ pub(crate) fn classify_name_ref(name_ref: &ast::NameRef) -> Option #[derive(Debug)] pub(crate) enum NameClass { ColumnDefinition { - create_table: ast::CreateTable, - column: ast::Column, - }, - ColumnDefinitionForeignTable { - create_foreign_table: ast::CreateForeignTable, + create_table: ast::CreateTableLike, column: ast::Column, }, - CreateTable(ast::CreateTable), - CreateForeignTable(ast::CreateForeignTable), + CreateTable(ast::CreateTableLike), WithTable(ast::WithTable), CreateIndex(ast::CreateIndex), CreateSequence(ast::CreateSequence), CreateTablespace(ast::CreateTablespace), CreateDatabase(ast::CreateDatabase), + CreateServer(ast::CreateServer), CreateType(ast::CreateType), CreateFunction(ast::CreateFunction), CreateAggregate(ast::CreateAggregate), @@ -457,7 +469,7 @@ pub(crate) fn classify_name(name: &ast::Name) -> Option { if !has_column_list && ast::ColumnList::can_cast(ancestor.kind()) { has_column_list = true; } - if let Some(create_table) = ast::CreateTable::cast(ancestor.clone()) { + if let Some(create_table) = ast::CreateTableLike::cast(ancestor.clone()) { if let Some(column) = column_parent { return Some(NameClass::ColumnDefinition { create_table, @@ -466,15 +478,6 @@ pub(crate) fn classify_name(name: &ast::Name) -> Option { } return Some(NameClass::CreateTable(create_table)); } - if let Some(create_foreign_table) = ast::CreateForeignTable::cast(ancestor.clone()) { - if let Some(column) = column_parent { - return Some(NameClass::ColumnDefinitionForeignTable { - create_foreign_table, - column, - }); - } - return Some(NameClass::CreateForeignTable(create_foreign_table)); - } if let Some(create_index) = ast::CreateIndex::cast(ancestor.clone()) { return Some(NameClass::CreateIndex(create_index)); } @@ -487,6 +490,9 @@ pub(crate) fn classify_name(name: &ast::Name) -> Option { if let Some(create_database) = ast::CreateDatabase::cast(ancestor.clone()) { return Some(NameClass::CreateDatabase(create_database)); } + if let Some(create_server) = ast::CreateServer::cast(ancestor.clone()) { + return Some(NameClass::CreateServer(create_server)); + } if let Some(create_type) = ast::CreateType::cast(ancestor.clone()) { return Some(NameClass::CreateType(create_type)); } diff --git a/crates/squawk_ide/src/goto_definition.rs b/crates/squawk_ide/src/goto_definition.rs index 0f710d18..13695b77 100644 --- a/crates/squawk_ide/src/goto_definition.rs +++ b/crates/squawk_ide/src/goto_definition.rs @@ -416,6 +416,62 @@ create database my$0db; "); } + #[test] + fn goto_drop_server() { + assert_snapshot!(goto(" +create server myserver foreign data wrapper fdw; +drop server my$0server; +"), @r" + ╭▸ + 2 │ create server myserver foreign data wrapper fdw; + │ ──────── 2. destination + 3 │ drop server myserver; + ╰╴ ─ 1. source + "); + } + + #[test] + fn goto_drop_server_defined_after() { + assert_snapshot!(goto(" +drop server my$0server; +create server myserver foreign data wrapper fdw; +"), @r" + ╭▸ + 2 │ drop server myserver; + │ ─ 1. source + 3 │ create server myserver foreign data wrapper fdw; + ╰╴ ──────── 2. destination + "); + } + + #[test] + fn goto_alter_server() { + assert_snapshot!(goto(" +create server myserver foreign data wrapper fdw; +alter server my$0server options (add foo 'bar'); +"), @r" + ╭▸ + 2 │ create server myserver foreign data wrapper fdw; + │ ──────── 2. destination + 3 │ alter server myserver options (add foo 'bar'); + ╰╴ ─ 1. source + "); + } + + #[test] + fn goto_server_definition_returns_self() { + assert_snapshot!(goto(" +create server my$0server foreign data wrapper fdw; +"), @r" + ╭▸ + 2 │ create server myserver foreign data wrapper fdw; + │ ┬┬────── + │ ││ + │ │1. source + ╰╴ 2. destination + "); + } + #[test] fn goto_drop_sequence_with_schema() { assert_snapshot!(goto(" @@ -553,6 +609,51 @@ select a from ft$0; "); } + #[test] + fn goto_foreign_table_server_name() { + assert_snapshot!(goto(" +create server myserver foreign data wrapper fdw; +create foreign table ft(a int) + server my$0server; +"), @r" + ╭▸ + 2 │ create server myserver foreign data wrapper fdw; + │ ──────── 2. destination + 3 │ create foreign table ft(a int) + 4 │ server myserver; + ╰╴ ─ 1. source + "); + } + + #[test] + fn goto_foreign_table_server_name_defined_after() { + assert_snapshot!(goto(" +create foreign table ft(a int) + server my$0server; +create server myserver foreign data wrapper fdw; +"), @r" + ╭▸ + 3 │ server myserver; + │ ─ 1. source + 4 │ create server myserver foreign data wrapper fdw; + ╰╴ ──────── 2. destination + "); + } + + #[test] + fn goto_user_mapping_server_name() { + assert_snapshot!(goto(" +create server myserver foreign data wrapper fdw; +create user mapping for current_user server my$0server; +"), @r" + ╭▸ + 2 │ create server myserver foreign data wrapper fdw; + │ ──────── 2. destination + 3 │ create user mapping for current_user server myserver; + ╰╴ ─ 1. source + "); + } + #[test] fn goto_foreign_key_references_table() { assert_snapshot!(goto(" diff --git a/crates/squawk_ide/src/hover.rs b/crates/squawk_ide/src/hover.rs index 69e422b8..8ead853f 100644 --- a/crates/squawk_ide/src/hover.rs +++ b/crates/squawk_ide/src/hover.rs @@ -1,4 +1,5 @@ use crate::classify::{NameClass, NameRefClass, classify_name, classify_name_ref}; +use crate::column_name::ColumnName; use crate::offsets::token_from_offset; use crate::resolve; use crate::{binder, symbols::Name}; @@ -98,6 +99,12 @@ pub fn hover(file: &ast::SourceFile, offset: TextSize) -> Option { } NameRefClass::DropSequence => return hover_sequence(root, &name_ref, &binder), NameRefClass::DropDatabase => return hover_database(root, &name_ref, &binder), + NameRefClass::DropServer + | NameRefClass::AlterServer + | NameRefClass::CreateServer + | NameRefClass::ForeignTableServerName => { + return hover_server(root, &name_ref, &binder); + } NameRefClass::Tablespace => return hover_tablespace(root, &name_ref, &binder), NameRefClass::DropIndex => return hover_index(root, &name_ref, &binder), NameRefClass::DropFunction => return hover_function(root, &name_ref, &binder), @@ -132,18 +139,9 @@ pub fn hover(file: &ast::SourceFile, offset: TextSize) -> Option { create_table, column, } => return hover_column_definition(&create_table, &column, &binder), - NameClass::ColumnDefinitionForeignTable { - create_foreign_table, - column, - } => { - return hover_column_definition(&create_foreign_table, &column, &binder); - } NameClass::CreateTable(create_table) => { return format_create_table(&create_table, &binder); } - NameClass::CreateForeignTable(create_foreign_table) => { - return format_create_foreign_table(&create_foreign_table, &binder); - } NameClass::WithTable(with_table) => return format_with_table(&with_table), NameClass::CreateIndex(create_index) => { return format_create_index(&create_index, &binder); @@ -157,6 +155,9 @@ pub fn hover(file: &ast::SourceFile, offset: TextSize) -> Option { NameClass::CreateDatabase(create_database) => { return format_create_database(&create_database); } + NameClass::CreateServer(create_server) => { + return format_create_server(&create_server); + } NameClass::CreateType(create_type) => { return format_create_type(&create_type, &binder); } @@ -369,9 +370,6 @@ fn hover_table_from_ptr( resolve::TableSource::CreateTable(create_table) => { format_create_table(&create_table, binder) } - resolve::TableSource::CreateForeignTable(create_foreign_table) => { - format_create_foreign_table(&create_foreign_table, binder) - } } } @@ -460,9 +458,6 @@ fn hover_qualified_star_columns( resolve::TableSource::CreateTable(create_table) => { hover_qualified_star_columns_from_table(&create_table, binder) } - resolve::TableSource::CreateForeignTable(create_foreign_table) => { - hover_qualified_star_columns_from_table(&create_foreign_table, binder) - } resolve::TableSource::CreateView(create_view) => { hover_qualified_star_columns_from_view(&create_view, binder) } @@ -551,6 +546,7 @@ fn hover_qualified_star_columns_from_subquery( let target_list = select_clause.target_list()?; let mut results = vec![]; + let subquery_alias = subquery_alias_name(paren_select); for target in target_list.targets() { if target.star_token().is_some() { @@ -560,6 +556,13 @@ fn hover_qualified_star_columns_from_subquery( results.push(columns) } } + continue; + } + + if let Some(result) = + hover_subquery_target_column(root, &target, subquery_alias.as_ref(), binder) + { + results.push(result); } } @@ -570,6 +573,38 @@ fn hover_qualified_star_columns_from_subquery( Some(results.join("\n")) } +fn subquery_alias_name(paren_select: &ast::ParenSelect) -> Option { + let from_item = paren_select + .syntax() + .ancestors() + .find_map(ast::FromItem::cast)?; + let alias_name = from_item.alias()?.name()?; + Some(Name::from_node(&alias_name)) +} + +fn hover_subquery_target_column( + root: &SyntaxNode, + target: &ast::Target, + subquery_alias: Option<&Name>, + binder: &binder::Binder, +) -> Option { + if let Some(alias) = subquery_alias + && let Some((col_name, _node)) = ColumnName::from_target(target.clone()) + && let Some(col_name) = col_name.to_string() + { + return Some(ColumnHover::table_column(&alias.to_string(), &col_name)); + } + + match target.expr()? { + ast::Expr::NameRef(name_ref) => hover_column(root, &name_ref, binder), + ast::Expr::FieldExpr(field_expr) => { + let field = field_expr.field()?; + hover_column(root, &field, binder) + } + _ => None, + } +} + fn hover_index( root: &SyntaxNode, name_ref: &ast::NameRef, @@ -630,6 +665,18 @@ fn hover_database( Some(format!("database {}", database_name_node.text())) } +fn hover_server( + root: &SyntaxNode, + name_ref: &ast::NameRef, + binder: &binder::Binder, +) -> Option { + let server_ptr = resolve::resolve_name_ref(binder, root, name_ref)? + .into_iter() + .next()?; + let server_name_node = server_ptr.to_node(root); + Some(format!("server {}", server_name_node.text())) +} + fn hover_type( root: &SyntaxNode, name_ref: &ast::NameRef, @@ -646,29 +693,22 @@ fn hover_type( format_create_type(&create_type, binder) } -// Insert inferred schema into the create table hover info -fn format_create_table(create_table: &ast::CreateTable, binder: &binder::Binder) -> Option { +fn format_create_table( + create_table: &impl ast::HasCreateTable, + binder: &binder::Binder, +) -> Option { let path = create_table.path()?; let (schema, table_name) = resolve::resolve_table_info(binder, &path)?; let schema = schema.to_string(); let args = create_table.table_arg_list()?.syntax().text().to_string(); - Some(format!("table {}.{}{}", schema, table_name, args)) -} - -fn format_create_foreign_table( - create_foreign_table: &ast::CreateForeignTable, - binder: &binder::Binder, -) -> Option { - let path = create_foreign_table.path()?; - let (schema, table_name) = resolve::resolve_table_info(binder, &path)?; - let schema = schema.to_string(); - let args = create_foreign_table - .table_arg_list() - .map(|list| list.syntax().text().to_string()) - .unwrap_or_default(); + let foreign = if create_table.syntax().kind() == SyntaxKind::CREATE_FOREIGN_TABLE { + "foreign " + } else { + "" + }; - Some(format!("foreign table {}.{}{}", schema, table_name, args)) + Some(format!("{foreign}table {schema}.{table_name}{args}")) } fn format_create_view(create_view: &ast::CreateView, binder: &binder::Binder) -> Option { @@ -747,6 +787,11 @@ fn format_create_database(create_database: &ast::CreateDatabase) -> Option Option { + let name = create_server.name()?.syntax().text().to_string(); + Some(format!("server {}", name)) +} + fn index_schema(create_index: &ast::CreateIndex, binder: &binder::Binder) -> Option { let position = create_index.syntax().text_range().start(); let search_path = binder.search_path_at(position); @@ -2503,6 +2548,19 @@ select *$0 from (select *, *, * from u); "); } + #[test] + fn hover_on_star_with_subquery_from_table() { + assert_snapshot!(check_hover(" +create table t(a int, b int); +select *$0 from (select a from t); +"), @r" + hover: column public.t.a int + ╭▸ + 3 │ select * from (select a from t); + ╰╴ ─ hover + "); + } + #[test] fn hover_on_view_qualified_star() { assert_snapshot!(check_hover(" diff --git a/crates/squawk_ide/src/resolve.rs b/crates/squawk_ide/src/resolve.rs index fcafba76..0e66b45a 100644 --- a/crates/squawk_ide/src/resolve.rs +++ b/crates/squawk_ide/src/resolve.rs @@ -24,7 +24,9 @@ pub(crate) fn resolve_name_ref( | NameRefClass::CreateIndex | NameRefClass::InsertTable | NameRefClass::DeleteTable - | NameRefClass::UpdateTable => { + | NameRefClass::UpdateTable + | NameRefClass::PartitionOfTable + | NameRefClass::InheritsTable => { let path = find_containing_path(name_ref)?; let table_name = extract_table_name(&path)?; let schema = extract_schema_name(&path); @@ -107,6 +109,13 @@ pub(crate) fn resolve_name_ref( let database_name = Name::from_node(name_ref); resolve_database(binder, &database_name).map(|ptr| smallvec![ptr]) } + NameRefClass::DropServer + | NameRefClass::AlterServer + | NameRefClass::CreateServer + | NameRefClass::ForeignTableServerName => { + let server_name = Name::from_node(name_ref); + resolve_server(binder, &server_name).map(|ptr| smallvec![ptr]) + } NameRefClass::SequenceOwnedByColumn => { let sequence_option = name_ref .syntax() @@ -149,77 +158,21 @@ pub(crate) fn resolve_name_ref( let column_name = Name::from_node(name_ref); resolve_column_for_path(binder, root, &path, column_name).map(|ptr| smallvec![ptr]) } - NameRefClass::ForeignKeyLocalColumn => { - let create_table = name_ref - .syntax() - .ancestors() - .find_map(ast::CreateTable::cast)?; - let column_name = Name::from_node(name_ref); - find_column_in_create_table(&create_table, &column_name).map(|ptr| smallvec![ptr]) - } - NameRefClass::CheckConstraintColumn => { - let create_table = name_ref - .syntax() - .ancestors() - .find_map(ast::CreateTable::cast)?; - let column_name = Name::from_node(name_ref); - find_column_in_create_table(&create_table, &column_name).map(|ptr| smallvec![ptr]) - } - NameRefClass::GeneratedColumn => { - let create_table = name_ref - .syntax() - .ancestors() - .find_map(ast::CreateTable::cast)?; - let column_name = Name::from_node(name_ref); - find_column_in_create_table(&create_table, &column_name).map(|ptr| smallvec![ptr]) - } - NameRefClass::UniqueConstraintColumn => { - let create_table = name_ref - .syntax() - .ancestors() - .find_map(ast::CreateTable::cast)?; - let column_name = Name::from_node(name_ref); - find_column_in_create_table(&create_table, &column_name).map(|ptr| smallvec![ptr]) - } - NameRefClass::PrimaryKeyConstraintColumn => { - let create_table = name_ref - .syntax() - .ancestors() - .find_map(ast::CreateTable::cast)?; - let column_name = Name::from_node(name_ref); - find_column_in_create_table(&create_table, &column_name).map(|ptr| smallvec![ptr]) - } - NameRefClass::NotNullConstraintColumn => { - let create_table = name_ref - .syntax() - .ancestors() - .find_map(ast::CreateTable::cast)?; - let column_name = Name::from_node(name_ref); - find_column_in_create_table(&create_table, &column_name).map(|ptr| smallvec![ptr]) - } - NameRefClass::ExcludeConstraintColumn => { - let create_table = name_ref - .syntax() - .ancestors() - .find_map(ast::CreateTable::cast)?; - let column_name = Name::from_node(name_ref); - find_column_in_create_table(&create_table, &column_name).map(|ptr| smallvec![ptr]) - } - NameRefClass::PartitionByColumn => { + NameRefClass::GeneratedColumn + | NameRefClass::CheckConstraintColumn + | NameRefClass::UniqueConstraintColumn + | NameRefClass::PrimaryKeyConstraintColumn + | NameRefClass::NotNullConstraintColumn + | NameRefClass::ExcludeConstraintColumn + | NameRefClass::PartitionByColumn + | NameRefClass::ForeignKeyLocalColumn => { let create_table = name_ref .syntax() .ancestors() - .find_map(ast::CreateTable::cast)?; + .find_map(ast::CreateTableLike::cast)?; let column_name = Name::from_node(name_ref); find_column_in_create_table(&create_table, &column_name).map(|ptr| smallvec![ptr]) } - NameRefClass::PartitionOfTable => { - let path = find_containing_path(name_ref)?; - let table_name = extract_table_name(&path)?; - let schema = extract_schema_name(&path); - let position = name_ref.syntax().text_range().start(); - resolve_table(binder, &table_name, &schema, position).map(|ptr| smallvec![ptr]) - } NameRefClass::LikeTable => { let like_clause = name_ref .syntax() @@ -231,13 +184,6 @@ pub(crate) fn resolve_name_ref( let position = name_ref.syntax().text_range().start(); resolve_table(binder, &table_name, &schema, position).map(|ptr| smallvec![ptr]) } - NameRefClass::InheritsTable => { - let path = find_containing_path(name_ref)?; - let table_name = extract_table_name(&path)?; - let schema = extract_schema_name(&path); - let position = name_ref.syntax().text_range().start(); - resolve_table(binder, &table_name, &schema, position).map(|ptr| smallvec![ptr]) - } NameRefClass::DropFunction => { let function_sig = name_ref .syntax() @@ -502,6 +448,15 @@ fn resolve_database(binder: &Binder, database_name: &Name) -> Option Option { + let symbols = binder.scopes[binder.root_scope()].get(server_name)?; + let symbol_id = symbols.iter().copied().find(|id| { + let symbol = &binder.symbols[*id]; + symbol.kind == SymbolKind::Server + })?; + Some(binder.symbols[symbol_id].ptr) +} + fn resolve_for_kind( binder: &Binder, name: &Name, @@ -1751,8 +1706,7 @@ fn collect_tables_from_item( pub(crate) enum TableSource { WithTable(ast::WithTable), CreateView(ast::CreateView), - CreateTable(ast::CreateTable), - CreateForeignTable(ast::CreateForeignTable), + CreateTable(ast::CreateTableLike), } pub(crate) fn find_table_source(node: &SyntaxNode) -> Option { @@ -1765,13 +1719,9 @@ pub(crate) fn find_table_source(node: &SyntaxNode) -> Option { return Some(TableSource::CreateView(create_view)); } - if let Some(create_table) = ast::CreateTable::cast(ancestor.clone()) { + if let Some(create_table) = ast::CreateTableLike::cast(ancestor.clone()) { return Some(TableSource::CreateTable(create_table)); } - - if let Some(create_foreign_table) = ast::CreateForeignTable::cast(ancestor) { - return Some(TableSource::CreateForeignTable(create_foreign_table)); - } } None @@ -2063,7 +2013,7 @@ pub(crate) fn resolve_insert_create_table( root: &SyntaxNode, binder: &Binder, insert: &ast::Insert, -) -> Option { +) -> Option { let path = insert.path()?; let table_name = extract_table_name(&path)?; let schema = extract_schema_name(&path); @@ -2072,7 +2022,9 @@ pub(crate) fn resolve_insert_create_table( let table_ptr = resolve_table(binder, &table_name, &schema, position)?; let table_name_node = table_ptr.to_node(root); - table_name_node.ancestors().find_map(ast::CreateTable::cast) + table_name_node + .ancestors() + .find_map(ast::CreateTableLike::cast) } pub(crate) fn resolve_table_info(binder: &Binder, path: &ast::Path) -> Option<(Schema, String)> { diff --git a/crates/squawk_ide/src/symbols.rs b/crates/squawk_ide/src/symbols.rs index 954069da..5a33641c 100644 --- a/crates/squawk_ide/src/symbols.rs +++ b/crates/squawk_ide/src/symbols.rs @@ -55,6 +55,7 @@ pub(crate) enum SymbolKind { Sequence, Tablespace, Database, + Server, } #[derive(Clone, Debug)] diff --git a/crates/squawk_linter/Cargo.toml b/crates/squawk_linter/Cargo.toml index af70b34f..31ddbdaa 100644 --- a/crates/squawk_linter/Cargo.toml +++ b/crates/squawk_linter/Cargo.toml @@ -10,6 +10,9 @@ documentation.workspace = true homepage.workspace = true repository.workspace = true +[lib] +doctest = false + [dependencies] squawk-syntax.workspace = true diff --git a/crates/squawk_parser/src/generated/syntax_kind.rs b/crates/squawk_parser/src/generated/syntax_kind.rs index 629ec380..b62f24d8 100644 --- a/crates/squawk_parser/src/generated/syntax_kind.rs +++ b/crates/squawk_parser/src/generated/syntax_kind.rs @@ -803,7 +803,6 @@ pub enum SyntaxKind { FRAME_CLAUSE, FROM_CLAUSE, FROM_ITEM, - FROM_SERVER, FROM_TABLE, FUNCTION_SIG, FUNCTION_SIG_LIST, @@ -1058,6 +1057,7 @@ pub enum SyntaxKind { SEQUENCE_OPTION, SEQUENCE_OPTION_LIST, SERIALIZABLE, + SERVER_NAME, SET, SET_ACCESS_METHOD, SET_CLAUSE, diff --git a/crates/squawk_parser/src/grammar.rs b/crates/squawk_parser/src/grammar.rs index 8126bdcb..a5421b39 100644 --- a/crates/squawk_parser/src/grammar.rs +++ b/crates/squawk_parser/src/grammar.rs @@ -8017,14 +8017,20 @@ fn alter_user_mapping(p: &mut Parser<'_>) -> CompletedMarker { p.bump(MAPPING_KW); p.expect(FOR_KW); role(p); - p.expect(SERVER_KW); - name_ref(p); + server_name(p); if !opt_alter_option_list(p) { p.error("expected options"); } m.complete(p, ALTER_USER_MAPPING) } +fn server_name(p: &mut Parser<'_>) { + let m = p.start(); + p.expect(SERVER_KW); + name_ref(p); + m.complete(p, SERVER_NAME); +} + const ALTER_OPTION_FIRST: TokenSet = TokenSet::new(&[DROP_KW, ADD_KW, SET_KW]).union(COL_LABEL_FIRST); @@ -8724,8 +8730,7 @@ fn create_foreign_table(p: &mut Parser<'_>) -> CompletedMarker { } opt_inherits_tables(p); } - p.expect(SERVER_KW); - name_ref(p); + server_name(p); opt_alter_option_list(p); m.complete(p, CREATE_FOREIGN_TABLE) } @@ -9489,9 +9494,7 @@ fn create_user_mapping(p: &mut Parser<'_>) -> CompletedMarker { if !p.eat(USER_KW) { role(p); } - p.eat(SERVER_KW); - // server_name - name_ref(p); + server_name(p); opt_alter_option_list(p); m.complete(p, CREATE_USER_MAPPING) } @@ -10168,9 +10171,7 @@ fn drop_user_mapping(p: &mut Parser<'_>) -> CompletedMarker { if !p.eat(USER_KW) { role(p); } - p.eat(SERVER_KW); - // server_name - name_ref(p); + server_name(p); m.complete(p, DROP_USER_MAPPING) } @@ -10322,7 +10323,8 @@ fn import_foreign_schema(p: &mut Parser<'_>) -> CompletedMarker { p.expect(R_PAREN); m.complete(p, kind); } - from_server(p); + p.expect(FROM_KW); + server_name(p); into_schema(p); opt_alter_option_list(p); m.complete(p, IMPORT_FOREIGN_SCHEMA) @@ -10336,15 +10338,6 @@ fn into_schema(p: &mut Parser<'_>) { m.complete(p, INTO_SCHEMA); } -// FROM SERVER server_name -fn from_server(p: &mut Parser<'_>) { - let m = p.start(); - p.expect(FROM_KW); - p.expect(SERVER_KW); - name_ref(p); - m.complete(p, FROM_SERVER); -} - // LOCK [ TABLE ] [ ONLY ] name [ * ] [, ...] [ IN lockmode MODE ] [ NOWAIT ] // where lockmode is one of: // ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE diff --git a/crates/squawk_parser/tests/snapshots/tests__alter_user_mapping_ok.snap b/crates/squawk_parser/tests/snapshots/tests__alter_user_mapping_ok.snap index 7dad2c8a..eaea492b 100644 --- a/crates/squawk_parser/tests/snapshots/tests__alter_user_mapping_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__alter_user_mapping_ok.snap @@ -17,10 +17,11 @@ SOURCE_FILE ROLE CURRENT_ROLE_KW "current_role" WHITESPACE "\n " - SERVER_KW "server" - WHITESPACE " " - NAME_REF - IDENT "s" + SERVER_NAME + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" WHITESPACE "\n " ALTER_OPTION_LIST OPTIONS_KW "options" diff --git a/crates/squawk_parser/tests/snapshots/tests__create_foreign_table_ok.snap b/crates/squawk_parser/tests/snapshots/tests__create_foreign_table_ok.snap index def07967..dba3a546 100644 --- a/crates/squawk_parser/tests/snapshots/tests__create_foreign_table_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__create_foreign_table_ok.snap @@ -20,10 +20,11 @@ SOURCE_FILE L_PAREN "(" R_PAREN ")" WHITESPACE "\n " - SERVER_KW "server" - WHITESPACE " " - NAME_REF - IDENT "s" + SERVER_NAME + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- full" @@ -212,10 +213,11 @@ SOURCE_FILE IDENT "bar" R_PAREN ")" WHITESPACE "\n " - SERVER_KW "server" - WHITESPACE " " - NAME_REF - IDENT "s" + SERVER_NAME + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" WHITESPACE "\n " ALTER_OPTION_LIST OPTIONS_KW "options" @@ -264,10 +266,11 @@ SOURCE_FILE PARTITION_DEFAULT DEFAULT_KW "default" WHITESPACE "\n " - SERVER_KW "server" - WHITESPACE " " - NAME_REF - IDENT "s" + SERVER_NAME + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- partitioned" @@ -369,10 +372,11 @@ SOURCE_FILE PARTITION_DEFAULT DEFAULT_KW "default" WHITESPACE "\n " - SERVER_KW "server" - WHITESPACE " " - NAME_REF - IDENT "s" + SERVER_NAME + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" WHITESPACE "\n " ALTER_OPTION_LIST OPTIONS_KW "options" @@ -451,10 +455,11 @@ SOURCE_FILE IDENT "b" R_PAREN ")" WHITESPACE "\n " - SERVER_KW "server" - WHITESPACE " " - NAME_REF - IDENT "s" + SERVER_NAME + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- partitioned_bound_spec_from" @@ -532,10 +537,11 @@ SOURCE_FILE MINVALUE_KW "minvalue" R_PAREN ")" WHITESPACE "\n " - SERVER_KW "server" - WHITESPACE " " - NAME_REF - IDENT "s" + SERVER_NAME + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- partitioned_bound_spec_with" @@ -594,10 +600,11 @@ SOURCE_FILE INT_NUMBER "2" R_PAREN ")" WHITESPACE "\n " - SERVER_KW "server" - WHITESPACE " " - NAME_REF - IDENT "s" + SERVER_NAME + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- with schema" @@ -634,10 +641,11 @@ SOURCE_FILE WHITESPACE "\n" R_PAREN ")" WHITESPACE "\n " - SERVER_KW "server" - WHITESPACE " " - NAME_REF - IDENT "cal_server" + SERVER_NAME + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "cal_server" WHITESPACE "\n " ALTER_OPTION_LIST OPTIONS_KW "options" diff --git a/crates/squawk_parser/tests/snapshots/tests__create_foreign_table_pg18_ok.snap b/crates/squawk_parser/tests/snapshots/tests__create_foreign_table_pg18_ok.snap index 98aaecb1..8da7b894 100644 --- a/crates/squawk_parser/tests/snapshots/tests__create_foreign_table_pg18_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__create_foreign_table_pg18_ok.snap @@ -30,10 +30,11 @@ SOURCE_FILE WHITESPACE "\n" R_PAREN ")" WHITESPACE " " - SERVER_KW "server" - WHITESPACE " " - NAME_REF - IDENT "s" + SERVER_NAME + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- like clause is >=pg18" @@ -88,9 +89,10 @@ SOURCE_FILE WHITESPACE "\n" R_PAREN ")" WHITESPACE " " - SERVER_KW "server" - WHITESPACE " " - NAME_REF - IDENT "remote_server" + SERVER_NAME + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "remote_server" SEMICOLON ";" WHITESPACE "\n\n" diff --git a/crates/squawk_parser/tests/snapshots/tests__drop_user_mapping_ok.snap b/crates/squawk_parser/tests/snapshots/tests__drop_user_mapping_ok.snap index 793fd144..bfd6a9a5 100644 --- a/crates/squawk_parser/tests/snapshots/tests__drop_user_mapping_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__drop_user_mapping_ok.snap @@ -16,10 +16,11 @@ SOURCE_FILE WHITESPACE " " USER_KW "user" WHITESPACE " " - SERVER_KW "server" - WHITESPACE " " - NAME_REF - IDENT "s" + SERVER_NAME + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- full" @@ -41,9 +42,10 @@ SOURCE_FILE ROLE CURRENT_ROLE_KW "current_role" WHITESPACE " " - SERVER_KW "server" - WHITESPACE " " - NAME_REF - IDENT "some_server_name" + SERVER_NAME + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "some_server_name" SEMICOLON ";" WHITESPACE "\n\n" diff --git a/crates/squawk_parser/tests/snapshots/tests__import_foreign_schema_ok.snap b/crates/squawk_parser/tests/snapshots/tests__import_foreign_schema_ok.snap index 506209a9..a78f8257 100644 --- a/crates/squawk_parser/tests/snapshots/tests__import_foreign_schema_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__import_foreign_schema_ok.snap @@ -15,9 +15,9 @@ SOURCE_FILE NAME_REF IDENT "s" WHITESPACE "\n " - FROM_SERVER - FROM_KW "from" - WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + SERVER_NAME SERVER_KW "server" WHITESPACE " " NAME_REF @@ -54,9 +54,9 @@ SOURCE_FILE IDENT "t2" R_PAREN ")" WHITESPACE "\n " - FROM_SERVER - FROM_KW "FROM" - WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + SERVER_NAME SERVER_KW "SERVER" WHITESPACE " " NAME_REF @@ -81,9 +81,9 @@ SOURCE_FILE NAME_REF IDENT "a" WHITESPACE "\n " - FROM_SERVER - FROM_KW "from" - WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + SERVER_NAME SERVER_KW "server" WHITESPACE " " NAME_REF @@ -120,9 +120,9 @@ SOURCE_FILE NAME_REF IDENT "a" WHITESPACE "\n " - FROM_SERVER - FROM_KW "from" - WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + SERVER_NAME SERVER_KW "server" WHITESPACE " " NAME_REF @@ -167,9 +167,9 @@ SOURCE_FILE NAME_REF IDENT "foreign_films" WHITESPACE "\n " - FROM_SERVER - FROM_KW "FROM" - WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + SERVER_NAME SERVER_KW "SERVER" WHITESPACE " " NAME_REF @@ -208,9 +208,9 @@ SOURCE_FILE IDENT "directors" R_PAREN ")" WHITESPACE "\n " - FROM_SERVER - FROM_KW "FROM" - WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + SERVER_NAME SERVER_KW "SERVER" WHITESPACE " " NAME_REF diff --git a/crates/squawk_parser/tests/snapshots/tests__misc_ok.snap b/crates/squawk_parser/tests/snapshots/tests__misc_ok.snap index 02a1a1fc..3b5b5ca9 100644 --- a/crates/squawk_parser/tests/snapshots/tests__misc_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__misc_ok.snap @@ -3327,10 +3327,11 @@ SOURCE_FILE WHITESPACE "\n" R_PAREN ")" WHITESPACE "\n " - SERVER_KW "server" - WHITESPACE " " - NAME_REF - IDENT "cal_server" + SERVER_NAME + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "cal_server" WHITESPACE "\n " ALTER_OPTION_LIST OPTIONS_KW "options" @@ -3379,10 +3380,11 @@ SOURCE_FILE WHITESPACE "\n" R_PAREN ")" WHITESPACE "\n " - SERVER_KW "server" - WHITESPACE " " - NAME_REF - IDENT "cal_server" + SERVER_NAME + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "cal_server" WHITESPACE "\n " ALTER_OPTION_LIST OPTIONS_KW "options" @@ -4435,10 +4437,11 @@ SOURCE_FILE NUMERIC_KW "numeric" R_PAREN ")" WHITESPACE " " - SERVER_KW "SERVER" - WHITESPACE " " - NAME_REF - IDENT "cstore_server" + SERVER_NAME + SERVER_KW "SERVER" + WHITESPACE " " + NAME_REF + IDENT "cstore_server" WHITESPACE "\n" ALTER_OPTION_LIST OPTIONS_KW "OPTIONS" @@ -4510,10 +4513,11 @@ SOURCE_FILE WHITESPACE "\n" R_PAREN ")" WHITESPACE " " - SERVER_KW "SERVER" - WHITESPACE " " - NAME_REF - IDENT "parquet_server" + SERVER_NAME + SERVER_KW "SERVER" + WHITESPACE " " + NAME_REF + IDENT "parquet_server" WHITESPACE "\n" ALTER_OPTION_LIST OPTIONS_KW "OPTIONS" diff --git a/crates/squawk_server/Cargo.toml b/crates/squawk_server/Cargo.toml index 33278367..4fbd5bf6 100644 --- a/crates/squawk_server/Cargo.toml +++ b/crates/squawk_server/Cargo.toml @@ -10,6 +10,9 @@ documentation.workspace = true homepage.workspace = true repository.workspace = true +[lib] +doctest = false + [dependencies] anyhow.workspace = true log.workspace = true diff --git a/crates/squawk_syntax/Cargo.toml b/crates/squawk_syntax/Cargo.toml index b44f7ffa..44c2c014 100644 --- a/crates/squawk_syntax/Cargo.toml +++ b/crates/squawk_syntax/Cargo.toml @@ -10,6 +10,9 @@ documentation.workspace = true homepage.workspace = true repository.workspace = true +[lib] +doctest = false + [dependencies] squawk-parser.workspace = true rowan.workspace = true diff --git a/crates/squawk_syntax/src/ast/generated/nodes.rs b/crates/squawk_syntax/src/ast/generated/nodes.rs index 6895d384..93c8f78b 100644 --- a/crates/squawk_syntax/src/ast/generated/nodes.rs +++ b/crates/squawk_syntax/src/ast/generated/nodes.rs @@ -1638,11 +1638,11 @@ impl AlterUserMapping { support::child(&self.syntax) } #[inline] - pub fn name_ref(&self) -> Option { + pub fn role(&self) -> Option { support::child(&self.syntax) } #[inline] - pub fn role(&self) -> Option { + pub fn server_name(&self) -> Option { support::child(&self.syntax) } #[inline] @@ -1658,10 +1658,6 @@ impl AlterUserMapping { support::token(&self.syntax, SyntaxKind::MAPPING_KW) } #[inline] - pub fn server_token(&self) -> Option { - support::token(&self.syntax, SyntaxKind::SERVER_KW) - } - #[inline] pub fn user_token(&self) -> Option { support::token(&self.syntax, SyntaxKind::USER_KW) } @@ -3504,10 +3500,6 @@ impl CreateForeignTable { support::child(&self.syntax) } #[inline] - pub fn name_ref(&self) -> Option { - support::child(&self.syntax) - } - #[inline] pub fn partition_of(&self) -> Option { support::child(&self.syntax) } @@ -3520,6 +3512,10 @@ impl CreateForeignTable { support::child(&self.syntax) } #[inline] + pub fn server_name(&self) -> Option { + support::child(&self.syntax) + } + #[inline] pub fn table_arg_list(&self) -> Option { support::child(&self.syntax) } @@ -3532,10 +3528,6 @@ impl CreateForeignTable { support::token(&self.syntax, SyntaxKind::FOREIGN_KW) } #[inline] - pub fn server_token(&self) -> Option { - support::token(&self.syntax, SyntaxKind::SERVER_KW) - } - #[inline] pub fn table_token(&self) -> Option { support::token(&self.syntax, SyntaxKind::TABLE_KW) } @@ -4926,11 +4918,11 @@ impl CreateUserMapping { support::child(&self.syntax) } #[inline] - pub fn name_ref(&self) -> Option { + pub fn role(&self) -> Option { support::child(&self.syntax) } #[inline] - pub fn role(&self) -> Option { + pub fn server_name(&self) -> Option { support::child(&self.syntax) } #[inline] @@ -4946,10 +4938,6 @@ impl CreateUserMapping { support::token(&self.syntax, SyntaxKind::MAPPING_KW) } #[inline] - pub fn server_token(&self) -> Option { - support::token(&self.syntax, SyntaxKind::SERVER_KW) - } - #[inline] pub fn user_token(&self) -> Option { support::token(&self.syntax, SyntaxKind::USER_KW) } @@ -7012,11 +7000,11 @@ impl DropUserMapping { support::child(&self.syntax) } #[inline] - pub fn name_ref(&self) -> Option { + pub fn role(&self) -> Option { support::child(&self.syntax) } #[inline] - pub fn role(&self) -> Option { + pub fn server_name(&self) -> Option { support::child(&self.syntax) } #[inline] @@ -7032,10 +7020,6 @@ impl DropUserMapping { support::token(&self.syntax, SyntaxKind::MAPPING_KW) } #[inline] - pub fn server_token(&self) -> Option { - support::token(&self.syntax, SyntaxKind::SERVER_KW) - } - #[inline] pub fn user_token(&self) -> Option { support::token(&self.syntax, SyntaxKind::USER_KW) } @@ -7832,25 +7816,6 @@ impl FromItem { } } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct FromServer { - pub(crate) syntax: SyntaxNode, -} -impl FromServer { - #[inline] - pub fn name_ref(&self) -> Option { - support::child(&self.syntax) - } - #[inline] - pub fn from_token(&self) -> Option { - support::token(&self.syntax, SyntaxKind::FROM_KW) - } - #[inline] - pub fn server_token(&self) -> Option { - support::token(&self.syntax, SyntaxKind::SERVER_KW) - } -} - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FromTable { pub(crate) syntax: SyntaxNode, @@ -8279,10 +8244,6 @@ impl ImportForeignSchema { support::child(&self.syntax) } #[inline] - pub fn from_server(&self) -> Option { - support::child(&self.syntax) - } - #[inline] pub fn into_schema(&self) -> Option { support::child(&self.syntax) } @@ -8295,10 +8256,18 @@ impl ImportForeignSchema { support::child(&self.syntax) } #[inline] + pub fn server_name(&self) -> Option { + support::child(&self.syntax) + } + #[inline] pub fn foreign_token(&self) -> Option { support::token(&self.syntax, SyntaxKind::FOREIGN_KW) } #[inline] + pub fn from_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::FROM_KW) + } + #[inline] pub fn import_token(&self) -> Option { support::token(&self.syntax, SyntaxKind::IMPORT_KW) } @@ -13872,6 +13841,21 @@ impl Serializable { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct ServerName { + pub(crate) syntax: SyntaxNode, +} +impl ServerName { + #[inline] + pub fn name_ref(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn server_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::SERVER_KW) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Set { pub(crate) syntax: SyntaxNode, @@ -21672,24 +21656,6 @@ impl AstNode for FromItem { &self.syntax } } -impl AstNode for FromServer { - #[inline] - fn can_cast(kind: SyntaxKind) -> bool { - kind == SyntaxKind::FROM_SERVER - } - #[inline] - fn cast(syntax: SyntaxNode) -> Option { - if Self::can_cast(syntax.kind()) { - Some(Self { syntax }) - } else { - None - } - } - #[inline] - fn syntax(&self) -> &SyntaxNode { - &self.syntax - } -} impl AstNode for FromTable { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -26262,6 +26228,24 @@ impl AstNode for Serializable { &self.syntax } } +impl AstNode for ServerName { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::SERVER_NAME + } + #[inline] + fn cast(syntax: SyntaxNode) -> Option { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + #[inline] + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } +} impl AstNode for Set { #[inline] fn can_cast(kind: SyntaxKind) -> bool { diff --git a/crates/squawk_syntax/src/postgresql.ungram b/crates/squawk_syntax/src/postgresql.ungram index e17490c1..090de625 100644 --- a/crates/squawk_syntax/src/postgresql.ungram +++ b/crates/squawk_syntax/src/postgresql.ungram @@ -2076,7 +2076,7 @@ AlterUser = 'alter' 'user' Role AlterUserMapping = - 'alter' 'user' 'mapping' 'for' Role 'server' NameRef AlterOptionList + 'alter' 'user' 'mapping' 'for' Role ServerName AlterOptionList AlterView = 'alter' 'view' Path @@ -2159,9 +2159,12 @@ CreateForeignTable = TableArgList? Inherits? PartitionType? - ('server' NameRef) + ServerName AlterOptionList? +ServerName = + 'server' NameRef + CreateGroup = 'create' 'group' Name RoleOptionList @@ -2273,7 +2276,7 @@ TransformToFunc = CreateUserMapping = 'create' 'user' 'mapping' IfNotExists? 'for' Role - 'server' NameRef + ServerName AlterOptionList? CreateUser = @@ -2435,7 +2438,7 @@ DropUser = 'drop' 'user' IfExists? (NameRef (',' NameRef)*) DropUserMapping = - 'drop' 'user' 'mapping' IfExists? 'for' Role 'server' NameRef + 'drop' 'user' 'mapping' IfExists? 'for' Role ServerName DropView = 'drop' 'view' IfExists? Path @@ -2465,7 +2468,7 @@ ExplainStmt = ImportForeignSchema = 'import' 'foreign' 'schema' NameRef (LimitToTables | ExceptTables)? - FromServer + 'from' ServerName IntoSchema AlterOptionList? @@ -2475,9 +2478,6 @@ LimitToTables = ExceptTables = 'except' (NameRef (',' NameRef)*) -FromServer = - 'from' 'server' NameRef - IntoSchema = 'into' NameRef diff --git a/crates/squawk_wasm/Cargo.toml b/crates/squawk_wasm/Cargo.toml index 56803701..b36aafb6 100644 --- a/crates/squawk_wasm/Cargo.toml +++ b/crates/squawk_wasm/Cargo.toml @@ -12,6 +12,7 @@ repository.workspace = true [lib] crate-type = ["cdylib", "rlib"] +doctest = false [features] default = ["console_error_panic_hook"]