1- //! Snowflake ALTER of object kinds with no statement of their own: EXPERIMENT, SNAPSHOT, SNAPSHOT SET , TAG, TASK and TASK GRAPH .
1+ //! Snowflake ALTER of object kinds that have no statement of their own, such as TASK , TAG or ALERT .
22
33use crate :: expressions:: names:: models:: Identifier ;
44use crate :: expressions:: names:: models:: TableRef ;
55use crate :: expressions:: schema_objects:: models:: AlterObject ;
66use crate :: expressions:: schema_objects:: models:: ObjectProperty ;
77use crate :: expressions:: tree:: models:: Expression ;
8+ use crate :: expressions:: types:: models:: Tuple ;
89use crate :: parser:: constants:: SNOWFLAKE_ALTER_KINDS ;
910use crate :: parser:: constants:: TASK_ACTIONS ;
1011use crate :: parser:: models:: Parser ;
@@ -51,6 +52,28 @@ impl Parser {
5152 if self . match_identifier ( "EXPERIMENT" ) {
5253 return self . parse_alter_experiment ( ) . map ( Some ) ;
5354 }
55+ if self . match_identifier ( "ALERT" ) {
56+ return self . parse_alter_alert ( ) . map ( Some ) ;
57+ }
58+ if self . match_text_seq ( & [ "ONLINE" , "FEATURE" , "TABLE" ] ) {
59+ return self . parse_alter_online_feature_table ( ) . map ( Some ) ;
60+ }
61+ if self . check_identifier ( "ONLINE" )
62+ || self . check_identifier ( "FEATURE" ) && !self . check_next_identifier ( "POLICY" )
63+ {
64+ return Err ( self . parse_error (
65+ "Snowflake has ALTER ONLINE FEATURE TABLE and ALTER FEATURE POLICY only" ,
66+ ) ) ;
67+ }
68+ if self . match_identifier ( "VARIABLE" ) {
69+ return self . parse_alter_variable ( ) . map ( Some ) ;
70+ }
71+ if self . match_token ( TokenType :: Function ) || self . match_identifier ( "FUNCTION" ) {
72+ return self . parse_alter_function ( ) . map ( Some ) ;
73+ }
74+ if let Some ( alter) = self . parse_alter_snowflake_resource ( ) ? {
75+ return Ok ( Some ( alter) ) ;
76+ }
5477 if !self . is_at_end ( )
5578 && !SNOWFLAKE_ALTER_KINDS . contains ( & self . peek_text ( ) . to_ascii_uppercase ( ) . as_str ( ) )
5679 {
@@ -63,20 +86,20 @@ impl Parser {
6386 }
6487
6588 /// The uppercase text of the token `offset` tokens ahead, if there is one.
66- pub ( crate ) fn text_at ( & self , offset : usize ) -> Option < String > {
89+ pub ( super ) fn text_at ( & self , offset : usize ) -> Option < String > {
6790 self . tokens
6891 . get ( self . current + offset)
6992 . map ( |token| token. text . to_ascii_uppercase ( ) )
7093 }
7194
7295 /// Parse `[ IF EXISTS ] <name>` after the kind.
73- pub ( crate ) fn parse_alter_object_head ( & mut self ) -> Result < ( TableRef , bool ) > {
96+ pub ( super ) fn parse_alter_object_head ( & mut self ) -> Result < ( TableRef , bool ) > {
7497 let if_exists = self . match_keywords ( & [ TokenType :: If , TokenType :: Exists ] ) ;
7598 Ok ( ( self . parse_object_name ( ) ?, if_exists) )
7699 }
77100
78101 /// Parse an object name: an identifier, never a string or an unquoted reserved keyword.
79- pub ( crate ) fn parse_object_name ( & mut self ) -> Result < TableRef > {
102+ pub ( super ) fn parse_object_name ( & mut self ) -> Result < TableRef > {
80103 if self . check ( TokenType :: String )
81104 || self . is_snowflake_reserved_keyword ( )
82105 || !self . is_object_name_start ( )
@@ -94,7 +117,7 @@ impl Parser {
94117 }
95118
96119 /// Parse a simple name, such as a contact purpose or a property: an identifier, not a reserved keyword.
97- pub ( crate ) fn parse_simple_name ( & mut self ) -> Result < Identifier > {
120+ pub ( super ) fn parse_simple_name ( & mut self ) -> Result < Identifier > {
98121 if self . check ( TokenType :: String )
99122 || self . is_snowflake_reserved_keyword ( )
100123 || !self . is_object_name_start ( )
@@ -105,7 +128,7 @@ impl Parser {
105128 }
106129
107130 /// Parse a property value: a literal, TRUE, FALSE or a name.
108- pub ( crate ) fn parse_object_value ( & mut self ) -> Result < Expression > {
131+ pub ( super ) fn parse_object_value ( & mut self ) -> Result < Expression > {
109132 if self . check ( TokenType :: String )
110133 || self . check ( TokenType :: Number )
111134 || self . check ( TokenType :: DollarString )
@@ -129,15 +152,15 @@ impl Parser {
129152 }
130153
131154 /// Parse a string literal value.
132- pub ( crate ) fn parse_string_value ( & mut self ) -> Result < Expression > {
155+ pub ( super ) fn parse_string_value ( & mut self ) -> Result < Expression > {
133156 if !self . check ( TokenType :: String ) {
134157 return Err ( self . parse_error ( "Expected a string" ) ) ;
135158 }
136159 self . parse_primary ( )
137160 }
138161
139162 /// Consume one of `choices`, each a sequence of words, and return its words joined.
140- pub ( crate ) fn expect_alter_words ( & mut self , choices : & [ & [ & str ] ] ) -> Result < String > {
163+ pub ( super ) fn expect_alter_words ( & mut self , choices : & [ & [ & str ] ] ) -> Result < String > {
141164 match choices. iter ( ) . find ( |words| self . match_text_seq ( words) ) {
142165 Some ( words) => Ok ( words. join ( " " ) ) ,
143166 None => Err ( self . parse_error ( format ! (
@@ -152,7 +175,7 @@ impl Parser {
152175 }
153176
154177 /// Parse a comma-separated list of object names.
155- fn parse_object_name_list ( & mut self ) -> Result < Vec < Expression > > {
178+ pub ( super ) fn parse_object_name_list ( & mut self ) -> Result < Vec < Expression > > {
156179 let mut names = vec ! [ Expression :: Table ( Box :: new( self . parse_object_name( ) ?) ) ] ;
157180 while self . match_token ( TokenType :: Comma ) {
158181 names. push ( Expression :: Table ( Box :: new ( self . parse_object_name ( ) ?) ) ) ;
@@ -161,7 +184,7 @@ impl Parser {
161184 }
162185
163186 /// Parse the properties of a SET (`set`) or UNSET action; `graph` admits TASK_DEFAULTS and always reads CONTACT as contacts.
164- fn parse_alter_object_properties (
187+ pub ( super ) fn parse_alter_object_properties (
165188 & mut self ,
166189 set : bool ,
167190 graph : bool ,
@@ -248,7 +271,7 @@ impl Parser {
248271 }
249272
250273 /// Parse a possibly qualified name, such as a tag name, as one identifier.
251- pub ( crate ) fn parse_simple_qualified_name ( & mut self ) -> Result < Identifier > {
274+ pub ( super ) fn parse_simple_qualified_name ( & mut self ) -> Result < Identifier > {
252275 let mut name = self . parse_simple_name ( ) ?;
253276 while self . match_token ( TokenType :: Dot ) {
254277 let part = self . parse_simple_name ( ) ?;
@@ -496,10 +519,214 @@ impl Parser {
496519 ( operands, Vec :: new ( ) ) ,
497520 ) )
498521 }
522+
523+ /// Parse ALTER ALERT after its kind.
524+ fn parse_alter_alert ( & mut self ) -> Result < Expression > {
525+ let head = self . parse_alter_object_head ( ) ?;
526+ let mut action = self . expect_alter_words ( & [
527+ & [ "RESUME" ] ,
528+ & [ "SUSPEND" ] ,
529+ & [ "FROM" , "TEMPLATE" ] ,
530+ & [ "MODIFY" , "CONDITION" , "EXISTS" ] ,
531+ & [ "MODIFY" , "ACTION" ] ,
532+ & [ "SET" ] ,
533+ & [ "UNSET" ] ,
534+ ] ) ?;
535+ let mut operands: Vec < Expression > = Vec :: new ( ) ;
536+ let mut properties: Vec < ObjectProperty > = Vec :: new ( ) ;
537+ match action. as_str ( ) {
538+ "FROM TEMPLATE" => {
539+ operands. push ( Expression :: Table ( Box :: new ( self . parse_object_name ( ) ?) ) ) ;
540+ action. push_str ( & format ! ( " {}" , self . expect_alter_words( & [ & [ "SET" ] ] ) ?) ) ;
541+ properties = self . parse_alter_object_properties ( true , false ) ?;
542+ }
543+ "MODIFY CONDITION EXISTS" => {
544+ self . expect_token ( TokenType :: LParen ) ?;
545+ operands. push ( self . parse_statement ( ) ?) ;
546+ self . expect_token ( TokenType :: RParen ) ?;
547+ }
548+ "MODIFY ACTION" => operands. push ( self . parse_statement ( ) ?) ,
549+ "SET" => properties = self . parse_alter_object_properties ( true , false ) ?,
550+ "UNSET" => properties = self . parse_alter_object_properties ( false , false ) ?,
551+ _ => { }
552+ }
553+ Ok ( alter_object ( "ALERT" , head, action, ( operands, properties) ) )
554+ }
555+
556+ /// Parse ALTER ONLINE FEATURE TABLE after its kind.
557+ fn parse_alter_online_feature_table ( & mut self ) -> Result < Expression > {
558+ let head = self . parse_alter_object_head ( ) ?;
559+ let action = self . expect_alter_words ( & [
560+ & [ "SUSPEND" ] ,
561+ & [ "RESUME" ] ,
562+ & [ "REFRESH" ] ,
563+ & [ "RENAME" , "TO" ] ,
564+ & [ "SET" ] ,
565+ & [ "UNSET" ] ,
566+ ] ) ?;
567+ let mut operands: Vec < Expression > = Vec :: new ( ) ;
568+ let mut properties: Vec < ObjectProperty > = Vec :: new ( ) ;
569+ match action. as_str ( ) {
570+ "RENAME TO" => operands. push ( Expression :: Table ( Box :: new ( self . parse_object_name ( ) ?) ) ) ,
571+ "SET" => properties = self . parse_alter_object_properties ( true , false ) ?,
572+ "UNSET" => {
573+ self . expect_alter_words ( & [ & [ "TAG" ] ] ) ?;
574+ loop {
575+ let name = self . parse_simple_qualified_name ( ) ?;
576+ properties. push ( property ( "TAG" , Some ( name) , None ) ) ;
577+ if !self . match_token ( TokenType :: Comma ) {
578+ break ;
579+ }
580+ }
581+ }
582+ _ => { }
583+ }
584+ Ok ( alter_object (
585+ "ONLINE FEATURE TABLE" ,
586+ head,
587+ action,
588+ ( operands, properties) ,
589+ ) )
590+ }
591+
592+ /// Parse ALTER VARIABLE after its kind.
593+ fn parse_alter_variable ( & mut self ) -> Result < Expression > {
594+ let head = self . parse_alter_object_head ( ) ?;
595+ let action = self . expect_alter_words ( & [
596+ & [ "RENAME" , "TO" ] ,
597+ & [ "SET" , "DEFAULT" ] ,
598+ & [ "DROP" , "DEFAULT" ] ,
599+ & [ "SET" , "COMMENT" ] ,
600+ & [ "UNSET" , "COMMENT" ] ,
601+ ] ) ?;
602+ let mut operands: Vec < Expression > = Vec :: new ( ) ;
603+ let mut properties: Vec < ObjectProperty > = Vec :: new ( ) ;
604+ match action. as_str ( ) {
605+ "RENAME TO" => operands. push ( Expression :: Table ( Box :: new ( self . parse_object_name ( ) ?) ) ) ,
606+ "SET DEFAULT" => operands. push ( self . parse_expression ( ) ?) ,
607+ "SET COMMENT" => {
608+ self . expect_token ( TokenType :: Eq ) ?;
609+ properties. push ( property ( "COMMENT" , None , Some ( self . parse_string_value ( ) ?) ) ) ;
610+ }
611+ _ => { }
612+ }
613+ Ok ( alter_object (
614+ "VARIABLE" ,
615+ head,
616+ action,
617+ ( operands, properties) ,
618+ ) )
619+ }
620+
621+ /// Parse ALTER FUNCTION after its kind: UDF, external, service and data metric functions.
622+ fn parse_alter_function ( & mut self ) -> Result < Expression > {
623+ let head = self . parse_alter_object_head ( ) ?;
624+ let arguments = self . parse_routine_signature ( ) ?;
625+ let mut action = self . expect_alter_words ( & [ & [ "RENAME" , "TO" ] , & [ "SET" ] , & [ "UNSET" ] ] ) ?;
626+ let mut operands: Vec < Expression > = Vec :: new ( ) ;
627+ let mut properties: Vec < ObjectProperty > = Vec :: new ( ) ;
628+ match action. as_str ( ) {
629+ "RENAME TO" => operands. push ( Expression :: Table ( Box :: new ( self . parse_object_name ( ) ?) ) ) ,
630+ "SET" if self . check_identifier ( "SECURE" ) && self . is_statement_end_at ( 1 ) => {
631+ self . skip ( ) ;
632+ action. push_str ( " SECURE" ) ;
633+ }
634+ "SET" => properties = self . parse_routine_set_properties ( ) ?,
635+ _ => properties = self . parse_alter_object_properties ( false , false ) ?,
636+ }
637+ let Expression :: AlterObject ( mut alter) =
638+ alter_object ( "FUNCTION" , head, action, ( operands, properties) )
639+ else {
640+ return Err ( self . parse_error ( "Expected an ALTER statement" ) ) ;
641+ } ;
642+ alter. arguments = arguments;
643+ Ok ( Expression :: AlterObject ( alter) )
644+ }
645+
646+ /// Whether the token `offset` tokens ahead ends the statement.
647+ pub ( super ) fn is_statement_end_at ( & self , offset : usize ) -> bool {
648+ self . tokens
649+ . get ( self . current + offset)
650+ . is_none_or ( |token| token. token_type == TokenType :: Semicolon )
651+ }
652+
653+ /// Parse `( [ <type> , ... ] )` or `( TABLE( <type> , ... ) [ , TABLE( ... ) ] )` after a routine name.
654+ pub ( super ) fn parse_routine_signature ( & mut self ) -> Result < Vec < Expression > > {
655+ self . expect_token ( TokenType :: LParen ) ?;
656+ let mut arguments: Vec < Expression > = Vec :: new ( ) ;
657+ if self . match_token ( TokenType :: RParen ) {
658+ return Ok ( arguments) ;
659+ }
660+ loop {
661+ if self . check ( TokenType :: Table ) && self . check_next ( TokenType :: LParen ) {
662+ self . current += 2 ;
663+ let mut columns = vec ! [ Expression :: DataType ( self . parse_data_type( ) ?) ] ;
664+ while self . match_token ( TokenType :: Comma ) {
665+ columns. push ( Expression :: DataType ( self . parse_data_type ( ) ?) ) ;
666+ }
667+ self . expect_token ( TokenType :: RParen ) ?;
668+ arguments. push ( Expression :: Tuple ( Box :: new ( Tuple {
669+ expressions : columns,
670+ } ) ) ) ;
671+ } else {
672+ arguments. push ( Expression :: DataType ( self . parse_data_type ( ) ?) ) ;
673+ }
674+ if !self . match_token ( TokenType :: Comma ) {
675+ break ;
676+ }
677+ }
678+ self . expect_token ( TokenType :: RParen ) ?;
679+ Ok ( arguments)
680+ }
681+
682+ /// Parse the properties after a routine's SET: TAG pairs, or `<name> = <value>` with list values.
683+ fn parse_routine_set_properties ( & mut self ) -> Result < Vec < ObjectProperty > > {
684+ if self . check_identifier ( "TAG" ) && !self . check_next ( TokenType :: Eq ) {
685+ return self . parse_alter_object_properties ( true , false ) ;
686+ }
687+ let mut properties: Vec < ObjectProperty > = Vec :: new ( ) ;
688+ loop {
689+ let name = self . parse_simple_name ( ) ?;
690+ self . expect_token ( TokenType :: Eq ) ?;
691+ let value = if self . check ( TokenType :: LParen ) {
692+ self . parse_routine_value_list ( ) ?
693+ } else {
694+ self . parse_object_value ( ) ?
695+ } ;
696+ properties. push ( property ( & name. name . to_ascii_uppercase ( ) , None , Some ( value) ) ) ;
697+ self . match_token ( TokenType :: Comma ) ;
698+ if self . is_at_end ( ) || self . check ( TokenType :: Semicolon ) {
699+ return Ok ( properties) ;
700+ }
701+ }
702+ }
703+
704+ /// Parse `( [ <item> [ , ... ] ] )`, each item a value or a `'<key>' = <value>` pair.
705+ pub ( super ) fn parse_routine_value_list ( & mut self ) -> Result < Expression > {
706+ self . expect_token ( TokenType :: LParen ) ?;
707+ let mut items: Vec < Expression > = Vec :: new ( ) ;
708+ if !self . check ( TokenType :: RParen ) {
709+ loop {
710+ let item = self . parse_object_value ( ) ?;
711+ items. push ( if self . match_token ( TokenType :: Eq ) {
712+ Expression :: Tuple ( Box :: new ( Tuple {
713+ expressions : vec ! [ item, self . parse_object_value( ) ?] ,
714+ } ) )
715+ } else {
716+ item
717+ } ) ;
718+ if !self . match_token ( TokenType :: Comma ) {
719+ break ;
720+ }
721+ }
722+ }
723+ self . expect_token ( TokenType :: RParen ) ?;
724+ Ok ( Expression :: Tuple ( Box :: new ( Tuple { expressions : items } ) ) )
725+ }
499726}
500727
501728/// An ALTER of `kind` on the named object, with its action, operands and properties.
502- pub ( crate ) fn alter_object (
729+ pub ( super ) fn alter_object (
503730 kind : & str ,
504731 ( name, if_exists) : ( TableRef , bool ) ,
505732 action : String ,
@@ -508,6 +735,7 @@ pub(crate) fn alter_object(
508735 Expression :: AlterObject ( Box :: new ( AlterObject {
509736 kind : kind. to_owned ( ) ,
510737 name,
738+ arguments : Vec :: new ( ) ,
511739 if_exists,
512740 action,
513741 operands,
@@ -516,7 +744,7 @@ pub(crate) fn alter_object(
516744}
517745
518746/// One property of kind `kind`.
519- pub ( crate ) fn property (
747+ pub ( super ) fn property (
520748 kind : & str ,
521749 name : Option < Identifier > ,
522750 value : Option < Expression > ,
0 commit comments