Snowflake: Support dollar quoted comments (#1755)

This commit is contained in:
Aleksei Piianin 2025-03-15 07:07:07 +01:00 committed by GitHub
parent f81aed6359
commit 10cf7c164e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 34 additions and 23 deletions

View file

@ -644,10 +644,7 @@ pub fn parse_create_stage(
// [ comment ]
if parser.parse_keyword(Keyword::COMMENT) {
parser.expect_token(&Token::Eq)?;
comment = Some(match parser.next_token().token {
Token::SingleQuotedString(word) => Ok(word),
_ => parser.expected("a comment statement", parser.peek_token()),
}?)
comment = Some(parser.parse_comment_value()?);
}
Ok(Statement::CreateStage {

View file

@ -5451,11 +5451,7 @@ impl<'a> Parser<'a> {
&& self.parse_keyword(Keyword::COMMENT)
{
self.expect_token(&Token::Eq)?;
let next_token = self.next_token();
match next_token.token {
Token::SingleQuotedString(str) => Some(str),
_ => self.expected("string literal", next_token)?,
}
Some(self.parse_comment_value()?)
} else {
None
};
@ -7059,21 +7055,28 @@ impl<'a> Parser<'a> {
pub fn parse_optional_inline_comment(&mut self) -> Result<Option<CommentDef>, ParserError> {
let comment = if self.parse_keyword(Keyword::COMMENT) {
let has_eq = self.consume_token(&Token::Eq);
let next_token = self.next_token();
match next_token.token {
Token::SingleQuotedString(str) => Some(if has_eq {
CommentDef::WithEq(str)
} else {
CommentDef::WithoutEq(str)
}),
_ => self.expected("comment", next_token)?,
}
let comment = self.parse_comment_value()?;
Some(if has_eq {
CommentDef::WithEq(comment)
} else {
CommentDef::WithoutEq(comment)
})
} else {
None
};
Ok(comment)
}
pub fn parse_comment_value(&mut self) -> Result<String, ParserError> {
let next_token = self.next_token();
let value = match next_token.token {
Token::SingleQuotedString(str) => str,
Token::DollarQuotedString(str) => str.value,
_ => self.expected("string literal", next_token)?,
};
Ok(value)
}
pub fn parse_optional_procedure_parameters(
&mut self,
) -> Result<Option<Vec<ProcedureParam>>, ParserError> {
@ -7209,11 +7212,7 @@ impl<'a> Parser<'a> {
} else if self.parse_keywords(&[Keyword::NOT, Keyword::NULL]) {
Ok(Some(ColumnOption::NotNull))
} else if self.parse_keywords(&[Keyword::COMMENT]) {
let next_token = self.next_token();
match next_token.token {
Token::SingleQuotedString(value, ..) => Ok(Some(ColumnOption::Comment(value))),
_ => self.expected("string", next_token),
}
Ok(Some(ColumnOption::Comment(self.parse_comment_value()?)))
} else if self.parse_keyword(Keyword::NULL) {
Ok(Some(ColumnOption::Null))
} else if self.parse_keyword(Keyword::DEFAULT) {

View file

@ -976,6 +976,21 @@ fn parse_sf_create_or_replace_with_comment_for_snowflake() {
}
}
#[test]
fn parse_sf_create_table_or_view_with_dollar_quoted_comment() {
// Snowflake transforms dollar quoted comments into a common comment in DDL representation of creation
snowflake()
.one_statement_parses_to(
r#"CREATE OR REPLACE TEMPORARY VIEW foo.bar.baz ("COL_1" COMMENT $$comment 1$$) COMMENT = $$view comment$$ AS (SELECT 1)"#,
r#"CREATE OR REPLACE TEMPORARY VIEW foo.bar.baz ("COL_1" COMMENT 'comment 1') COMMENT = 'view comment' AS (SELECT 1)"#
);
snowflake().one_statement_parses_to(
r#"CREATE TABLE my_table (a STRING COMMENT $$comment 1$$) COMMENT = $$table comment$$"#,
r#"CREATE TABLE my_table (a STRING COMMENT 'comment 1') COMMENT = 'table comment'"#,
);
}
#[test]
fn test_sf_derived_table_in_parenthesis() {
// Nesting a subquery in an extra set of parentheses is non-standard,