diff --git a/crates/squawk_ide/src/classify.rs b/crates/squawk_ide/src/classify.rs index ecc3143f..595143d7 100644 --- a/crates/squawk_ide/src/classify.rs +++ b/crates/squawk_ide/src/classify.rs @@ -1106,10 +1106,12 @@ pub(crate) fn classify_def_node(def_node: &SyntaxNode) -> Option { if let Some(class) = classify_object_definition(ancestor.kind()) { return Some(class); } - if ast::Column::can_cast(ancestor.kind()) || ast::AliasColumn::can_cast(ancestor.kind()) { + if ast::Column::can_cast(ancestor.kind()) || ast::ColumnDef::can_cast(ancestor.kind()) { in_column = true; } - if ast::ColumnList::can_cast(ancestor.kind()) { + if ast::ColumnList::can_cast(ancestor.kind()) + || ast::ColumnDefList::can_cast(ancestor.kind()) + { in_column_list = true; } if ast::Param::can_cast(ancestor.kind()) { @@ -1149,7 +1151,7 @@ pub(crate) fn classify_def_node(def_node: &SyntaxNode) -> Option { || ast::OptionalAsAlias::can_cast(ancestor.kind()) || ast::RequiredAsAlias::can_cast(ancestor.kind()) { - if in_column { + if in_column || in_column_list { return Some(LocationKind::Column); } return Some(LocationKind::Table); diff --git a/crates/squawk_ide/src/collect.rs b/crates/squawk_ide/src/collect.rs index 76b531b6..6b5433d3 100644 --- a/crates/squawk_ide/src/collect.rs +++ b/crates/squawk_ide/src/collect.rs @@ -687,7 +687,7 @@ fn columns_for_star_from_from_item( from_item: &ast::FromItem, ) -> Vec<(Name, Option)> { if let Some(alias) = from_item.alias() - && alias.column_list().is_some() + && alias.columns().is_some() { return columns_for_star_from_alias(db, file, from_item, &alias); } @@ -706,9 +706,9 @@ pub(crate) fn columns_for_star_from_alias( alias: &ast::FromAlias, ) -> Vec<(Name, Option)> { let alias_columns: Vec = alias - .column_list() + .columns() .into_iter() - .flat_map(|column_list| column_list.column_names()) + .flat_map(|columns| columns.column_names()) .map(|name| Name::from_node(&name)) .collect(); @@ -833,9 +833,9 @@ pub(crate) fn star_column_names(db: &dyn Db, file: File, table_ptr: &SyntaxNodeP match ast_nav::parent_source(&table_name_node) { Some(ast_nav::ParentSouce::Alias(alias)) => alias - .column_list() + .columns() .into_iter() - .flat_map(|column_list| column_list.column_names()) + .flat_map(|columns| columns.column_names()) .map(|name| Name::from_node(&name)) .collect(), Some(ast_nav::ParentSouce::WithTable(with_table)) => { diff --git a/crates/squawk_ide/src/completion.rs b/crates/squawk_ide/src/completion.rs index 3f7edd41..c3ee0fda 100644 --- a/crates/squawk_ide/src/completion.rs +++ b/crates/squawk_ide/src/completion.rs @@ -400,9 +400,9 @@ fn column_completions_from_clause( } Some(ast_nav::ParentSouce::Alias(alias)) => { let alias_columns: Vec = alias - .column_list() + .columns() .into_iter() - .flat_map(|column_list| column_list.column_names()) + .flat_map(|columns| columns.column_names()) .map(|name| Name::from_node(&name)) .collect(); diff --git a/crates/squawk_ide/src/expand_selection.rs b/crates/squawk_ide/src/expand_selection.rs index 7f91f969..97ddcab9 100644 --- a/crates/squawk_ide/src/expand_selection.rs +++ b/crates/squawk_ide/src/expand_selection.rs @@ -38,12 +38,12 @@ use crate::tokens::is_string_or_comment; const DELIMITED_LIST_KINDS: &[SyntaxKind] = &[ SyntaxKind::ALTER_OPTION_LIST, - SyntaxKind::ALIAS_COLUMN_LIST, SyntaxKind::ALTER_TYPE_ATTRIBUTE_ACTION_LIST, SyntaxKind::ARG_LIST, SyntaxKind::ATTRIBUTE_LIST, SyntaxKind::BEGIN_FUNC_OPTION_LIST, SyntaxKind::CHECKPOINT_OPTION_LIST, + SyntaxKind::COLUMN_DEF_LIST, SyntaxKind::COLUMN_LIST, SyntaxKind::COLUMN_REF_LIST, SyntaxKind::COLUMN_TARGET_LIST, diff --git a/crates/squawk_ide/src/folding_ranges.rs b/crates/squawk_ide/src/folding_ranges.rs index f3087a6b..d8c9b00e 100644 --- a/crates/squawk_ide/src/folding_ranges.rs +++ b/crates/squawk_ide/src/folding_ranges.rs @@ -135,12 +135,12 @@ fn fold_kind(kind: SyntaxKind) -> Option { SyntaxKind::TUPLE_EXPR => Some(FoldKind::Tuple), SyntaxKind::WHERE_CLAUSE => Some(FoldKind::WhereClause), SyntaxKind::WHEN_CLAUSE_LIST - | SyntaxKind::ALIAS_COLUMN_LIST | SyntaxKind::ALTER_OPTION_LIST | SyntaxKind::ALTER_TYPE_ATTRIBUTE_ACTION_LIST | SyntaxKind::ATTRIBUTE_LIST | SyntaxKind::BEGIN_FUNC_OPTION_LIST | SyntaxKind::CHECKPOINT_OPTION_LIST + | SyntaxKind::COLUMN_DEF_LIST | SyntaxKind::COLUMN_LIST | SyntaxKind::COLUMN_REF_LIST | SyntaxKind::COLUMN_TARGET_LIST diff --git a/crates/squawk_ide/src/hover.rs b/crates/squawk_ide/src/hover.rs index 3cc1cd4e..99994be0 100644 --- a/crates/squawk_ide/src/hover.rs +++ b/crates/squawk_ide/src/hover.rs @@ -631,7 +631,7 @@ fn format_hover_for_column_ptr(db: &dyn Db, def: Location) -> Option { } ast_nav::ParentSouce::Alias(alias) => { let alias_name = alias.name()?; - alias.column_list()?; + alias.columns()?; let from_item = alias.syntax().ancestors().find_map(ast::FromItem::cast)?; let table_name = Name::from_node(&alias_name); let column_name = Name::from_string(def_node.text().to_string()); @@ -802,7 +802,7 @@ fn format_alias_with_column_list(db: &dyn Db, alias: InFile) -> let alias_name = alias.name()?; let name = Name::from_node(&alias_name); - let Some(column_list) = alias.column_list() else { + let Some(alias_columns) = alias.columns() else { let name = Name::from_node(&alias.name()?); let from_item = alias.syntax().ancestors().find_map(ast::FromItem::cast)?; let ast::FromItem::ParenFromItem(paren) = from_item else { @@ -812,7 +812,7 @@ fn format_alias_with_column_list(db: &dyn Db, alias: InFile) -> return format_subquery_table(name, paren_select); }; - let mut columns: Vec = column_list + let mut columns: Vec = alias_columns .column_names() .map(|column_name| Name::from_node(&column_name)) .collect(); @@ -954,7 +954,7 @@ fn hover_qualified_star_columns_from_alias( let file = alias.file_id; let alias = alias.value; let alias_name = Name::from_node(&alias.name()?); - alias.column_list()?; + alias.columns()?; let from_item = alias.syntax().ancestors().find_map(ast::FromItem::cast)?; let columns = collect::columns_for_star_from_alias(db, file, &from_item, alias); @@ -2034,7 +2034,7 @@ fn qualified_star_from_clause_table_ptr( let from_item = resolve::find_from_item_in_from_clause(&from_clause, table_name)?; if let Some(alias) = from_item.alias() - && alias.column_list().is_some() + && alias.columns().is_some() { return Some(SyntaxNodePtr::new(alias.syntax())); } diff --git a/crates/squawk_ide/src/resolve.rs b/crates/squawk_ide/src/resolve.rs index 8d8e6156..8c162b13 100644 --- a/crates/squawk_ide/src/resolve.rs +++ b/crates/squawk_ide/src/resolve.rs @@ -2060,7 +2060,7 @@ fn resolve_select_qualified_column_ptr( return Some(ptr); } - if from_item.alias().and_then(|a| a.column_list()).is_none() + if from_item.alias().and_then(|a| a.columns()).is_none() && column_name == Name::from_string("ordinality") && let Some(ordinality_token) = from_item .with_ordinality() @@ -2101,8 +2101,8 @@ fn resolve_select_qualified_column_ptr( } // `from t as u(a, b, c)` - if let Some(column_list) = alias.column_list() { - for col_name in column_list.column_names() { + if let Some(columns) = alias.columns() { + for col_name in columns.column_names() { if Name::from_node(&col_name) == column_name { return Some(smallvec![Location::new( file, @@ -2447,13 +2447,10 @@ fn resolve_from_item_column_by_name_after_index( if let ast::FromItem::RowsFromItem(rows_from) = from_item { let mut remaining_skip = skip_column_count; for arg in rows_from.rows_from_args() { - if let Some(column_def_list) = arg - .column_def_list() - .filter(|alias| alias.column_list().is_some()) - { + if let Some(column_def_list) = arg.column_def_list() { let (column_count, column) = resolve_column_list_column( file, - alias_column_names(Some(column_def_list)), + column_def_list.column_names(), column_name, remaining_skip, ); @@ -2545,7 +2542,7 @@ fn resolve_from_item_column_by_name_after_index( } if original_skip == 0 - && from_item.alias().and_then(|a| a.column_list()).is_none() + && from_item.alias().and_then(|a| a.columns()).is_none() && *column_name == Name::from_string("ordinality") && let Some(ordinality_token) = from_item .with_ordinality() @@ -3371,9 +3368,9 @@ fn column_list_names( fn alias_column_names(alias: Option) -> impl Iterator { alias - .and_then(|alias| alias.column_list()) + .and_then(|alias| alias.columns()) .into_iter() - .flat_map(|column_list| column_list.column_names()) + .flat_map(|columns| columns.column_names()) } fn resolve_column_list_column( @@ -4489,7 +4486,7 @@ pub(crate) fn table_ptrs_from_clause( for from_item in ast_nav::iter_from_clause(from_clause) { if let Some(alias) = from_item.alias() - && alias.column_list().is_some() + && alias.columns().is_some() { results.push(SyntaxNodePtr::new(alias.syntax())); continue; diff --git a/crates/squawk_parser/src/generated/syntax_kind.rs b/crates/squawk_parser/src/generated/syntax_kind.rs index 0923e893..67a199e4 100644 --- a/crates/squawk_parser/src/generated/syntax_kind.rs +++ b/crates/squawk_parser/src/generated/syntax_kind.rs @@ -591,8 +591,6 @@ pub enum SyntaxKind { AGGREGATE, AGGREGATE_NAME, AGGREGATE_RENAME_TO, - ALIAS_COLUMN, - ALIAS_COLUMN_LIST, ALL, ALL_FN, ALL_IN_TABLESPACE, @@ -724,6 +722,8 @@ pub enum SyntaxKind { COLON_COLON, COLON_EQ, COLUMN, + COLUMN_DEF, + COLUMN_DEF_LIST, COLUMN_LIST, COLUMN_NAME, COLUMN_NAME_REF, diff --git a/crates/squawk_parser/src/grammar.rs b/crates/squawk_parser/src/grammar.rs index 78da919c..29de16a8 100644 --- a/crates/squawk_parser/src/grammar.rs +++ b/crates/squawk_parser/src/grammar.rs @@ -3803,7 +3803,9 @@ fn opt_row_from_expr(p: &mut Parser<'_>) -> bool { } let m = p.start(); call_expr(p); - opt_from_alias(p); + if p.eat(AS_KW) && !opt_column_list_with(p, ColumnDefKind::ColumnDef) { + p.error("expected column definition list"); + } m.complete(p, ROWS_FROM_ARG); true } @@ -4275,11 +4277,12 @@ fn opt_sequence_options(p: &mut Parser<'_>) -> Option { #[derive(Clone, Copy, PartialEq)] enum ColumnDefKind { - Alias, + ColumnDef, ColumnTarget, CompositeFieldDef, ConstraintColumnRef, ForeignKeyColumnRef, + FromAliasColumn, Name, NameRef, } @@ -4298,6 +4301,7 @@ fn opt_column_list_with(p: &mut Parser<'_>, kind: ColumnDefKind) -> bool { } let m = p.start(); p.expect(L_PAREN); + let mut kind = kind; let mut seen_period = false; while !p.at(EOF) && !p.at(R_PAREN) { if p.at(COMMA) { @@ -4311,7 +4315,7 @@ fn opt_column_list_with(p: &mut Parser<'_>, kind: ColumnDefKind) -> bool { p.error("PERIOD must be the last column in the list"); } seen_period |= kind == ColumnDefKind::ForeignKeyColumnRef && at_period_column(p); - column(p, kind); + kind = column(p, kind); if p.at(COMMA) && p.nth_at(1, R_PAREN) { p.err_and_bump("unexpected trailing comma"); } @@ -4326,28 +4330,41 @@ fn opt_column_list_with(p: &mut Parser<'_>, kind: ColumnDefKind) -> bool { opt_without_overlaps(p, kind); p.expect(R_PAREN); let list_kind = match kind { - ColumnDefKind::Alias => ALIAS_COLUMN_LIST, + ColumnDefKind::ColumnDef => COLUMN_DEF_LIST, ColumnDefKind::ColumnTarget => COLUMN_TARGET_LIST, ColumnDefKind::CompositeFieldDef => COMPOSITE_FIELD_LIST, ColumnDefKind::ConstraintColumnRef => CONSTRAINT_COLUMN_REF_LIST, ColumnDefKind::ForeignKeyColumnRef => FOREIGN_KEY_COLUMN_LIST, - ColumnDefKind::Name => COLUMN_LIST, + ColumnDefKind::FromAliasColumn | ColumnDefKind::Name => COLUMN_LIST, ColumnDefKind::NameRef => COLUMN_REF_LIST, }; m.complete(p, list_kind); return true; } -fn column(p: &mut Parser<'_>, kind: ColumnDefKind) { +fn column(p: &mut Parser<'_>, kind: ColumnDefKind) -> ColumnDefKind { assert!(p.at_ts(COLUMN_FIRST)); match kind { - ColumnDefKind::Alias => { + ColumnDefKind::FromAliasColumn => { let m = p.start(); column_name(p); if !p.at(COMMA) && !p.at(R_PAREN) && opt_type_name(p) { opt_collate(p); + m.complete(p, COLUMN_DEF); + return ColumnDefKind::ColumnDef; } - m.complete(p, ALIAS_COLUMN); + m.abandon(p); + return ColumnDefKind::Name; + } + ColumnDefKind::ColumnDef => { + let m = p.start(); + column_name(p); + if p.at(COMMA) || p.at(R_PAREN) || !opt_type_name(p) { + p.error("expected a type"); + } else { + opt_collate(p); + } + m.complete(p, COLUMN_DEF); } ColumnDefKind::CompositeFieldDef => { let m = p.start(); @@ -4392,6 +4409,7 @@ fn column(p: &mut Parser<'_>, kind: ColumnDefKind) { } } } + kind } fn at_period_column(p: &Parser<'_>) -> bool { @@ -5344,7 +5362,6 @@ fn like_clause(p: &mut Parser<'_>) -> CompletedMarker { // [ AS ] alias ( column_definition [, ...] ) // AS ( column_definition [, ...] ) fn opt_from_alias(p: &mut Parser<'_>) -> Option { - // TODO: we should split this into opt_col_def and opt_col_alias if !(p.at(AS_KW) || p.at_ts(NAME_FIRST) || p.at(L_PAREN)) { return None; } @@ -5354,10 +5371,8 @@ fn opt_from_alias(p: &mut Parser<'_>) -> Option { if p.at_ts(NAME_FIRST) { table_alias(p); } - if p.at(L_PAREN) { - if !opt_column_list_with(p, ColumnDefKind::Alias) { - p.error("expected column list"); - } + if p.at(L_PAREN) && !opt_column_list_with(p, ColumnDefKind::FromAliasColumn) { + p.error("expected column list"); } Some(m.complete(p, FROM_ALIAS)) } diff --git a/crates/squawk_parser/tests/data/err/select.sql b/crates/squawk_parser/tests/data/err/select.sql index 42032e00..c88e8841 100644 --- a/crates/squawk_parser/tests/data/err/select.sql +++ b/crates/squawk_parser/tests/data/err/select.sql @@ -147,5 +147,12 @@ select 1 union with x as (select 2) select * from x; select f(1, all 2); select f(1, distinct 2); +-- only column def list list allowed, not alias +select * from rows from (f() t); +select * from rows from (f() as t(a int)); + +-- column def columns a type +select * from rows from (f() as (a)); + -- trailing comma at EOF select 1, diff --git a/crates/squawk_parser/tests/snapshots/tests__misc_ok.snap b/crates/squawk_parser/tests/snapshots/tests__misc_ok.snap index 4bd4d9f6..7b77552a 100644 --- a/crates/squawk_parser/tests/snapshots/tests__misc_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__misc_ok.snap @@ -760,9 +760,9 @@ SOURCE_FILE WHITESPACE " " TABLE_ALIAS IDENT "x" - ALIAS_COLUMN_LIST + COLUMN_DEF_LIST L_PAREN "(" - ALIAS_COLUMN + COLUMN_DEF COLUMN_NAME IDENT "\"index\"" WHITESPACE " " @@ -772,7 +772,7 @@ SOURCE_FILE INT_KW "int" COMMA "," WHITESPACE " " - ALIAS_COLUMN + COLUMN_DEF COLUMN_NAME IDENT "\"document\"" WHITESPACE " " @@ -782,7 +782,7 @@ SOURCE_FILE IDENT "jsonb" COMMA "," WHITESPACE " " - ALIAS_COLUMN + COLUMN_DEF COLUMN_NAME IDENT "relevance_score" WHITESPACE " " diff --git a/crates/squawk_parser/tests/snapshots/tests__select_err.snap b/crates/squawk_parser/tests/snapshots/tests__select_err.snap index ab346b80..1ac2d4bb 100644 --- a/crates/squawk_parser/tests/snapshots/tests__select_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__select_err.snap @@ -84,11 +84,10 @@ SOURCE_FILE WHITESPACE " " TABLE_ALIAS IDENT "u" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "a" + COLUMN_NAME + IDENT "a" ERROR COMMA "," R_PAREN ")" @@ -1606,6 +1605,121 @@ SOURCE_FILE R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" + COMMENT "-- only column def list list allowed, not alias" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + ROWS_FROM_ITEM + ROWS_KW "rows" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + L_PAREN "(" + ROWS_FROM_ARG + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + ROWS_FROM_ARG + NAME_REF + IDENT "t" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + ROWS_FROM_ITEM + ROWS_KW "rows" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + L_PAREN "(" + ROWS_FROM_ARG + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + ROWS_FROM_ARG + CALL_EXPR + NAME_REF + IDENT "t" + ARG_LIST + L_PAREN "(" + ARG + NAME_REF + IDENT "a" + WHITESPACE " " + ARG + NAME_REF + INT_KW "int" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- column def columns a type" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + ROWS_FROM_ITEM + ROWS_KW "rows" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + L_PAREN "(" + ROWS_FROM_ARG + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + COLUMN_DEF_LIST + L_PAREN "(" + COLUMN_DEF + COLUMN_NAME + IDENT "a" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" COMMENT "-- trailing comma at EOF" WHITESPACE "\n" SELECT @@ -1824,7 +1938,31 @@ error[syntax-error]: ALL or DISTINCT is only allowed before the first argument ╭▸ 148 │ select f(1, distinct 2); ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +151 │ select * from rows from (f() t); + ╰╴ ━ +error[syntax-error]: expected call expression + ╭▸ +151 │ select * from rows from (f() t); + ╰╴ ━ +error[syntax-error]: expected column definition list + ╭▸ +152 │ select * from rows from (f() as t(a int)); + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +152 │ select * from rows from (f() as t(a int)); + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +152 │ select * from rows from (f() as t(a int)); + ╰╴ ━ +error[syntax-error]: expected a type + ╭▸ +155 │ select * from rows from (f() as (a)); + ╰╴ ━ error[syntax-error]: unexpected trailing comma ╭▸ -151 │ select 1, +158 │ select 1, ╰╴ ━ diff --git a/crates/squawk_parser/tests/snapshots/tests__select_funcs_ok.snap b/crates/squawk_parser/tests/snapshots/tests__select_funcs_ok.snap index f9d09d09..5345cf05 100644 --- a/crates/squawk_parser/tests/snapshots/tests__select_funcs_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__select_funcs_ok.snap @@ -3871,11 +3871,10 @@ SOURCE_FILE WHITESPACE " " TABLE_ALIAS IDENT "s" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "i" + COLUMN_NAME + IDENT "i" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" diff --git a/crates/squawk_parser/tests/snapshots/tests__select_ok.snap b/crates/squawk_parser/tests/snapshots/tests__select_ok.snap index a8499d05..6b9b963d 100644 --- a/crates/squawk_parser/tests/snapshots/tests__select_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__select_ok.snap @@ -183,21 +183,18 @@ SOURCE_FILE WHITESPACE " " TABLE_ALIAS IDENT "t" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "a" + COLUMN_NAME + IDENT "a" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "b" + COLUMN_NAME + IDENT "b" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "c" + COLUMN_NAME + IDENT "c" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" @@ -269,16 +266,14 @@ SOURCE_FILE WHITESPACE " " TABLE_ALIAS TARGET_KW "target" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - TARGET_KW "target" + COLUMN_NAME + TARGET_KW "target" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - FUNCTION_KW "function" + COLUMN_NAME + FUNCTION_KW "function" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" @@ -307,16 +302,14 @@ SOURCE_FILE WHITESPACE " " TABLE_ALIAS IDENT "t" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "col1" + COLUMN_NAME + IDENT "col1" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "col2" + COLUMN_NAME + IDENT "col2" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" @@ -359,16 +352,14 @@ SOURCE_FILE FROM_ALIAS TABLE_ALIAS TARGET_KW "target" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - TARGET_KW "target" + COLUMN_NAME + TARGET_KW "target" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - FUNCTION_KW "function" + COLUMN_NAME + FUNCTION_KW "function" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" @@ -1824,21 +1815,18 @@ SOURCE_FILE WHITESPACE " " TABLE_ALIAS IDENT "r" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "a" + COLUMN_NAME + IDENT "a" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "b" + COLUMN_NAME + IDENT "b" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "c" + COLUMN_NAME + IDENT "c" R_PAREN ")" WHITESPACE " " TABLESAMPLE_CLAUSE @@ -1932,21 +1920,18 @@ SOURCE_FILE WHITESPACE " " TABLE_ALIAS IDENT "t" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "a" + COLUMN_NAME + IDENT "a" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "b" + COLUMN_NAME + IDENT "b" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "c" + COLUMN_NAME + IDENT "c" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" @@ -1995,16 +1980,14 @@ SOURCE_FILE WHITESPACE " " TABLE_ALIAS IDENT "t" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "a" + COLUMN_NAME + IDENT "a" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "b" + COLUMN_NAME + IDENT "b" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" @@ -2049,16 +2032,14 @@ SOURCE_FILE FROM_ALIAS TABLE_ALIAS IDENT "t" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "a" + COLUMN_NAME + IDENT "a" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "b" + COLUMN_NAME + IDENT "b" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" @@ -2162,16 +2143,14 @@ SOURCE_FILE WHITESPACE " " TABLE_ALIAS IDENT "t" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "a" + COLUMN_NAME + IDENT "a" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "b" + COLUMN_NAME + IDENT "b" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" @@ -2205,16 +2184,14 @@ SOURCE_FILE FROM_ALIAS TABLE_ALIAS IDENT "t" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "a" + COLUMN_NAME + IDENT "a" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "b" + COLUMN_NAME + IDENT "b" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" @@ -2245,9 +2222,9 @@ SOURCE_FILE FROM_ALIAS TABLE_ALIAS IDENT "t" - ALIAS_COLUMN_LIST + COLUMN_DEF_LIST L_PAREN "(" - ALIAS_COLUMN + COLUMN_DEF COLUMN_NAME IDENT "a" WHITESPACE " " @@ -2257,7 +2234,7 @@ SOURCE_FILE INT_KW "int" COMMA "," WHITESPACE " " - ALIAS_COLUMN + COLUMN_DEF COLUMN_NAME IDENT "b" WHITESPACE " " @@ -2292,9 +2269,9 @@ SOURCE_FILE WHITESPACE " " TABLE_ALIAS IDENT "t" - ALIAS_COLUMN_LIST + COLUMN_DEF_LIST L_PAREN "(" - ALIAS_COLUMN + COLUMN_DEF COLUMN_NAME IDENT "a" WHITESPACE " " @@ -2304,7 +2281,7 @@ SOURCE_FILE INT_KW "int" COMMA "," WHITESPACE " " - ALIAS_COLUMN + COLUMN_DEF COLUMN_NAME IDENT "b" WHITESPACE " " @@ -2337,9 +2314,9 @@ SOURCE_FILE FROM_ALIAS AS_KW "as" WHITESPACE " " - ALIAS_COLUMN_LIST + COLUMN_DEF_LIST L_PAREN "(" - ALIAS_COLUMN + COLUMN_DEF COLUMN_NAME IDENT "a" WHITESPACE " " @@ -2349,7 +2326,7 @@ SOURCE_FILE INT_KW "int" COMMA "," WHITESPACE " " - ALIAS_COLUMN + COLUMN_DEF COLUMN_NAME IDENT "b" WHITESPACE " " @@ -2384,9 +2361,9 @@ SOURCE_FILE FROM_ALIAS AS_KW "as" WHITESPACE " " - ALIAS_COLUMN_LIST + COLUMN_DEF_LIST L_PAREN "(" - ALIAS_COLUMN + COLUMN_DEF COLUMN_NAME IDENT "a" WHITESPACE " " @@ -2396,7 +2373,7 @@ SOURCE_FILE INT_KW "int" COMMA "," WHITESPACE " " - ALIAS_COLUMN + COLUMN_DEF COLUMN_NAME IDENT "b" WHITESPACE " " @@ -2445,9 +2422,9 @@ SOURCE_FILE FROM_ALIAS AS_KW "as" WHITESPACE " " - ALIAS_COLUMN_LIST + COLUMN_DEF_LIST L_PAREN "(" - ALIAS_COLUMN + COLUMN_DEF COLUMN_NAME IDENT "a" WHITESPACE " " @@ -2457,7 +2434,7 @@ SOURCE_FILE INT_KW "int" COMMA "," WHITESPACE " " - ALIAS_COLUMN + COLUMN_DEF COLUMN_NAME IDENT "b" WHITESPACE " " @@ -2601,21 +2578,18 @@ SOURCE_FILE WHITESPACE " " TABLE_ALIAS IDENT "z" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "a" + COLUMN_NAME + IDENT "a" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "b" + COLUMN_NAME + IDENT "b" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "c" + COLUMN_NAME + IDENT "c" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" @@ -2643,21 +2617,18 @@ SOURCE_FILE WHITESPACE " " TABLE_ALIAS IDENT "z" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "a" + COLUMN_NAME + IDENT "a" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "b" + COLUMN_NAME + IDENT "b" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "c" + COLUMN_NAME + IDENT "c" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" @@ -2681,21 +2652,18 @@ SOURCE_FILE FROM_ALIAS TABLE_ALIAS IDENT "z" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "a" + COLUMN_NAME + IDENT "a" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "b" + COLUMN_NAME + IDENT "b" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "c" + COLUMN_NAME + IDENT "c" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" @@ -2807,21 +2775,18 @@ SOURCE_FILE WHITESPACE " " TABLE_ALIAS IDENT "b" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "x" + COLUMN_NAME + IDENT "x" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "y" + COLUMN_NAME + IDENT "y" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "z" + COLUMN_NAME + IDENT "z" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" @@ -2904,21 +2869,18 @@ SOURCE_FILE WHITESPACE " " TABLE_ALIAS IDENT "t" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "a" + COLUMN_NAME + IDENT "a" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "b" + COLUMN_NAME + IDENT "b" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "c" + COLUMN_NAME + IDENT "c" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" @@ -2951,21 +2913,18 @@ SOURCE_FILE WHITESPACE " " TABLE_ALIAS IDENT "t" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "a" + COLUMN_NAME + IDENT "a" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "b" + COLUMN_NAME + IDENT "b" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "c" + COLUMN_NAME + IDENT "c" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" @@ -3100,21 +3059,18 @@ SOURCE_FILE WHITESPACE " " TABLE_ALIAS IDENT "t" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "a" + COLUMN_NAME + IDENT "a" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "b" + COLUMN_NAME + IDENT "b" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "c" + COLUMN_NAME + IDENT "c" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" @@ -3142,21 +3098,18 @@ SOURCE_FILE WHITESPACE " " TABLE_ALIAS IDENT "t" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "a" + COLUMN_NAME + IDENT "a" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "b" + COLUMN_NAME + IDENT "b" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "c" + COLUMN_NAME + IDENT "c" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" @@ -3182,21 +3135,18 @@ SOURCE_FILE FROM_ALIAS TABLE_ALIAS IDENT "t" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "a" + COLUMN_NAME + IDENT "a" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "b" + COLUMN_NAME + IDENT "b" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "c" + COLUMN_NAME + IDENT "c" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" @@ -3254,9 +3204,9 @@ SOURCE_FILE WHITESPACE " " TABLE_ALIAS IDENT "t" - ALIAS_COLUMN_LIST + COLUMN_DEF_LIST L_PAREN "(" - ALIAS_COLUMN + COLUMN_DEF COLUMN_NAME IDENT "a" WHITESPACE " " @@ -3266,7 +3216,7 @@ SOURCE_FILE INT_KW "int" COMMA "," WHITESPACE " " - ALIAS_COLUMN + COLUMN_DEF COLUMN_NAME IDENT "b" WHITESPACE " " @@ -3299,9 +3249,9 @@ SOURCE_FILE FROM_ALIAS TABLE_ALIAS IDENT "t" - ALIAS_COLUMN_LIST + COLUMN_DEF_LIST L_PAREN "(" - ALIAS_COLUMN + COLUMN_DEF COLUMN_NAME IDENT "a" WHITESPACE " " @@ -3311,7 +3261,7 @@ SOURCE_FILE INT_KW "int" COMMA "," WHITESPACE " " - ALIAS_COLUMN + COLUMN_DEF COLUMN_NAME IDENT "b" WHITESPACE " " @@ -3362,9 +3312,9 @@ SOURCE_FILE FROM_ALIAS AS_KW "as" WHITESPACE " " - ALIAS_COLUMN_LIST + COLUMN_DEF_LIST L_PAREN "(" - ALIAS_COLUMN + COLUMN_DEF COLUMN_NAME IDENT "x" WHITESPACE " " @@ -3374,7 +3324,7 @@ SOURCE_FILE INT_KW "int" COMMA "," WHITESPACE " " - ALIAS_COLUMN + COLUMN_DEF COLUMN_NAME IDENT "y" WHITESPACE " " @@ -3384,7 +3334,7 @@ SOURCE_FILE TEXT_KW "text" COMMA "," WHITESPACE " " - ALIAS_COLUMN + COLUMN_DEF COLUMN_NAME IDENT "z" WHITESPACE " " @@ -3553,21 +3503,18 @@ SOURCE_FILE WHITESPACE " " TABLE_ALIAS IDENT "t" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "a" + COLUMN_NAME + IDENT "a" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "b" + COLUMN_NAME + IDENT "b" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "c" + COLUMN_NAME + IDENT "c" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" @@ -3599,21 +3546,18 @@ SOURCE_FILE FROM_ALIAS TABLE_ALIAS IDENT "t" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "a" + COLUMN_NAME + IDENT "a" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "b" + COLUMN_NAME + IDENT "b" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "c" + COLUMN_NAME + IDENT "c" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" @@ -3641,20 +3585,19 @@ SOURCE_FILE L_PAREN "(" R_PAREN ")" WHITESPACE " " - FROM_ALIAS - AS_KW "as" - WHITESPACE " " - ALIAS_COLUMN_LIST - L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "x" - WHITESPACE " " - PATH_TYPE - PATH_REF - PATH_SEGMENT_REF - INT_KW "int" - R_PAREN ")" + AS_KW "as" + WHITESPACE " " + COLUMN_DEF_LIST + L_PAREN "(" + COLUMN_DEF + COLUMN_NAME + IDENT "x" + WHITESPACE " " + PATH_TYPE + PATH_REF + PATH_SEGMENT_REF + INT_KW "int" + R_PAREN ")" COMMA "," WHITESPACE " " ROWS_FROM_ARG @@ -3665,20 +3608,19 @@ SOURCE_FILE L_PAREN "(" R_PAREN ")" WHITESPACE " " - FROM_ALIAS - AS_KW "as" - WHITESPACE " " - ALIAS_COLUMN_LIST - L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "y" - WHITESPACE " " - PATH_TYPE - PATH_REF - PATH_SEGMENT_REF - INT_KW "int" - R_PAREN ")" + AS_KW "as" + WHITESPACE " " + COLUMN_DEF_LIST + L_PAREN "(" + COLUMN_DEF + COLUMN_NAME + IDENT "y" + WHITESPACE " " + PATH_TYPE + PATH_REF + PATH_SEGMENT_REF + INT_KW "int" + R_PAREN ")" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" @@ -3706,20 +3648,19 @@ SOURCE_FILE L_PAREN "(" R_PAREN ")" WHITESPACE " " - FROM_ALIAS - AS_KW "as" - WHITESPACE " " - ALIAS_COLUMN_LIST - L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "x" - WHITESPACE " " - PATH_TYPE - PATH_REF - PATH_SEGMENT_REF - INT_KW "int" - R_PAREN ")" + AS_KW "as" + WHITESPACE " " + COLUMN_DEF_LIST + L_PAREN "(" + COLUMN_DEF + COLUMN_NAME + IDENT "x" + WHITESPACE " " + PATH_TYPE + PATH_REF + PATH_SEGMENT_REF + INT_KW "int" + R_PAREN ")" R_PAREN ")" WHITESPACE " " FROM_ALIAS @@ -3727,11 +3668,10 @@ SOURCE_FILE WHITESPACE " " TABLE_ALIAS IDENT "t" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "a" + COLUMN_NAME + IDENT "a" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" @@ -3759,20 +3699,19 @@ SOURCE_FILE L_PAREN "(" R_PAREN ")" WHITESPACE " " - FROM_ALIAS - AS_KW "as" - WHITESPACE " " - ALIAS_COLUMN_LIST - L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "x" - WHITESPACE " " - PATH_TYPE - PATH_REF - PATH_SEGMENT_REF - INT_KW "int" - R_PAREN ")" + AS_KW "as" + WHITESPACE " " + COLUMN_DEF_LIST + L_PAREN "(" + COLUMN_DEF + COLUMN_NAME + IDENT "x" + WHITESPACE " " + PATH_TYPE + PATH_REF + PATH_SEGMENT_REF + INT_KW "int" + R_PAREN ")" R_PAREN ")" WHITESPACE " " WITH_ORDINALITY @@ -3785,16 +3724,14 @@ SOURCE_FILE WHITESPACE " " TABLE_ALIAS IDENT "t" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "a" + COLUMN_NAME + IDENT "a" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "n" + COLUMN_NAME + IDENT "n" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" @@ -5270,15 +5207,13 @@ SOURCE_FILE FROM_ALIAS TABLE_ALIAS IDENT "x" - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "x0" + COLUMN_NAME + IDENT "x0" COMMA "," - ALIAS_COLUMN - COLUMN_NAME - IDENT "x1" + COLUMN_NAME + IDENT "x1" R_PAREN ")" WHITESPACE " " JOIN diff --git a/crates/squawk_parser/tests/snapshots/tests__values_ok.snap b/crates/squawk_parser/tests/snapshots/tests__values_ok.snap index e8892db7..a12e3381 100644 --- a/crates/squawk_parser/tests/snapshots/tests__values_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__values_ok.snap @@ -245,16 +245,14 @@ SOURCE_FILE TABLE_ALIAS IDENT "t" WHITESPACE " " - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "studio" + COLUMN_NAME + IDENT "studio" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "kind" + COLUMN_NAME + IDENT "kind" R_PAREN ")" WHITESPACE "\n " WHERE_CLAUSE @@ -379,21 +377,18 @@ SOURCE_FILE TABLE_ALIAS IDENT "v" WHITESPACE " " - ALIAS_COLUMN_LIST + COLUMN_LIST L_PAREN "(" - ALIAS_COLUMN - COLUMN_NAME - IDENT "depno" + COLUMN_NAME + IDENT "depno" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - TARGET_KW "target" + COLUMN_NAME + TARGET_KW "target" COMMA "," WHITESPACE " " - ALIAS_COLUMN - COLUMN_NAME - IDENT "increase" + COLUMN_NAME + IDENT "increase" R_PAREN ")" WHITESPACE "\n" WHERE_CLAUSE diff --git a/crates/squawk_syntax/src/ast/generated/nodes.rs b/crates/squawk_syntax/src/ast/generated/nodes.rs index f136e44f..958afa2c 100644 --- a/crates/squawk_syntax/src/ast/generated/nodes.rs +++ b/crates/squawk_syntax/src/ast/generated/nodes.rs @@ -537,44 +537,6 @@ impl AggregateRenameTo { } } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct AliasColumn { - pub(crate) syntax: SyntaxNode, -} -impl AliasColumn { - #[inline] - pub fn collate(&self) -> Option { - support::child(&self.syntax) - } - #[inline] - pub fn name(&self) -> Option { - support::child(&self.syntax) - } - #[inline] - pub fn ty(&self) -> Option { - support::child(&self.syntax) - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct AliasColumnList { - pub(crate) syntax: SyntaxNode, -} -impl AliasColumnList { - #[inline] - pub fn alias_columns(&self) -> AstChildren { - support::children(&self.syntax) - } - #[inline] - pub fn l_paren_token(&self) -> Option { - support::token(&self.syntax, SyntaxKind::L_PAREN) - } - #[inline] - pub fn r_paren_token(&self) -> Option { - support::token(&self.syntax, SyntaxKind::R_PAREN) - } -} - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct All { pub(crate) syntax: SyntaxNode, @@ -3835,6 +3797,44 @@ impl Column { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct ColumnDef { + pub(crate) syntax: SyntaxNode, +} +impl ColumnDef { + #[inline] + pub fn collate(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn name(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn ty(&self) -> Option { + support::child(&self.syntax) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct ColumnDefList { + pub(crate) syntax: SyntaxNode, +} +impl ColumnDefList { + #[inline] + pub fn column_defs(&self) -> AstChildren { + support::children(&self.syntax) + } + #[inline] + pub fn l_paren_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::L_PAREN) + } + #[inline] + pub fn r_paren_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::R_PAREN) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ColumnList { pub(crate) syntax: SyntaxNode, @@ -11716,7 +11716,7 @@ pub struct FromAlias { } impl FromAlias { #[inline] - pub fn column_list(&self) -> Option { + pub fn columns(&self) -> Option { support::child(&self.syntax) } #[inline] @@ -22285,9 +22285,13 @@ impl RowsFromArg { support::child(&self.syntax) } #[inline] - pub fn column_def_list(&self) -> Option { + pub fn column_def_list(&self) -> Option { support::child(&self.syntax) } + #[inline] + pub fn as_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::AS_KW) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -28536,6 +28540,12 @@ pub enum FrameUnits { FrameRows(FrameRows), } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum FromAliasColumns { + ColumnDefList(ColumnDefList), + ColumnList(ColumnList), +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum FromItem { ExprFromItem(ExprFromItem), @@ -30041,42 +30051,6 @@ impl AstNode for AggregateRenameTo { &self.syntax } } -impl AstNode for AliasColumn { - #[inline] - fn can_cast(kind: SyntaxKind) -> bool { - kind == SyntaxKind::ALIAS_COLUMN - } - #[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 AliasColumnList { - #[inline] - fn can_cast(kind: SyntaxKind) -> bool { - kind == SyntaxKind::ALIAS_COLUMN_LIST - } - #[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 All { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -32435,6 +32409,42 @@ impl AstNode for Column { &self.syntax } } +impl AstNode for ColumnDef { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::COLUMN_DEF + } + #[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 ColumnDefList { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::COLUMN_DEF_LIST + } + #[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 ColumnList { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -61757,6 +61767,44 @@ impl From for FrameUnits { FrameUnits::FrameRows(node) } } +impl AstNode for FromAliasColumns { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + matches!(kind, SyntaxKind::COLUMN_DEF_LIST | SyntaxKind::COLUMN_LIST) + } + #[inline] + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + SyntaxKind::COLUMN_DEF_LIST => { + FromAliasColumns::ColumnDefList(ColumnDefList { syntax }) + } + SyntaxKind::COLUMN_LIST => FromAliasColumns::ColumnList(ColumnList { syntax }), + _ => { + return None; + } + }; + Some(res) + } + #[inline] + fn syntax(&self) -> &SyntaxNode { + match self { + FromAliasColumns::ColumnDefList(it) => &it.syntax, + FromAliasColumns::ColumnList(it) => &it.syntax, + } + } +} +impl From for FromAliasColumns { + #[inline] + fn from(node: ColumnDefList) -> FromAliasColumns { + FromAliasColumns::ColumnDefList(node) + } +} +impl From for FromAliasColumns { + #[inline] + fn from(node: ColumnList) -> FromAliasColumns { + FromAliasColumns::ColumnList(node) + } +} impl AstNode for FromItem { #[inline] fn can_cast(kind: SyntaxKind) -> bool { diff --git a/crates/squawk_syntax/src/ast/node_ext.rs b/crates/squawk_syntax/src/ast/node_ext.rs index a5441b16..fc4804f2 100644 --- a/crates/squawk_syntax/src/ast/node_ext.rs +++ b/crates/squawk_syntax/src/ast/node_ext.rs @@ -26,6 +26,7 @@ use std::borrow::Cow; +use either::Either; #[cfg(test)] use insta::assert_snapshot; use rowan::{GreenNodeData, GreenTokenData, NodeOrToken}; @@ -155,6 +156,21 @@ impl ast::FromItem { } } +impl ast::ColumnDefList { + pub fn column_names(self) -> impl Iterator { + self.column_defs().filter_map(|column| column.name()) + } +} + +impl ast::FromAliasColumns { + pub fn column_names(self) -> impl Iterator { + match self { + ast::FromAliasColumns::ColumnList(it) => Either::Left(it.column_names()), + ast::FromAliasColumns::ColumnDefList(it) => Either::Right(it.column_names()), + } + } +} + impl ast::RelationFromItem { pub fn path_ref(&self) -> Option { self.relation_name_ref()?.path_ref() diff --git a/crates/squawk_syntax/src/ast/nodes.rs b/crates/squawk_syntax/src/ast/nodes.rs index ee3134ac..135611ac 100644 --- a/crates/squawk_syntax/src/ast/nodes.rs +++ b/crates/squawk_syntax/src/ast/nodes.rs @@ -4,12 +4,6 @@ use crate::{ ast::{self, AstNode, support}, }; -impl ast::AliasColumnList { - pub fn column_names(self) -> impl Iterator { - self.alias_columns().filter_map(|column| column.name()) - } -} - // TODO: Initial attempt to try and unify the CreateTable and // CreateForeignTable. Not sure this is the right approach, we may want to be // more general, like TableSource, which can be a View, CTE, Table, diff --git a/crates/squawk_syntax/src/postgresql.ungram b/crates/squawk_syntax/src/postgresql.ungram index d7069032..cdf99b24 100644 --- a/crates/squawk_syntax/src/postgresql.ungram +++ b/crates/squawk_syntax/src/postgresql.ungram @@ -1492,7 +1492,11 @@ TableAlias = '#name'? FromAlias = - 'as'? name:TableAlias column_list:AliasColumnList? + 'as'? name:TableAlias? columns:FromAliasColumns? + +FromAliasColumns = + ColumnList +| ColumnDefList OptionalAsAlias = 'as'? name:TableAlias @@ -1575,11 +1579,11 @@ OptionCycle = ColumnList = '(' (ColumnName (',' ColumnName)*) ')' -AliasColumnList = - '(' (AliasColumn (',' AliasColumn)*) ')' +ColumnDefList = + '(' (ColumnDef (',' ColumnDef)*) ')' -AliasColumn = - name:ColumnName Type? Collate? +ColumnDef = + name:ColumnName Type Collate? ColumnRefList = '(' (ColumnNameRef (',' ColumnNameRef)*) ')' @@ -2914,7 +2918,7 @@ RowsFromItem = 'lateral'? 'rows' 'from' '(' (RowsFromArg (',' RowsFromArg)*) ')' WithOrdinality? alias:FromAlias? RowsFromArg = - CallExpr column_def_list:FromAlias? + CallExpr ('as' ColumnDefList)? FromClause = 'from' diff --git a/crates/squawk_syntax/src/snapshots/squawk_syntax__test__empty_column_list_validation.snap b/crates/squawk_syntax/src/snapshots/squawk_syntax__test__empty_column_list_validation.snap index 523127e3..338b8066 100644 --- a/crates/squawk_syntax/src/snapshots/squawk_syntax__test__empty_column_list_validation.snap +++ b/crates/squawk_syntax/src/snapshots/squawk_syntax__test__empty_column_list_validation.snap @@ -157,11 +157,10 @@ SOURCE_FILE@0..438 TABLE_ALIAS@236..237 IDENT@236..237 "x" WHITESPACE@237..238 " " - ALIAS_COLUMN_LIST@238..241 + COLUMN_LIST@238..241 L_PAREN@238..239 "(" - ALIAS_COLUMN@239..240 - COLUMN_NAME@239..240 - IDENT@239..240 "a" + COLUMN_NAME@239..240 + IDENT@239..240 "a" R_PAREN@240..241 ")" SEMICOLON@241..242 ";" WHITESPACE@242..244 "\n\n" @@ -284,7 +283,7 @@ SOURCE_FILE@0..438 TABLE_ALIAS@432..433 IDENT@432..433 "x" WHITESPACE@433..434 " " - ALIAS_COLUMN_LIST@434..436 + COLUMN_LIST@434..436 L_PAREN@434..435 "(" R_PAREN@435..436 ")" SEMICOLON@436..437 ";" diff --git a/crates/squawk_syntax/src/validation.rs b/crates/squawk_syntax/src/validation.rs index ca8aed0a..8a8255a4 100644 --- a/crates/squawk_syntax/src/validation.rs +++ b/crates/squawk_syntax/src/validation.rs @@ -21,7 +21,7 @@ pub(crate) fn validate(root: &SyntaxNode, errors: &mut Vec) { ast::CreateTable(it) => validate_create_table(it, errors), ast::CreateViewLike(it) => validate_non_empty_column_list(it.column_list(), errors), ast::CustomOp(it) => validate_custom_op_length(it, errors), - ast::FromAlias(it) => validate_non_empty_column_list(it.column_list(), errors), + ast::FromAlias(it) => validate_non_empty_column_list(it.columns(), errors), ast::WithTable(it) => validate_non_empty_column_list(it.column_list(), errors), ast::PrefixExpr(it) => validate_prefix_expr(it, errors), ast::ArrayExpr(it) => validate_array_expr(it, errors),