From e8318920b92fc19a178725dcd7763c978c24115a Mon Sep 17 00:00:00 2001 From: if-loop69420 Date: Wed, 28 Aug 2024 08:45:15 +0200 Subject: [PATCH] Add forall statement, sytaxkinds, tokens, parsing functions, tests and everything else needed --- crates/definitions/src/data.rs | 4 + crates/source_gen/src/lexer/generated.rs | 6 +- crates/source_gen/src/syntax/generated.rs | 6 ++ src/grammar/block.rs | 6 +- src/grammar/forall.rs | 116 ++++++++++++++++++++++ src/grammar/mod.rs | 2 + 6 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 src/grammar/forall.rs diff --git a/crates/definitions/src/data.rs b/crates/definitions/src/data.rs index d047ab7..1991124 100644 --- a/crates/definitions/src/data.rs +++ b/crates/definitions/src/data.rs @@ -190,6 +190,7 @@ pub const TOKENS: Tokens<'_> = Tokens { T!("float"), T!("follows"), T!("for"), + T!("forall"), T!("force"), T!("foreign"), T!("forward"), @@ -344,6 +345,7 @@ pub const TOKENS: Tokens<'_> = Tokens { T!("row"), T!("rowid"), T!("rowtype"), + T!("save"), T!("scale"), T!("schema"), T!("scope"), @@ -432,6 +434,7 @@ pub const SYNTAX_NODES: &'_ [SyntaxNode<'_>] = &[ S!("bind_var", "A bind variable, e.g. `:OLD`"), S!("block", "A node that marks a block"), S!("block_statement", "A node that marks an individual statement inside a block"), + S!("bounds_clause", "A node that contains a full bounds clause"), S!("bulk_into_clause", "A node containing a BULK COLLECT INTO clause"), S!("calc_meas_clause", "A node containing a calc meas clause"), S!("case_stmt", "A node containing a CASE statement"), @@ -472,6 +475,7 @@ pub const SYNTAX_NODES: &'_ [SyntaxNode<'_>] = &[ S!("expression", "Holds a generic SQL logic/arithmetic expression"), S!("filter_clause", "A node that contains a full filter clause"), S!("filter_clauses", "A node that contains a full filter clauses"), + S!("forall_stmt", "A node that contains a full forall statement"), S!("for_loop", "A node containing a FOR LOOP"), S!("func_decl_in_type", "A node containing a func_decl_in_type"), S!("function", "A node that marks a full CREATE [..] FUNCTION block"), diff --git a/crates/source_gen/src/lexer/generated.rs b/crates/source_gen/src/lexer/generated.rs index 2357812..00a2a7a 100644 --- a/crates/source_gen/src/lexer/generated.rs +++ b/crates/source_gen/src/lexer/generated.rs @@ -298,6 +298,8 @@ pub enum TokenKind { FollowsKw, #[token("for", ignore(case))] ForKw, + #[token("forall", ignore(case))] + ForallKw, #[token("force", ignore(case))] ForceKw, #[token("foreign", ignore(case))] @@ -606,6 +608,8 @@ pub enum TokenKind { RowidKw, #[token("rowtype", ignore(case))] RowtypeKw, + #[token("save", ignore(case))] + SaveKw, #[token("scale", ignore(case))] ScaleKw, #[token("schema", ignore(case))] @@ -804,4 +808,4 @@ impl std::fmt::Display for TokenKind { } } #[macro_export] -macro_rules ! T { [inline_comment] => { TokenKind :: InlineComment } ; [whitespace] => { TokenKind :: Whitespace } ; ["$$"] => { TokenKind :: DollarQuote } ; [:=] => { TokenKind :: Assign } ; [*] => { TokenKind :: Asterisk } ; [,] => { TokenKind :: Comma } ; [comparison] => { TokenKind :: Comparison } ; [.] => { TokenKind :: Dot } ; [..] => { TokenKind :: DoubleDot } ; [||] => { TokenKind :: DoublePipe } ; [=] => { TokenKind :: Equals } ; [!] => { TokenKind :: Exclam } ; ["("] => { TokenKind :: LParen } ; [-] => { TokenKind :: Minus } ; [(+)] => { TokenKind :: OracleJoin } ; [%] => { TokenKind :: Percentage } ; [+] => { TokenKind :: Plus } ; [")"] => { TokenKind :: RParen } ; [;] => { TokenKind :: Semicolon } ; [/] => { TokenKind :: Slash } ; [int_literal] => { TokenKind :: Integer } ; [decimal_literal] => { TokenKind :: Decimal } ; [unquoted_ident] => { TokenKind :: UnquotedIdent } ; [quoted_ident] => { TokenKind :: QuotedIdent } ; [quoted_literal] => { TokenKind :: QuotedLiteral } ; [bind_var] => { TokenKind :: BindVar } ; [loop_label] => { TokenKind :: LoopLabel } ; [iter_range] => { TokenKind :: IterRange } ; [accessible] => { TokenKind :: AccessibleKw } ; [add] => { TokenKind :: AddKw } ; [after] => { TokenKind :: AfterKw } ; [agent] => { TokenKind :: AgentKw } ; [aggregate] => { TokenKind :: AggregateKw } ; [all] => { TokenKind :: AllKw } ; [allow] => { TokenKind :: AllowKw } ; [alter] => { TokenKind :: AlterKw } ; [analytic] => { TokenKind :: AnalyticKw } ; [analyze] => { TokenKind :: AnalyzeKw } ; [and] => { TokenKind :: AndKw } ; [annotations] => { TokenKind :: AnnotationsKw } ; [any] => { TokenKind :: AnyKw } ; [anyschema] => { TokenKind :: AnyschemaKw } ; [apply] => { TokenKind :: ApplyKw } ; [array] => { TokenKind :: ArrayKw } ; [as] => { TokenKind :: AsKw } ; [asc] => { TokenKind :: AscKw } ; [associate] => { TokenKind :: AssociateKw } ; [audit] => { TokenKind :: AuditKw } ; [authid] => { TokenKind :: AuthidKw } ; [batch] => { TokenKind :: BatchKw } ; [before] => { TokenKind :: BeforeKw } ; [begin] => { TokenKind :: BeginKw } ; [bequeath] => { TokenKind :: BequeathKw } ; [between] => { TokenKind :: BetweenKw } ; [bfile] => { TokenKind :: BfileKw } ; [binary] => { TokenKind :: BinaryKw } ; [binary_double] => { TokenKind :: BinaryDoubleKw } ; [binary_float] => { TokenKind :: BinaryFloatKw } ; [binary_integer] => { TokenKind :: BinaryIntegerKw } ; [blob] => { TokenKind :: BlobKw } ; [body] => { TokenKind :: BodyKw } ; [breadth] => { TokenKind :: BreadthKw } ; [bulk] => { TokenKind :: BulkKw } ; [by] => { TokenKind :: ByKw } ; [byte] => { TokenKind :: ByteKw } ; [cache] => { TokenKind :: CacheKw } ; [call] => { TokenKind :: CallKw } ; [cascade] => { TokenKind :: CascadeKw } ; [case] => { TokenKind :: CaseKw } ; [c] => { TokenKind :: CKw } ; [char] => { TokenKind :: CharKw } ; [character] => { TokenKind :: CharacterKw } ; [charsetform] => { TokenKind :: CharsetformKw } ; [charsetid] => { TokenKind :: CharsetidKw } ; [check] => { TokenKind :: CheckKw } ; [clob] => { TokenKind :: ClobKw } ; [clone] => { TokenKind :: CloneKw } ; [cluster] => { TokenKind :: ClusterKw } ; [collation] => { TokenKind :: CollationKw } ; [collect] => { TokenKind :: CollectKw } ; [comment] => { TokenKind :: CommentKw } ; [commit] => { TokenKind :: CommitKw } ; [connect] => { TokenKind :: ConnectKw } ; [connect_by_root] => { TokenKind :: ConnectByRootKw } ; [constant] => { TokenKind :: ConstantKw } ; [constraint] => { TokenKind :: ConstraintKw } ; [constructor] => { TokenKind :: ConstructorKw } ; [container] => { TokenKind :: ContainerKw } ; [container_map] => { TokenKind :: ContainerMapKw } ; [containers_default] => { TokenKind :: ContainersDefaultKw } ; [continue] => { TokenKind :: ContinueKw } ; [context] => { TokenKind :: ContextKw } ; [create] => { TokenKind :: CreateKw } ; [cross] => { TokenKind :: CrossKw } ; [crossedition] => { TokenKind :: CrosseditionKw } ; [cube] => { TokenKind :: CubeKw } ; [current_user] => { TokenKind :: CurrentUserKw } ; [cursor] => { TokenKind :: CursorKw } ; [cycle] => { TokenKind :: CycleKw } ; [data] => { TokenKind :: DataKw } ; [database] => { TokenKind :: DatabaseKw } ; [date] => { TokenKind :: DateKw } ; [day] => { TokenKind :: DayKw } ; [db_role_change] => { TokenKind :: DbRoleChangeKw } ; [ddl] => { TokenKind :: DdlKw } ; [dec] => { TokenKind :: DecKw } ; [decimal] => { TokenKind :: DecimalKw } ; [declare] => { TokenKind :: DeclareKw } ; [default] => { TokenKind :: DefaultKw } ; [deferrable] => { TokenKind :: DeferrableKw } ; [deferred] => { TokenKind :: DeferredKw } ; [definer] => { TokenKind :: DefinerKw } ; [delete] => { TokenKind :: DeleteKw } ; [depth] => { TokenKind :: DepthKw } ; [desc] => { TokenKind :: DescKw } ; [deterministic] => { TokenKind :: DeterministicKw } ; [disable] => { TokenKind :: DisableKw } ; [disallow] => { TokenKind :: DisallowKw } ; [disassociate] => { TokenKind :: DisassociateKw } ; [double] => { TokenKind :: DoubleKw } ; [drop] => { TokenKind :: DropKw } ; [duration] => { TokenKind :: DurationKw } ; [each] => { TokenKind :: EachKw } ; [editionable] => { TokenKind :: EditionableKw } ; [editioning] => { TokenKind :: EditioningKw } ; [element] => { TokenKind :: ElementKw } ; [else] => { TokenKind :: ElseKw } ; [elsif] => { TokenKind :: ElsifKw } ; [enable] => { TokenKind :: EnableKw } ; [end] => { TokenKind :: EndKw } ; [env] => { TokenKind :: EnvKw } ; [exception] => { TokenKind :: ExceptionKw } ; [exceptions] => { TokenKind :: ExceptionsKw } ; [execute] => { TokenKind :: ExecuteKw } ; [exists] => { TokenKind :: ExistsKw } ; [exit] => { TokenKind :: ExitKw } ; [extend] => { TokenKind :: ExtendKw } ; [extended] => { TokenKind :: ExtendedKw } ; [external] => { TokenKind :: ExternalKw } ; [fact] => { TokenKind :: FactKw } ; [filter] => { TokenKind :: FilterKw } ; [final] => { TokenKind :: FinalKw } ; [first] => { TokenKind :: FirstKw } ; [float] => { TokenKind :: FloatKw } ; [follows] => { TokenKind :: FollowsKw } ; [for] => { TokenKind :: ForKw } ; [force] => { TokenKind :: ForceKw } ; [foreign] => { TokenKind :: ForeignKw } ; [forward] => { TokenKind :: ForwardKw } ; [from] => { TokenKind :: FromKw } ; [full] => { TokenKind :: FullKw } ; [function] => { TokenKind :: FunctionKw } ; [global] => { TokenKind :: GlobalKw } ; [grant] => { TokenKind :: GrantKw } ; [hierarchies] => { TokenKind :: HierarchiesKw } ; [group] => { TokenKind :: GroupKw } ; [grouping] => { TokenKind :: GroupingKw } ; [hash] => { TokenKind :: HashKw } ; [having] => { TokenKind :: HavingKw } ; [id] => { TokenKind :: IdKw } ; [identifier] => { TokenKind :: IdentifierKw } ; [if] => { TokenKind :: IfKw } ; [ilike] => { TokenKind :: IlikeKw } ; [immediate] => { TokenKind :: ImmediateKw } ; [immutable] => { TokenKind :: ImmutableKw } ; [in] => { TokenKind :: InKw } ; [increment] => { TokenKind :: IncrementKw } ; [index] => { TokenKind :: IndexKw } ; [indicator] => { TokenKind :: IndicatorKw } ; [indices] => { TokenKind :: IndicesKw } ; [initially] => { TokenKind :: InitiallyKw } ; [inner] => { TokenKind :: InnerKw } ; [insert] => { TokenKind :: InsertKw } ; [instantiable] => { TokenKind :: InstantiableKw } ; [instead] => { TokenKind :: InsteadKw } ; [int] => { TokenKind :: IntKw } ; [integer] => { TokenKind :: IntegerKw } ; [interval] => { TokenKind :: IntervalKw } ; [into] => { TokenKind :: IntoKw } ; [invisible] => { TokenKind :: InvisibleKw } ; [is] => { TokenKind :: IsKw } ; [java] => { TokenKind :: JavaKw } ; [keep] => { TokenKind :: KeepKw } ; [join] => { TokenKind :: JoinKw } ; [key] => { TokenKind :: KeyKw } ; [language] => { TokenKind :: LanguageKw } ; [large] => { TokenKind :: LargeKw } ; [last] => { TokenKind :: LastKw } ; [left] => { TokenKind :: LeftKw } ; [length] => { TokenKind :: LengthKw } ; [library] => { TokenKind :: LibraryKw } ; [like] => { TokenKind :: LikeKw } ; [lobs] => { TokenKind :: LobsKw } ; [local] => { TokenKind :: LocalKw } ; [logoff] => { TokenKind :: LogoffKw } ; [logon] => { TokenKind :: LogonKw } ; [long] => { TokenKind :: LongKw } ; [loop] => { TokenKind :: LoopKw } ; [map] => { TokenKind :: MapKw } ; [maxlen] => { TokenKind :: MaxlenKw } ; [measures] => { TokenKind :: MeasuresKw } ; [maxvalue] => { TokenKind :: MaxvalueKw } ; [member] => { TokenKind :: MemberKw } ; [metadata] => { TokenKind :: MetadataKw } ; [minvalue] => { TokenKind :: MinvalueKw } ; [mle] => { TokenKind :: MleKw } ; [module] => { TokenKind :: ModuleKw } ; [month] => { TokenKind :: MonthKw } ; [mutable] => { TokenKind :: MutableKw } ; [name] => { TokenKind :: NameKw } ; [national] => { TokenKind :: NationalKw } ; [natural] => { TokenKind :: NaturalKw } ; [nchar] => { TokenKind :: NcharKw } ; [nclob] => { TokenKind :: NclobKw } ; [new] => { TokenKind :: NewKw } ; [no] => { TokenKind :: NoKw } ; [noaudit] => { TokenKind :: NoauditKw } ; [nocache] => { TokenKind :: NocacheKw } ; [nocopy] => { TokenKind :: NocopyKw } ; [nocycle] => { TokenKind :: NocycleKw } ; [noextend] => { TokenKind :: NoextendKw } ; [nokeep] => { TokenKind :: NokeepKw } ; [nomaxvalue] => { TokenKind :: NomaxvalueKw } ; [nominvalue] => { TokenKind :: NominvalueKw } ; [none] => { TokenKind :: NoneKw } ; [noneditionable] => { TokenKind :: NoneditionableKw } ; [nonschema] => { TokenKind :: NonschemaKw } ; [noorder] => { TokenKind :: NoorderKw } ; [noprecheck] => { TokenKind :: NoprecheckKw } ; [norely] => { TokenKind :: NorelyKw } ; [noscale] => { TokenKind :: NoscaleKw } ; [noshard] => { TokenKind :: NoshardKw } ; [not] => { TokenKind :: NotKw } ; [novalidate] => { TokenKind :: NovalidateKw } ; [nowait] => { TokenKind :: NowaitKw } ; [null] => { TokenKind :: NullKw } ; [nulls] => { TokenKind :: NullsKw } ; [number] => { TokenKind :: NumberKw } ; [numeric] => { TokenKind :: NumericKw } ; [nvarchar2] => { TokenKind :: Nvarchar2Kw } ; [object] => { TokenKind :: ObjectKw } ; [of] => { TokenKind :: OfKw } ; [oid] => { TokenKind :: OidKw } ; [old] => { TokenKind :: OldKw } ; [on] => { TokenKind :: OnKw } ; [only] => { TokenKind :: OnlyKw } ; [option] => { TokenKind :: OptionKw } ; [or] => { TokenKind :: OrKw } ; [order] => { TokenKind :: OrderKw } ; [others] => { TokenKind :: OthersKw } ; [out] => { TokenKind :: OutKw } ; [overriding] => { TokenKind :: OverridingKw } ; [outer] => { TokenKind :: OuterKw } ; [package] => { TokenKind :: PackageKw } ; [parallel_enable] => { TokenKind :: ParallelEnableKw } ; [parameters] => { TokenKind :: ParametersKw } ; [parent] => { TokenKind :: ParentKw } ; [pairs] => { TokenKind :: PairsKw } ; [partition] => { TokenKind :: PartitionKw } ; [persistable] => { TokenKind :: PersistableKw } ; [pipelined] => { TokenKind :: PipelinedKw } ; [plpgsql] => { TokenKind :: PlpgsqlKw } ; [pls_integer] => { TokenKind :: PlsIntegerKw } ; [pluggable] => { TokenKind :: PluggableKw } ; [pragma] => { TokenKind :: PragmaKw } ; [precedes] => { TokenKind :: PrecedesKw } ; [precheck] => { TokenKind :: PrecheckKw } ; [precision] => { TokenKind :: PrecisionKw } ; [prior] => { TokenKind :: PriorKw } ; [primary] => { TokenKind :: PrimaryKw } ; [procedure] => { TokenKind :: ProcedureKw } ; [range] => { TokenKind :: RangeKw } ; [raise] => { TokenKind :: RaiseKw } ; [raw] => { TokenKind :: RawKw } ; [read] => { TokenKind :: ReadKw } ; [real] => { TokenKind :: RealKw } ; [record] => { TokenKind :: RecordKw } ; [ref] => { TokenKind :: RefKw } ; [reference] => { TokenKind :: ReferenceKw } ; [references] => { TokenKind :: ReferencesKw } ; [referencing] => { TokenKind :: ReferencingKw } ; [relies_on] => { TokenKind :: ReliesOnKw } ; [rely] => { TokenKind :: RelyKw } ; [rename] => { TokenKind :: RenameKw } ; [repeat] => { TokenKind :: RepeatKw } ; [replace] => { TokenKind :: ReplaceKw } ; [result] => { TokenKind :: ResultKw } ; [result_cache] => { TokenKind :: ResultCacheKw } ; [restricted_references] => { TokenKind :: RestrictedReferencesKw } ; [return] => { TokenKind :: ReturnKw } ; [returning] => { TokenKind :: ReturningKw } ; [reverse] => { TokenKind :: ReverseKw } ; [revoke] => { TokenKind :: RevokeKw } ; [rnds] => { TokenKind :: RndsKw } ; [rnps] => { TokenKind :: RnpsKw } ; [rollup] => { TokenKind :: RollupKw } ; [right] => { TokenKind :: RightKw } ; [row] => { TokenKind :: RowKw } ; [rowid] => { TokenKind :: RowidKw } ; [rowtype] => { TokenKind :: RowtypeKw } ; [scale] => { TokenKind :: ScaleKw } ; [schema] => { TokenKind :: SchemaKw } ; [scope] => { TokenKind :: ScopeKw } ; [search] => { TokenKind :: SearchKw } ; [second] => { TokenKind :: SecondKw } ; [select] => { TokenKind :: SelectKw } ; [self] => { TokenKind :: SelfKw } ; [sequence] => { TokenKind :: SequenceKw } ; [servererror] => { TokenKind :: ServererrorKw } ; [session] => { TokenKind :: SessionKw } ; [set] => { TokenKind :: SetKw } ; [sets] => { TokenKind :: SetsKw } ; [shard] => { TokenKind :: ShardKw } ; [sharing] => { TokenKind :: SharingKw } ; [shutdown] => { TokenKind :: ShutdownKw } ; [siblings] => { TokenKind :: SiblingsKw } ; [signature] => { TokenKind :: SignatureKw } ; [smallint] => { TokenKind :: SmallintKw } ; [start] => { TokenKind :: StartKw } ; [starts] => { TokenKind :: StartsKw } ; [startup] => { TokenKind :: StartupKw } ; [static] => { TokenKind :: StaticKw } ; [statistics] => { TokenKind :: StatisticsKw } ; [store] => { TokenKind :: StoreKw } ; [string] => { TokenKind :: StringKw } ; [struct] => { TokenKind :: StructKw } ; [subtype] => { TokenKind :: SubtypeKw } ; [suspend] => { TokenKind :: SuspendKw } ; [table] => { TokenKind :: TableKw } ; [tables] => { TokenKind :: TablesKw } ; [tdo] => { TokenKind :: TdoKw } ; [then] => { TokenKind :: ThenKw } ; [time] => { TokenKind :: TimeKw } ; [timestamp] => { TokenKind :: TimestampKw } ; [to] => { TokenKind :: ToKw } ; [trigger] => { TokenKind :: TriggerKw } ; [truncate] => { TokenKind :: TruncateKw } ; [trust] => { TokenKind :: TrustKw } ; [type] => { TokenKind :: TypeKw } ; [under] => { TokenKind :: UnderKw } ; [unique] => { TokenKind :: UniqueKw } ; [unplug] => { TokenKind :: UnplugKw } ; [update] => { TokenKind :: UpdateKw } ; [urowid] => { TokenKind :: UrowidKw } ; [using] => { TokenKind :: UsingKw } ; [using_nls_comp] => { TokenKind :: UsingNlsCompKw } ; [validate] => { TokenKind :: ValidateKw } ; [value] => { TokenKind :: ValueKw } ; [values] => { TokenKind :: ValuesKw } ; [varchar] => { TokenKind :: VarcharKw } ; [varchar2] => { TokenKind :: Varchar2Kw } ; [varray] => { TokenKind :: VarrayKw } ; [varrays] => { TokenKind :: VarraysKw } ; [varying] => { TokenKind :: VaryingKw } ; [view] => { TokenKind :: ViewKw } ; [visible] => { TokenKind :: VisibleKw } ; [wait] => { TokenKind :: WaitKw } ; [when] => { TokenKind :: WhenKw } ; [where] => { TokenKind :: WhereKw } ; [while] => { TokenKind :: WhileKw } ; [with] => { TokenKind :: WithKw } ; [wnds] => { TokenKind :: WndsKw } ; [wnps] => { TokenKind :: WnpsKw } ; [work] => { TokenKind :: WorkKw } ; [write] => { TokenKind :: WriteKw } ; [xmlschema] => { TokenKind :: XmlschemaKw } ; [xmltype] => { TokenKind :: XmltypeKw } ; [year] => { TokenKind :: YearKw } ; [zone] => { TokenKind :: ZoneKw } ; [EOF] => { TokenKind :: Eof } ; } +macro_rules ! T { [inline_comment] => { TokenKind :: InlineComment } ; [whitespace] => { TokenKind :: Whitespace } ; ["$$"] => { TokenKind :: DollarQuote } ; [:=] => { TokenKind :: Assign } ; [*] => { TokenKind :: Asterisk } ; [,] => { TokenKind :: Comma } ; [comparison] => { TokenKind :: Comparison } ; [.] => { TokenKind :: Dot } ; [..] => { TokenKind :: DoubleDot } ; [||] => { TokenKind :: DoublePipe } ; [=] => { TokenKind :: Equals } ; [!] => { TokenKind :: Exclam } ; ["("] => { TokenKind :: LParen } ; [-] => { TokenKind :: Minus } ; [(+)] => { TokenKind :: OracleJoin } ; [%] => { TokenKind :: Percentage } ; [+] => { TokenKind :: Plus } ; [")"] => { TokenKind :: RParen } ; [;] => { TokenKind :: Semicolon } ; [/] => { TokenKind :: Slash } ; [int_literal] => { TokenKind :: Integer } ; [decimal_literal] => { TokenKind :: Decimal } ; [unquoted_ident] => { TokenKind :: UnquotedIdent } ; [quoted_ident] => { TokenKind :: QuotedIdent } ; [quoted_literal] => { TokenKind :: QuotedLiteral } ; [bind_var] => { TokenKind :: BindVar } ; [loop_label] => { TokenKind :: LoopLabel } ; [iter_range] => { TokenKind :: IterRange } ; [accessible] => { TokenKind :: AccessibleKw } ; [add] => { TokenKind :: AddKw } ; [after] => { TokenKind :: AfterKw } ; [agent] => { TokenKind :: AgentKw } ; [aggregate] => { TokenKind :: AggregateKw } ; [all] => { TokenKind :: AllKw } ; [allow] => { TokenKind :: AllowKw } ; [alter] => { TokenKind :: AlterKw } ; [analytic] => { TokenKind :: AnalyticKw } ; [analyze] => { TokenKind :: AnalyzeKw } ; [and] => { TokenKind :: AndKw } ; [annotations] => { TokenKind :: AnnotationsKw } ; [any] => { TokenKind :: AnyKw } ; [anyschema] => { TokenKind :: AnyschemaKw } ; [apply] => { TokenKind :: ApplyKw } ; [array] => { TokenKind :: ArrayKw } ; [as] => { TokenKind :: AsKw } ; [asc] => { TokenKind :: AscKw } ; [associate] => { TokenKind :: AssociateKw } ; [audit] => { TokenKind :: AuditKw } ; [authid] => { TokenKind :: AuthidKw } ; [batch] => { TokenKind :: BatchKw } ; [before] => { TokenKind :: BeforeKw } ; [begin] => { TokenKind :: BeginKw } ; [bequeath] => { TokenKind :: BequeathKw } ; [between] => { TokenKind :: BetweenKw } ; [bfile] => { TokenKind :: BfileKw } ; [binary] => { TokenKind :: BinaryKw } ; [binary_double] => { TokenKind :: BinaryDoubleKw } ; [binary_float] => { TokenKind :: BinaryFloatKw } ; [binary_integer] => { TokenKind :: BinaryIntegerKw } ; [blob] => { TokenKind :: BlobKw } ; [body] => { TokenKind :: BodyKw } ; [breadth] => { TokenKind :: BreadthKw } ; [bulk] => { TokenKind :: BulkKw } ; [by] => { TokenKind :: ByKw } ; [byte] => { TokenKind :: ByteKw } ; [cache] => { TokenKind :: CacheKw } ; [call] => { TokenKind :: CallKw } ; [cascade] => { TokenKind :: CascadeKw } ; [case] => { TokenKind :: CaseKw } ; [c] => { TokenKind :: CKw } ; [char] => { TokenKind :: CharKw } ; [character] => { TokenKind :: CharacterKw } ; [charsetform] => { TokenKind :: CharsetformKw } ; [charsetid] => { TokenKind :: CharsetidKw } ; [check] => { TokenKind :: CheckKw } ; [clob] => { TokenKind :: ClobKw } ; [clone] => { TokenKind :: CloneKw } ; [cluster] => { TokenKind :: ClusterKw } ; [collation] => { TokenKind :: CollationKw } ; [collect] => { TokenKind :: CollectKw } ; [comment] => { TokenKind :: CommentKw } ; [commit] => { TokenKind :: CommitKw } ; [connect] => { TokenKind :: ConnectKw } ; [connect_by_root] => { TokenKind :: ConnectByRootKw } ; [constant] => { TokenKind :: ConstantKw } ; [constraint] => { TokenKind :: ConstraintKw } ; [constructor] => { TokenKind :: ConstructorKw } ; [container] => { TokenKind :: ContainerKw } ; [container_map] => { TokenKind :: ContainerMapKw } ; [containers_default] => { TokenKind :: ContainersDefaultKw } ; [continue] => { TokenKind :: ContinueKw } ; [context] => { TokenKind :: ContextKw } ; [create] => { TokenKind :: CreateKw } ; [cross] => { TokenKind :: CrossKw } ; [crossedition] => { TokenKind :: CrosseditionKw } ; [cube] => { TokenKind :: CubeKw } ; [current_user] => { TokenKind :: CurrentUserKw } ; [cursor] => { TokenKind :: CursorKw } ; [cycle] => { TokenKind :: CycleKw } ; [data] => { TokenKind :: DataKw } ; [database] => { TokenKind :: DatabaseKw } ; [date] => { TokenKind :: DateKw } ; [day] => { TokenKind :: DayKw } ; [db_role_change] => { TokenKind :: DbRoleChangeKw } ; [ddl] => { TokenKind :: DdlKw } ; [dec] => { TokenKind :: DecKw } ; [decimal] => { TokenKind :: DecimalKw } ; [declare] => { TokenKind :: DeclareKw } ; [default] => { TokenKind :: DefaultKw } ; [deferrable] => { TokenKind :: DeferrableKw } ; [deferred] => { TokenKind :: DeferredKw } ; [definer] => { TokenKind :: DefinerKw } ; [delete] => { TokenKind :: DeleteKw } ; [depth] => { TokenKind :: DepthKw } ; [desc] => { TokenKind :: DescKw } ; [deterministic] => { TokenKind :: DeterministicKw } ; [disable] => { TokenKind :: DisableKw } ; [disallow] => { TokenKind :: DisallowKw } ; [disassociate] => { TokenKind :: DisassociateKw } ; [double] => { TokenKind :: DoubleKw } ; [drop] => { TokenKind :: DropKw } ; [duration] => { TokenKind :: DurationKw } ; [each] => { TokenKind :: EachKw } ; [editionable] => { TokenKind :: EditionableKw } ; [editioning] => { TokenKind :: EditioningKw } ; [element] => { TokenKind :: ElementKw } ; [else] => { TokenKind :: ElseKw } ; [elsif] => { TokenKind :: ElsifKw } ; [enable] => { TokenKind :: EnableKw } ; [end] => { TokenKind :: EndKw } ; [env] => { TokenKind :: EnvKw } ; [exception] => { TokenKind :: ExceptionKw } ; [exceptions] => { TokenKind :: ExceptionsKw } ; [execute] => { TokenKind :: ExecuteKw } ; [exists] => { TokenKind :: ExistsKw } ; [exit] => { TokenKind :: ExitKw } ; [extend] => { TokenKind :: ExtendKw } ; [extended] => { TokenKind :: ExtendedKw } ; [external] => { TokenKind :: ExternalKw } ; [fact] => { TokenKind :: FactKw } ; [filter] => { TokenKind :: FilterKw } ; [final] => { TokenKind :: FinalKw } ; [first] => { TokenKind :: FirstKw } ; [float] => { TokenKind :: FloatKw } ; [follows] => { TokenKind :: FollowsKw } ; [for] => { TokenKind :: ForKw } ; [forall] => { TokenKind :: ForallKw } ; [force] => { TokenKind :: ForceKw } ; [foreign] => { TokenKind :: ForeignKw } ; [forward] => { TokenKind :: ForwardKw } ; [from] => { TokenKind :: FromKw } ; [full] => { TokenKind :: FullKw } ; [function] => { TokenKind :: FunctionKw } ; [global] => { TokenKind :: GlobalKw } ; [grant] => { TokenKind :: GrantKw } ; [hierarchies] => { TokenKind :: HierarchiesKw } ; [group] => { TokenKind :: GroupKw } ; [grouping] => { TokenKind :: GroupingKw } ; [hash] => { TokenKind :: HashKw } ; [having] => { TokenKind :: HavingKw } ; [id] => { TokenKind :: IdKw } ; [identifier] => { TokenKind :: IdentifierKw } ; [if] => { TokenKind :: IfKw } ; [ilike] => { TokenKind :: IlikeKw } ; [immediate] => { TokenKind :: ImmediateKw } ; [immutable] => { TokenKind :: ImmutableKw } ; [in] => { TokenKind :: InKw } ; [increment] => { TokenKind :: IncrementKw } ; [index] => { TokenKind :: IndexKw } ; [indicator] => { TokenKind :: IndicatorKw } ; [indices] => { TokenKind :: IndicesKw } ; [initially] => { TokenKind :: InitiallyKw } ; [inner] => { TokenKind :: InnerKw } ; [insert] => { TokenKind :: InsertKw } ; [instantiable] => { TokenKind :: InstantiableKw } ; [instead] => { TokenKind :: InsteadKw } ; [int] => { TokenKind :: IntKw } ; [integer] => { TokenKind :: IntegerKw } ; [interval] => { TokenKind :: IntervalKw } ; [into] => { TokenKind :: IntoKw } ; [invisible] => { TokenKind :: InvisibleKw } ; [is] => { TokenKind :: IsKw } ; [java] => { TokenKind :: JavaKw } ; [keep] => { TokenKind :: KeepKw } ; [join] => { TokenKind :: JoinKw } ; [key] => { TokenKind :: KeyKw } ; [language] => { TokenKind :: LanguageKw } ; [large] => { TokenKind :: LargeKw } ; [last] => { TokenKind :: LastKw } ; [left] => { TokenKind :: LeftKw } ; [length] => { TokenKind :: LengthKw } ; [library] => { TokenKind :: LibraryKw } ; [like] => { TokenKind :: LikeKw } ; [lobs] => { TokenKind :: LobsKw } ; [local] => { TokenKind :: LocalKw } ; [logoff] => { TokenKind :: LogoffKw } ; [logon] => { TokenKind :: LogonKw } ; [long] => { TokenKind :: LongKw } ; [loop] => { TokenKind :: LoopKw } ; [map] => { TokenKind :: MapKw } ; [maxlen] => { TokenKind :: MaxlenKw } ; [measures] => { TokenKind :: MeasuresKw } ; [maxvalue] => { TokenKind :: MaxvalueKw } ; [member] => { TokenKind :: MemberKw } ; [metadata] => { TokenKind :: MetadataKw } ; [minvalue] => { TokenKind :: MinvalueKw } ; [mle] => { TokenKind :: MleKw } ; [module] => { TokenKind :: ModuleKw } ; [month] => { TokenKind :: MonthKw } ; [mutable] => { TokenKind :: MutableKw } ; [name] => { TokenKind :: NameKw } ; [national] => { TokenKind :: NationalKw } ; [natural] => { TokenKind :: NaturalKw } ; [nchar] => { TokenKind :: NcharKw } ; [nclob] => { TokenKind :: NclobKw } ; [new] => { TokenKind :: NewKw } ; [no] => { TokenKind :: NoKw } ; [noaudit] => { TokenKind :: NoauditKw } ; [nocache] => { TokenKind :: NocacheKw } ; [nocopy] => { TokenKind :: NocopyKw } ; [nocycle] => { TokenKind :: NocycleKw } ; [noextend] => { TokenKind :: NoextendKw } ; [nokeep] => { TokenKind :: NokeepKw } ; [nomaxvalue] => { TokenKind :: NomaxvalueKw } ; [nominvalue] => { TokenKind :: NominvalueKw } ; [none] => { TokenKind :: NoneKw } ; [noneditionable] => { TokenKind :: NoneditionableKw } ; [nonschema] => { TokenKind :: NonschemaKw } ; [noorder] => { TokenKind :: NoorderKw } ; [noprecheck] => { TokenKind :: NoprecheckKw } ; [norely] => { TokenKind :: NorelyKw } ; [noscale] => { TokenKind :: NoscaleKw } ; [noshard] => { TokenKind :: NoshardKw } ; [not] => { TokenKind :: NotKw } ; [novalidate] => { TokenKind :: NovalidateKw } ; [nowait] => { TokenKind :: NowaitKw } ; [null] => { TokenKind :: NullKw } ; [nulls] => { TokenKind :: NullsKw } ; [number] => { TokenKind :: NumberKw } ; [numeric] => { TokenKind :: NumericKw } ; [nvarchar2] => { TokenKind :: Nvarchar2Kw } ; [object] => { TokenKind :: ObjectKw } ; [of] => { TokenKind :: OfKw } ; [oid] => { TokenKind :: OidKw } ; [old] => { TokenKind :: OldKw } ; [on] => { TokenKind :: OnKw } ; [only] => { TokenKind :: OnlyKw } ; [option] => { TokenKind :: OptionKw } ; [or] => { TokenKind :: OrKw } ; [order] => { TokenKind :: OrderKw } ; [others] => { TokenKind :: OthersKw } ; [out] => { TokenKind :: OutKw } ; [overriding] => { TokenKind :: OverridingKw } ; [outer] => { TokenKind :: OuterKw } ; [package] => { TokenKind :: PackageKw } ; [parallel_enable] => { TokenKind :: ParallelEnableKw } ; [parameters] => { TokenKind :: ParametersKw } ; [parent] => { TokenKind :: ParentKw } ; [pairs] => { TokenKind :: PairsKw } ; [partition] => { TokenKind :: PartitionKw } ; [persistable] => { TokenKind :: PersistableKw } ; [pipelined] => { TokenKind :: PipelinedKw } ; [plpgsql] => { TokenKind :: PlpgsqlKw } ; [pls_integer] => { TokenKind :: PlsIntegerKw } ; [pluggable] => { TokenKind :: PluggableKw } ; [pragma] => { TokenKind :: PragmaKw } ; [precedes] => { TokenKind :: PrecedesKw } ; [precheck] => { TokenKind :: PrecheckKw } ; [precision] => { TokenKind :: PrecisionKw } ; [prior] => { TokenKind :: PriorKw } ; [primary] => { TokenKind :: PrimaryKw } ; [procedure] => { TokenKind :: ProcedureKw } ; [range] => { TokenKind :: RangeKw } ; [raise] => { TokenKind :: RaiseKw } ; [raw] => { TokenKind :: RawKw } ; [read] => { TokenKind :: ReadKw } ; [real] => { TokenKind :: RealKw } ; [record] => { TokenKind :: RecordKw } ; [ref] => { TokenKind :: RefKw } ; [reference] => { TokenKind :: ReferenceKw } ; [references] => { TokenKind :: ReferencesKw } ; [referencing] => { TokenKind :: ReferencingKw } ; [relies_on] => { TokenKind :: ReliesOnKw } ; [rely] => { TokenKind :: RelyKw } ; [rename] => { TokenKind :: RenameKw } ; [repeat] => { TokenKind :: RepeatKw } ; [replace] => { TokenKind :: ReplaceKw } ; [result] => { TokenKind :: ResultKw } ; [result_cache] => { TokenKind :: ResultCacheKw } ; [restricted_references] => { TokenKind :: RestrictedReferencesKw } ; [return] => { TokenKind :: ReturnKw } ; [returning] => { TokenKind :: ReturningKw } ; [reverse] => { TokenKind :: ReverseKw } ; [revoke] => { TokenKind :: RevokeKw } ; [rnds] => { TokenKind :: RndsKw } ; [rnps] => { TokenKind :: RnpsKw } ; [rollup] => { TokenKind :: RollupKw } ; [right] => { TokenKind :: RightKw } ; [row] => { TokenKind :: RowKw } ; [rowid] => { TokenKind :: RowidKw } ; [rowtype] => { TokenKind :: RowtypeKw } ; [save] => { TokenKind :: SaveKw } ; [scale] => { TokenKind :: ScaleKw } ; [schema] => { TokenKind :: SchemaKw } ; [scope] => { TokenKind :: ScopeKw } ; [search] => { TokenKind :: SearchKw } ; [second] => { TokenKind :: SecondKw } ; [select] => { TokenKind :: SelectKw } ; [self] => { TokenKind :: SelfKw } ; [sequence] => { TokenKind :: SequenceKw } ; [servererror] => { TokenKind :: ServererrorKw } ; [session] => { TokenKind :: SessionKw } ; [set] => { TokenKind :: SetKw } ; [sets] => { TokenKind :: SetsKw } ; [shard] => { TokenKind :: ShardKw } ; [sharing] => { TokenKind :: SharingKw } ; [shutdown] => { TokenKind :: ShutdownKw } ; [siblings] => { TokenKind :: SiblingsKw } ; [signature] => { TokenKind :: SignatureKw } ; [smallint] => { TokenKind :: SmallintKw } ; [start] => { TokenKind :: StartKw } ; [starts] => { TokenKind :: StartsKw } ; [startup] => { TokenKind :: StartupKw } ; [static] => { TokenKind :: StaticKw } ; [statistics] => { TokenKind :: StatisticsKw } ; [store] => { TokenKind :: StoreKw } ; [string] => { TokenKind :: StringKw } ; [struct] => { TokenKind :: StructKw } ; [subtype] => { TokenKind :: SubtypeKw } ; [suspend] => { TokenKind :: SuspendKw } ; [table] => { TokenKind :: TableKw } ; [tables] => { TokenKind :: TablesKw } ; [tdo] => { TokenKind :: TdoKw } ; [then] => { TokenKind :: ThenKw } ; [time] => { TokenKind :: TimeKw } ; [timestamp] => { TokenKind :: TimestampKw } ; [to] => { TokenKind :: ToKw } ; [trigger] => { TokenKind :: TriggerKw } ; [truncate] => { TokenKind :: TruncateKw } ; [trust] => { TokenKind :: TrustKw } ; [type] => { TokenKind :: TypeKw } ; [under] => { TokenKind :: UnderKw } ; [unique] => { TokenKind :: UniqueKw } ; [unplug] => { TokenKind :: UnplugKw } ; [update] => { TokenKind :: UpdateKw } ; [urowid] => { TokenKind :: UrowidKw } ; [using] => { TokenKind :: UsingKw } ; [using_nls_comp] => { TokenKind :: UsingNlsCompKw } ; [validate] => { TokenKind :: ValidateKw } ; [value] => { TokenKind :: ValueKw } ; [values] => { TokenKind :: ValuesKw } ; [varchar] => { TokenKind :: VarcharKw } ; [varchar2] => { TokenKind :: Varchar2Kw } ; [varray] => { TokenKind :: VarrayKw } ; [varrays] => { TokenKind :: VarraysKw } ; [varying] => { TokenKind :: VaryingKw } ; [view] => { TokenKind :: ViewKw } ; [visible] => { TokenKind :: VisibleKw } ; [wait] => { TokenKind :: WaitKw } ; [when] => { TokenKind :: WhenKw } ; [where] => { TokenKind :: WhereKw } ; [while] => { TokenKind :: WhileKw } ; [with] => { TokenKind :: WithKw } ; [wnds] => { TokenKind :: WndsKw } ; [wnps] => { TokenKind :: WnpsKw } ; [work] => { TokenKind :: WorkKw } ; [write] => { TokenKind :: WriteKw } ; [xmlschema] => { TokenKind :: XmlschemaKw } ; [xmltype] => { TokenKind :: XmltypeKw } ; [year] => { TokenKind :: YearKw } ; [zone] => { TokenKind :: ZoneKw } ; [EOF] => { TokenKind :: Eof } ; } diff --git a/crates/source_gen/src/syntax/generated.rs b/crates/source_gen/src/syntax/generated.rs index 7833f2e..88027c8 100644 --- a/crates/source_gen/src/syntax/generated.rs +++ b/crates/source_gen/src/syntax/generated.rs @@ -46,6 +46,8 @@ pub enum SyntaxKind { Block, #[doc = "A node that marks an individual statement inside a block"] BlockStatement, + #[doc = "A node that contains a full bounds clause"] + BoundsClause, #[doc = "A node containing a BULK COLLECT INTO clause"] BulkIntoClause, #[doc = "A node containing a calc meas clause"] @@ -126,6 +128,8 @@ pub enum SyntaxKind { FilterClause, #[doc = "A node that contains a full filter clauses"] FilterClauses, + #[doc = "A node that contains a full forall statement"] + ForallStmt, #[doc = "A node containing a FOR LOOP"] ForLoop, #[doc = "A node containing a func_decl_in_type"] @@ -471,6 +475,7 @@ impl From for SyntaxKind { TokenKind::FloatKw => SyntaxKind::Keyword, TokenKind::FollowsKw => SyntaxKind::Keyword, TokenKind::ForKw => SyntaxKind::Keyword, + TokenKind::ForallKw => SyntaxKind::Keyword, TokenKind::ForceKw => SyntaxKind::Keyword, TokenKind::ForeignKw => SyntaxKind::Keyword, TokenKind::ForwardKw => SyntaxKind::Keyword, @@ -625,6 +630,7 @@ impl From for SyntaxKind { TokenKind::RowKw => SyntaxKind::Keyword, TokenKind::RowidKw => SyntaxKind::Keyword, TokenKind::RowtypeKw => SyntaxKind::Keyword, + TokenKind::SaveKw => SyntaxKind::Keyword, TokenKind::ScaleKw => SyntaxKind::Keyword, TokenKind::SchemaKw => SyntaxKind::Keyword, TokenKind::ScopeKw => SyntaxKind::Keyword, diff --git a/src/grammar/block.rs b/src/grammar/block.rs index 7a64721..356ab87 100644 --- a/src/grammar/block.rs +++ b/src/grammar/block.rs @@ -16,7 +16,10 @@ use source_gen::T; use super::commit::parse_commit; use super::loops::{parse_continue_stmt, parse_exit_stmt, parse_loop}; -use super::{parse_cte, parse_cursor, parse_dml, parse_execute_immediate, parse_raise_stmt}; +use super::{ + parse_cte, parse_cursor, parse_dml, parse_execute_immediate, parse_forall_stmt, + parse_raise_stmt, +}; /// Parses a complete block. pub fn parse_block(p: &mut Parser) { @@ -64,6 +67,7 @@ pub(super) fn parse_stmt(p: &mut Parser) { T![raise] => parse_raise_stmt(p), T![delete] | T![update] => parse_dml(p), T![commit] => parse_commit(p), + T![forall] => parse_forall_stmt(p), current_token => { if !(opt_assignment_stmt(p) || opt_procedure_call(p)) { p.error(ParseErrorType::ExpectedStatement(current_token)); diff --git a/src/grammar/forall.rs b/src/grammar/forall.rs new file mode 100644 index 0000000..e3431e0 --- /dev/null +++ b/src/grammar/forall.rs @@ -0,0 +1,116 @@ +use crate::Parser; + +use super::{parse_dml, parse_expr, parse_ident}; +use source_gen::{lexer::TokenKind, syntax::SyntaxKind, T}; + +pub(crate) fn parse_forall_stmt(p: &mut Parser) { + p.start(SyntaxKind::ForallStmt); + p.expect(T![forall]); + parse_ident(p, 1..2); + p.expect(T![in]); + parse_bounds_clause(p); + if p.eat(T![save]) { + p.expect(T![exceptions]); + } + parse_dml(p); + p.eat(T![;]); + p.finish(); +} + +pub(crate) fn parse_bounds_clause(p: &mut Parser) { + p.start(SyntaxKind::BoundsClause); + match p.current() { + T![values] => { + p.expect(T![values]); + p.expect(T![of]); + parse_ident(p, 1..2); + } + T![indices] => { + p.expect(T![indices]); + p.expect(T![of]); + parse_ident(p, 1..2); + if p.eat(T![between]) { + parse_expr(p); + p.expect(T![and]); + parse_expr(p); + } + } + _ => { + parse_expr(p); + p.expect(T![iter_range]); + parse_expr(p); + } + } + p.finish(); +} + +#[cfg(test)] +mod tests { + use expect_test::expect; + + use crate::grammar::tests::{check, parse}; + + use super::*; + + #[test] + fn test_parse_forall() { + check( + parse( + "FORALL i IN depts.FIRST..depts.LAST + DELETE FROM employees_temp + WHERE department_id = depts(i);", + parse_forall_stmt, + ), + expect![[r#" +Root@0..102 + ForallStmt@0..102 + Keyword@0..6 "FORALL" + Whitespace@6..7 " " + IdentGroup@7..8 + Ident@7..8 "i" + Whitespace@8..9 " " + Keyword@9..11 "IN" + Whitespace@11..12 " " + BoundsClause@12..40 + IdentGroup@12..23 + Ident@12..17 "depts" + Dot@17..18 "." + Ident@18..23 "FIRST" + IterRange@23..25 ".." + IdentGroup@25..35 + Ident@25..30 "depts" + Dot@30..31 "." + Ident@31..35 "LAST" + Whitespace@35..40 "\n " + DeleteStmt@40..102 + Keyword@40..46 "DELETE" + Whitespace@46..47 " " + Keyword@47..51 "FROM" + Whitespace@51..52 " " + IdentGroup@52..66 + Ident@52..66 "employees_temp" + Whitespace@66..71 "\n " + WhereClause@71..101 + Keyword@71..76 "WHERE" + Whitespace@76..77 " " + Expression@77..101 + IdentGroup@77..90 + Ident@77..90 "department_id" + Whitespace@90..91 " " + ComparisonOp@91..92 "=" + Whitespace@92..93 " " + FunctionInvocation@93..101 + IdentGroup@93..98 + Ident@93..98 "depts" + LParen@98..99 "(" + ArgumentList@99..100 + Argument@99..100 + IdentGroup@99..100 + Ident@99..100 "i" + RParen@100..101 ")" + Semicolon@101..102 ";" +"#]], + vec![], + ); + } +} diff --git a/src/grammar/mod.rs b/src/grammar/mod.rs index e0a9d20..96cb094 100644 --- a/src/grammar/mod.rs +++ b/src/grammar/mod.rs @@ -14,6 +14,7 @@ pub(crate) use datatype::*; pub(crate) use dml::*; pub(crate) use execute_immediate::*; pub(crate) use expressions::*; +pub(crate) use forall::*; pub(crate) use function::*; pub(crate) use function_invocation::*; pub(crate) use package::*; @@ -41,6 +42,7 @@ mod dml; mod element_spec; mod execute_immediate; mod expressions; +mod forall; mod function; mod function_invocation; mod loops;