Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4976,6 +4976,8 @@ pub enum Statement {
if_not_exists: bool,
/// Warehouse name.
name: ObjectName,
/// Trailing `WITH TAG (<t> = '<v>' [, ...])` clause; empty when absent.
with_tags: Vec<Tag>,
},
/// ```sql
/// CREATE [OR REPLACE] STREAM [IF NOT EXISTS] <name> ON { TABLE | VIEW } <source>
Expand Down Expand Up @@ -5405,6 +5407,8 @@ pub enum Statement {
object_type: ObjectType,
/// The target object name.
object_name: ObjectName,
/// Whether `IF EXISTS` was specified, suppressing the missing-target error.
if_exists: bool,
/// Whether this is `UNSET TAG` (`true`) or `SET TAG` (`false`).
unset: bool,
/// Tags to set (`SET TAG`); empty for `UNSET TAG`.
Expand Down Expand Up @@ -7589,13 +7593,18 @@ impl fmt::Display for Statement {
or_replace,
if_not_exists,
name,
with_tags,
} => {
write!(
f,
"CREATE {or_replace}WAREHOUSE {if_not_exists}{name}",
or_replace = if *or_replace { "OR REPLACE " } else { "" },
if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
)
)?;
if !with_tags.is_empty() {
write!(f, " WITH TAG ({})", display_comma_separated(with_tags))?;
}
Ok(())
}
Statement::CreateStream {
or_replace,
Expand Down Expand Up @@ -8023,11 +8032,16 @@ impl fmt::Display for Statement {
Statement::SetTags {
object_type,
object_name,
if_exists,
unset,
set_tags,
unset_tags,
} => {
write!(f, "ALTER {object_type} {object_name} ")?;
write!(f, "ALTER {object_type} ")?;
if *if_exists {
write!(f, "IF EXISTS ")?;
}
write!(f, "{object_name} ")?;
if *unset {
write!(f, "UNSET TAG {}", display_comma_separated(unset_tags))
} else {
Expand Down
14 changes: 14 additions & 0 deletions src/dialect/snowflake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,18 @@ impl Dialect for SnowflakeDialect {
return Some(Ok(stmt));
}

// ALTER WAREHOUSE [IF EXISTS] <name> { SET TAG | UNSET TAG } — intercept
// only the tag form. Every other ALTER WAREHOUSE form (SET <property>,
// UNSET, SUSPEND, RESUME, RENAME TO, ABORT ALL QUERIES) fails the closure
// and falls through to Parser::parse_alter_warehouse, which also keeps
// the bare (name-less) form a syntax error — the tag form requires a name.
if let Ok(Some(stmt)) = parser.maybe_parse(|p| {
p.expect_keywords(&[Keyword::ALTER, Keyword::WAREHOUSE])?;
parse_alter_object_set_tags(p, ObjectType::Warehouse)
}) {
return Some(Ok(stmt));
}

if parser.parse_keywords(&[Keyword::ALTER, Keyword::STAGE]) {
// ALTER STAGE
return Some(parse_alter_stage(parser));
Expand Down Expand Up @@ -3331,6 +3343,7 @@ fn parse_alter_object_set_tags(
parser: &mut Parser,
object_type: ObjectType,
) -> Result<Statement, ParserError> {
let if_exists = parser.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
let object_name = parser.parse_object_name(false)?;
let unset = match parser.expect_one_of_keywords(&[Keyword::SET, Keyword::UNSET])? {
Keyword::UNSET => true,
Expand Down Expand Up @@ -3362,6 +3375,7 @@ fn parse_alter_object_set_tags(
Ok(Statement::SetTags {
object_type,
object_name,
if_exists,
unset,
set_tags,
unset_tags,
Expand Down
22 changes: 21 additions & 1 deletion src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5727,10 +5727,29 @@ impl<'a> Parser<'a> {
fn parse_create_warehouse(&mut self, or_replace: bool) -> Result<Statement, ParserError> {
let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
let name = self.parse_object_name(false)?;
// Skip any warehouse parameters (SIZE, MAX_CLUSTER_COUNT, etc.)
// Skip any warehouse parameters (SIZE, MAX_CLUSTER_COUNT, etc.) up to the
// trailing `WITH TAG (<t> = '<v>' [, ...])` clause, which is trailing-only:
// no parameter may follow it.
let mut with_tags = Vec::new();
loop {
match self.peek_token().token {
Token::SemiColon | Token::EOF => break,
Token::Word(w) if w.keyword == Keyword::WITH => {
self.next_token();
self.expect_keyword(Keyword::TAG)?;
self.expect_token(&Token::LParen)?;
with_tags = self.parse_comma_separated(Parser::parse_tag)?;
self.expect_token(&Token::RParen)?;
match self.peek_token().token {
Token::SemiColon | Token::EOF => break,
_ => {
return self.expected(
"end of statement after WITH TAG (...)",
self.peek_token(),
)
}
}
}
_ => {
self.next_token();
}
Expand All @@ -5740,6 +5759,7 @@ impl<'a> Parser<'a> {
or_replace,
if_not_exists,
name,
with_tags,
})
}

Expand Down
Loading