From cdeb041abf8ead85c3031f92f8bacaf4a9ac3edb Mon Sep 17 00:00:00 2001 From: Steve Dignam Date: Sun, 25 May 2025 18:34:37 -0400 Subject: [PATCH] parser: cleanup ungrammar --- .../src/generated/syntax_kind.rs | 8 + .../squawk_syntax/src/ast/generated/nodes.rs | 337 +++++++++++++++++- crates/squawk_syntax/src/postgresql.ungram | 125 +++---- 3 files changed, 402 insertions(+), 68 deletions(-) diff --git a/crates/squawk_parser/src/generated/syntax_kind.rs b/crates/squawk_parser/src/generated/syntax_kind.rs index fb9223e6..fb0ce1e3 100644 --- a/crates/squawk_parser/src/generated/syntax_kind.rs +++ b/crates/squawk_parser/src/generated/syntax_kind.rs @@ -608,6 +608,7 @@ pub enum SyntaxKind { BIT_TYPE, CALL, CALL_EXPR, + CASCADE, CASE_EXPR, CAST_EXPR, CHAR_TYPE, @@ -816,11 +817,14 @@ pub enum SyntaxKind { NOT_NULL_CONSTRAINT, NOT_OF, NOT_VALID, + NO_ACTION, NO_FORCE_RLS, NO_INHERIT, NULL_CONSTRAINT, OFFSET_CLAUSE, OF_TYPE, + ON_DELETE_ACTION, + ON_UPDATE_ACTION, OP, OPERATOR_CALL, ORDER_BY_CLAUSE, @@ -854,6 +858,7 @@ pub enum SyntaxKind { REASSIGN, REFERENCES_CONSTRAINT, REFRESH, + REF_ACTION, REINDEX, RELATION_NAME, RELEASE_SAVEPOINT, @@ -868,6 +873,7 @@ pub enum SyntaxKind { RESET_OPTIONS, RESET_STORAGE_PARAMS, RESTART, + RESTRICT, RETURN_FUNC_OPTION, RET_TYPE, REVOKE, @@ -887,12 +893,14 @@ pub enum SyntaxKind { SET_COMPRESSION, SET_CONSTRAINTS, SET_DEFAULT, + SET_DEFAULT_COLUMNS, SET_EXPRESSION, SET_FUNC_OPTION, SET_GENERATED, SET_GENERATED_OPTIONS, SET_LOGGED, SET_NOT_NULL, + SET_NULL_COLUMNS, SET_OPTIONS, SET_OPTIONS_LIST, SET_ROLE, diff --git a/crates/squawk_syntax/src/ast/generated/nodes.rs b/crates/squawk_syntax/src/ast/generated/nodes.rs index b77e8978..70266445 100644 --- a/crates/squawk_syntax/src/ast/generated/nodes.rs +++ b/crates/squawk_syntax/src/ast/generated/nodes.rs @@ -1266,13 +1266,17 @@ pub struct BinExpr { } impl BinExpr { #[inline] - pub fn expr(&self) -> Option { + pub fn lhs(&self) -> Option { support::child(&self.syntax) } #[inline] pub fn op(&self) -> Option { support::child(&self.syntax) } + #[inline] + pub fn rhs(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -1320,6 +1324,17 @@ impl CallExpr { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Cascade { + pub(crate) syntax: SyntaxNode, +} +impl Cascade { + #[inline] + pub fn cascade_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::CASCADE_KW) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct CaseExpr { pub(crate) syntax: SyntaxNode, @@ -4480,6 +4495,14 @@ impl ForeignKeyConstraint { support::child(&self.syntax) } #[inline] + pub fn on_delete_action(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn on_update_action(&self) -> Option { + support::child(&self.syntax) + } + #[inline] pub fn path(&self) -> Option { support::child(&self.syntax) } @@ -4705,7 +4728,11 @@ pub struct IndexExpr { } impl IndexExpr { #[inline] - pub fn expr(&self) -> Option { + pub fn base(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn index(&self) -> Option { support::child(&self.syntax) } #[inline] @@ -5382,6 +5409,21 @@ impl Neqb { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct NoAction { + pub(crate) syntax: SyntaxNode, +} +impl NoAction { + #[inline] + pub fn action_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::ACTION_KW) + } + #[inline] + pub fn no_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::NO_KW) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct NoForceRls { pub(crate) syntax: SyntaxNode, @@ -5593,6 +5635,44 @@ impl OffsetClause { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct OnDeleteAction { + pub(crate) syntax: SyntaxNode, +} +impl OnDeleteAction { + #[inline] + pub fn ref_action(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn delete_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::DELETE_KW) + } + #[inline] + pub fn on_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::ON_KW) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct OnUpdateAction { + pub(crate) syntax: SyntaxNode, +} +impl OnUpdateAction { + #[inline] + pub fn ref_action(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn on_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::ON_KW) + } + #[inline] + pub fn update_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::UPDATE_KW) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Op { pub(crate) syntax: SyntaxNode, @@ -6547,6 +6627,17 @@ impl Restart { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Restrict { + pub(crate) syntax: SyntaxNode, +} +impl Restrict { + #[inline] + pub fn restrict_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::RESTRICT_KW) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct RetType { pub(crate) syntax: SyntaxNode, @@ -6928,6 +7019,25 @@ impl SetDefault { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct SetDefaultColumns { + pub(crate) syntax: SyntaxNode, +} +impl SetDefaultColumns { + #[inline] + pub fn column_list(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn default_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::DEFAULT_KW) + } + #[inline] + pub fn set_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::SET_KW) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct SetExpression { pub(crate) syntax: SyntaxNode, @@ -7014,6 +7124,25 @@ impl SetNotNull { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct SetNullColumns { + pub(crate) syntax: SyntaxNode, +} +impl SetNullColumns { + #[inline] + pub fn column_list(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn null_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::NULL_KW) + } + #[inline] + pub fn set_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::SET_KW) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct SetOptions { pub(crate) syntax: SyntaxNode, @@ -8028,6 +8157,15 @@ pub enum ParamMode { ParamVariadic(ParamVariadic), } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum RefAction { + Cascade(Cascade), + NoAction(NoAction), + Restrict(Restrict), + SetDefaultColumns(SetDefaultColumns), + SetNullColumns(SetNullColumns), +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Stmt { AlterAggregate(AlterAggregate), @@ -9397,6 +9535,24 @@ impl AstNode for CallExpr { &self.syntax } } +impl AstNode for Cascade { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::CASCADE + } + #[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 CaseExpr { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -12943,6 +13099,24 @@ impl AstNode for Neqb { &self.syntax } } +impl AstNode for NoAction { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::NO_ACTION + } + #[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 NoForceRls { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -13177,6 +13351,42 @@ impl AstNode for OffsetClause { &self.syntax } } +impl AstNode for OnDeleteAction { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::ON_DELETE_ACTION + } + #[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 OnUpdateAction { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::ON_UPDATE_ACTION + } + #[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 Op { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -14005,6 +14215,24 @@ impl AstNode for Restart { &self.syntax } } +impl AstNode for Restrict { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::RESTRICT + } + #[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 RetType { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -14347,6 +14575,24 @@ impl AstNode for SetDefault { &self.syntax } } +impl AstNode for SetDefaultColumns { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::SET_DEFAULT_COLUMNS + } + #[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 SetExpression { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -14455,6 +14701,24 @@ impl AstNode for SetNotNull { &self.syntax } } +impl AstNode for SetNullColumns { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::SET_NULL_COLUMNS + } + #[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 SetOptions { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -16573,6 +16837,75 @@ impl From for ParamMode { ParamMode::ParamVariadic(node) } } +impl AstNode for RefAction { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + matches!( + kind, + SyntaxKind::CASCADE + | SyntaxKind::NO_ACTION + | SyntaxKind::RESTRICT + | SyntaxKind::SET_DEFAULT_COLUMNS + | SyntaxKind::SET_NULL_COLUMNS + ) + } + #[inline] + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + SyntaxKind::CASCADE => RefAction::Cascade(Cascade { syntax }), + SyntaxKind::NO_ACTION => RefAction::NoAction(NoAction { syntax }), + SyntaxKind::RESTRICT => RefAction::Restrict(Restrict { syntax }), + SyntaxKind::SET_DEFAULT_COLUMNS => { + RefAction::SetDefaultColumns(SetDefaultColumns { syntax }) + } + SyntaxKind::SET_NULL_COLUMNS => RefAction::SetNullColumns(SetNullColumns { syntax }), + _ => { + return None; + } + }; + Some(res) + } + #[inline] + fn syntax(&self) -> &SyntaxNode { + match self { + RefAction::Cascade(it) => &it.syntax, + RefAction::NoAction(it) => &it.syntax, + RefAction::Restrict(it) => &it.syntax, + RefAction::SetDefaultColumns(it) => &it.syntax, + RefAction::SetNullColumns(it) => &it.syntax, + } + } +} +impl From for RefAction { + #[inline] + fn from(node: Cascade) -> RefAction { + RefAction::Cascade(node) + } +} +impl From for RefAction { + #[inline] + fn from(node: NoAction) -> RefAction { + RefAction::NoAction(node) + } +} +impl From for RefAction { + #[inline] + fn from(node: Restrict) -> RefAction { + RefAction::Restrict(node) + } +} +impl From for RefAction { + #[inline] + fn from(node: SetDefaultColumns) -> RefAction { + RefAction::SetDefaultColumns(node) + } +} +impl From for RefAction { + #[inline] + fn from(node: SetNullColumns) -> RefAction { + RefAction::SetNullColumns(node) + } +} impl AstNode for Stmt { #[inline] fn can_cast(kind: SyntaxKind) -> bool { diff --git a/crates/squawk_syntax/src/postgresql.ungram b/crates/squawk_syntax/src/postgresql.ungram index afced3c0..55da8beb 100644 --- a/crates/squawk_syntax/src/postgresql.ungram +++ b/crates/squawk_syntax/src/postgresql.ungram @@ -87,7 +87,6 @@ Literal = | '@dollar_quoted_string' | '@esc_string' | '@positional_param' - // TODO: ) NamedArg = @@ -131,7 +130,6 @@ IsNotDistinctFrom = 'is' 'not' 'distinct' 'from' OperatorCall = - // TODO: 'operator' '(' (Path '.')? Op ')' ColonEq = @@ -156,7 +154,7 @@ Op = 'or' | Gteq | '<' | '>' | FatArrow | '=' | 'in' | Neqb | Lteq | '+' | 'overlaps' | 'like' | NotLike | NotIn | CustomOp | IsDistinctFrom | IsNotDistinctFrom | OperatorCall | 'is' | '^' | '%' | 'and' | '/' | Neq | 'collate' | '-' | ColonEq | ColonColon | 'value' | ':' | IsNot | SimilarTo | AtTimeZone BinExpr = - Expr Op Expr + lhs:Expr Op rhs:Expr CaseExpr = 'case' @@ -180,8 +178,7 @@ ArrayType = // int array[] // text[] // t[10][10] - // TODO: - Type NameRef 'array'? // '[' Expr? ']' ('[' Expr? ']')* + Type NameRef 'array'? '[' Expr? ']' PercentType = '%' 'type' @@ -236,14 +233,13 @@ Type = | IntervalType Role = - // TODO: more general than #ident? ('group'? '#ident') | 'current_role' | 'current_user' | 'session_user' CheckConstraint = ('constraint' NameRef) 'check' '(' Expr ')' ('no' 'inherit')? - // ConstraintOptionList? + ConstraintOptionList? UsingIndex = 'using' 'index' NameRef @@ -252,27 +248,6 @@ Column = 'period'? (Name | Name Type Collate? | IndexExpr) -// ColumnList = -// '(' Column (',' Column)* ('without' 'overlaps')? ')' - -// IncludeColumns = -// 'include' ColumnList - -// Operator = -// ('operator' '(' '#op' ')') - -// StorageParam = -// Path ('=' (Literal | Operator | Type)) - -// StorageParamList = -// '(' StorageParam (',' StorageParam)* ')' - -// WithParams = -// 'with' StorageParamList - -// ConstraintIndexTablespace = -// 'using' 'index' 'tablespace' NameRef - UniqueConstraint = ('constraint' NameRef) 'unique' @@ -280,39 +255,62 @@ UniqueConstraint = UsingIndex | ( 'nulls' 'not'? 'distinct' )? ColumnList ) - // ConstraintOptionList? + ConstraintOptionList? PrimaryKeyConstraint = ('constraint' NameRef) 'primary' 'key' (UsingIndex | ColumnList IndexParams) - // ConstraintOptionList? + ConstraintOptionList? -// ExcludeElement = -// ('(' Expr ')' | Expr) 'with' Operator +SetNullColumns = + 'set' 'null' ColumnList? -// RefAction = -// 'no' 'action' -// | 'restrict' -// | 'cascade' -// | 'set' 'null' ColumnList? -// | 'set' 'default' ColumnList? +SetDefaultColumns = + 'set' 'default' ColumnList? -ForeignKeyConstraint = - 'foreign' 'key' ColumnList 'references' Path ColumnList - ('match' ('full' | 'partial' | 'simple') )? - // ('on' 'delete' RefAction)? - // ('on' 'update' RefAction)? +Cascade = + 'cascade' + +Restrict = + 'restrict' + +NoAction = + 'no' 'action' -// TableConstraint = -// ('constraint' Name)? +RefAction = + NoAction +| Restrict +| Cascade +| SetNullColumns +| SetDefaultColumns -// CheckConstraint -// | UniqueConstraint -// | PrimaryKeyConstraint -// | ExcludeConstraint -// | ForeignKeyConstraint +OnDeleteAction = + 'on' 'delete' RefAction -// ConstraintOptionList? +OnUpdateAction = + 'on' 'update' RefAction + +MatchFull = + 'match' 'full' + +MatchPartial = + 'match' 'partial' + + +MatchSimple = + 'match' 'simple' + +MatchType = + MatchFull +| MatchPartial +| MatchSimple + + +ForeignKeyConstraint = + 'foreign' 'key' from_columns:ColumnList 'references' Path to_columns:ColumnList + MatchType? + OnDeleteAction? + OnUpdateAction? DeferrableConstraintOption = 'deferrable' @@ -331,23 +329,21 @@ ConstraintOptionList = (DeferrableConstraintOption | NotDeferrableConstraintOption)? (InitiallyDeferredConstraintOption | InitiallyImmediateConstraintOption)? -// AddConstraint = -// 'add' TableConstraint ('not' 'valid')? NotNullConstraint = ('constraint' NameRef) 'not' 'null' - // ConstraintOptionList? + ConstraintOptionList? NullConstraint = ('constraint' NameRef) 'null' - // ConstraintOptionList? + ConstraintOptionList? DefaultConstraint = - // ('constraint' NameRef) + ('constraint' NameRef) 'default' Expr - // ConstraintOptionList? + ConstraintOptionList? // SequenceOption = // 'as' Type @@ -372,15 +368,15 @@ GeneratedConstraint = ('constraint' NameRef) 'generated' ('always' 'as' '(' Expr ')' 'stored' | ('always' | 'by' 'default') 'as' 'identity' SequenceOptionList? ) - // ConstraintOptionList? + ConstraintOptionList? ReferencesConstraint = ('constraint' NameRef) 'references' Path '(' NameRef ')' - ('match' 'full' | 'match' 'partial' | 'match' 'simple')? - // ('on' 'delete' RefAction)? - // ('on' 'update' RefAction)? - // ConstraintOptionList? + MatchType? + OnDeleteAction? + OnUpdateAction? + ConstraintOptionList? AlterTableAction = ValidateConstraint @@ -581,8 +577,6 @@ IfExists = 'if' 'exists' DropType = - // TODO: codegen isn't robust enough to allow us to exclude the extra wrapping - // parens around the Path stuff 'drop' 'type' IfExists? (Path (',' Path)*) ('cascade' | 'restrict')? DropIndex = @@ -615,7 +609,6 @@ BeginFuncOption = ReturnFuncOption = 'return' Expr - FuncOptionList = options:(FuncOption*) @@ -766,7 +759,7 @@ PostfixExpr = Expr IndexExpr = - Expr '[' Expr ']' + base:Expr '[' index:Expr ']' BetweenExpr = target:Expr 'between' (start:Expr) 'and' (end:Expr)