@@ -27,15 +27,15 @@ use crate::ast::helpers::stmt_data_loading::{
2727 FileStagingCommand , StageLoadSelectItem , StageLoadSelectItemKind , StageParamsObject ,
2828} ;
2929use crate :: ast:: {
30- AlterTable , AlterTableOperation , AlterTableType , CatalogSyncNamespaceMode , ColumnOption ,
31- ColumnPolicy , ColumnPolicyProperty , ContactEntry , CopyIntoSnowflakeKind , CreateExternalVolume ,
32- CreateTable , CreateTableLikeKind , DollarQuotedString , Ident , IdentityParameters ,
33- IdentityProperty , IdentityPropertyFormatKind , IdentityPropertyKind , IdentityPropertyOrder ,
34- InitializeKind , Insert , MultiTableInsertIntoClause , MultiTableInsertType ,
35- MultiTableInsertValue , MultiTableInsertValues , MultiTableInsertWhenClause , ObjectName ,
36- ObjectNamePart , RefreshModeKind , RowAccessPolicy , ShowObjects , SqlOption , Statement ,
37- StorageLifecyclePolicy , StorageSerializationPolicy , TableObject , TagsColumnOption , Value ,
38- WrappedCollection ,
30+ AlterExternalVolume , AlterExternalVolumeOperation , AlterTable , AlterTableOperation ,
31+ AlterTableType , CatalogSyncNamespaceMode , ColumnOption , ColumnPolicy , ColumnPolicyProperty ,
32+ ContactEntry , CopyIntoSnowflakeKind , CreateExternalVolume , CreateTable , CreateTableLikeKind ,
33+ DollarQuotedString , Ident , IdentityParameters , IdentityProperty , IdentityPropertyFormatKind ,
34+ IdentityPropertyKind , IdentityPropertyOrder , InitializeKind , Insert ,
35+ MultiTableInsertIntoClause , MultiTableInsertType , MultiTableInsertValue ,
36+ MultiTableInsertValues , MultiTableInsertWhenClause , ObjectName , ObjectNamePart ,
37+ RefreshModeKind , RowAccessPolicy , ShowObjects , SqlOption , Statement , StorageLifecyclePolicy ,
38+ StorageSerializationPolicy , TableObject , TagsColumnOption , Value , WrappedCollection ,
3939} ;
4040use crate :: dialect:: { Dialect , Precedence } ;
4141use crate :: keywords:: Keyword ;
@@ -272,6 +272,11 @@ impl Dialect for SnowflakeDialect {
272272 return Some ( parse_alter_dynamic_table ( parser) ) ;
273273 }
274274
275+ if parser. parse_keywords ( & [ Keyword :: ALTER , Keyword :: EXTERNAL , Keyword :: VOLUME ] ) {
276+ // ALTER EXTERNAL VOLUME
277+ return Some ( parse_alter_external_volume ( parser) ) ;
278+ }
279+
275280 if parser. parse_keywords ( & [ Keyword :: ALTER , Keyword :: EXTERNAL , Keyword :: TABLE ] ) {
276281 // ALTER EXTERNAL TABLE
277282 return Some ( parse_alter_external_table ( parser) ) ;
@@ -2041,6 +2046,40 @@ fn parse_create_external_volume(
20412046 . into ( ) )
20422047}
20432048
2049+ /// Parse `ALTER EXTERNAL VOLUME [IF EXISTS] <name> ...`
2050+ fn parse_alter_external_volume ( parser : & mut Parser ) -> Result < Statement , ParserError > {
2051+ let if_exists = parser. parse_keywords ( & [ Keyword :: IF , Keyword :: EXISTS ] ) ;
2052+ let name = parser. parse_object_name ( false ) ?;
2053+
2054+ let operation = if parser. parse_keyword ( Keyword :: ADD ) {
2055+ parser. expect_keyword_is ( Keyword :: STORAGE_LOCATION ) ?;
2056+ parser. expect_token ( & Token :: Eq ) ?;
2057+ AlterExternalVolumeOperation :: AddStorageLocation ( parse_external_volume_storage_location (
2058+ parser,
2059+ ) ?)
2060+ } else if parser. parse_keyword ( Keyword :: SET ) {
2061+ parser. expect_keyword_is ( Keyword :: ALLOW_WRITES ) ?;
2062+ parser. expect_token ( & Token :: Eq ) ?;
2063+ AlterExternalVolumeOperation :: SetAllowWrites ( parser. parse_boolean_string ( ) ?)
2064+ } else if parser. parse_keyword ( Keyword :: REMOVE ) {
2065+ parser. expect_keyword_is ( Keyword :: STORAGE_LOCATION ) ?;
2066+ let loc_name = parser. parse_literal_string ( ) ?;
2067+ AlterExternalVolumeOperation :: RemoveStorageLocation ( loc_name)
2068+ } else {
2069+ return parser. expected (
2070+ "ADD, SET, or REMOVE after ALTER EXTERNAL VOLUME <name>" ,
2071+ parser. peek_token ( ) ,
2072+ ) ;
2073+ } ;
2074+
2075+ Ok ( AlterExternalVolume {
2076+ name,
2077+ if_exists,
2078+ operation,
2079+ }
2080+ . into ( ) )
2081+ }
2082+
20442083/// Parse one parenthesized storage-location option list, e.g.
20452084/// `(NAME='loc1' STORAGE_PROVIDER='S3' ...)`. The options (and the
20462085/// `ENCRYPTION = (...)` sub-list) are parsed generically via
0 commit comments