Fix always uses CommentDef::WithoutEq while parsing the inline comment (#1453)

This commit is contained in:
hulk 2024-10-05 04:03:02 +08:00 committed by GitHub
parent 1e0460a7df
commit 32a126b27c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 60 additions and 19 deletions

View file

@ -22,9 +22,7 @@ use crate::ast::helpers::stmt_data_loading::{
DataLoadingOption, DataLoadingOptionType, DataLoadingOptions, StageLoadSelectItem,
StageParamsObject,
};
use crate::ast::{
CommentDef, Ident, ObjectName, RowAccessPolicy, Statement, Tag, WrappedCollection,
};
use crate::ast::{Ident, ObjectName, RowAccessPolicy, Statement, Tag, WrappedCollection};
use crate::dialect::{Dialect, Precedence};
use crate::keywords::Keyword;
use crate::parser::{Parser, ParserError};
@ -210,13 +208,9 @@ pub fn parse_create_table(
builder = builder.copy_grants(true);
}
Keyword::COMMENT => {
parser.expect_token(&Token::Eq)?;
let next_token = parser.next_token();
let comment = match next_token.token {
Token::SingleQuotedString(str) => Some(CommentDef::WithEq(str)),
_ => parser.expected("comment", next_token)?,
};
builder = builder.comment(comment);
// Rewind the COMMENT keyword
parser.prev_token();
builder = builder.comment(parser.parse_optional_inline_comment()?);
}
Keyword::AS => {
let query = parser.parse_boxed_query()?;

View file

@ -5871,12 +5871,9 @@ impl<'a> Parser<'a> {
// Excludes Hive dialect here since it has been handled after table column definitions.
if !dialect_of!(self is HiveDialect) && self.parse_keyword(Keyword::COMMENT) {
let _ = self.consume_token(&Token::Eq);
let next_token = self.next_token();
comment = match next_token.token {
Token::SingleQuotedString(str) => Some(CommentDef::WithoutEq(str)),
_ => self.expected("comment", next_token)?,
}
// rewind the COMMENT keyword
self.prev_token();
comment = self.parse_optional_inline_comment()?
};
// Parse optional `AS ( query )`
@ -5957,6 +5954,24 @@ 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)?,
}
} else {
None
};
Ok(comment)
}
pub fn parse_optional_procedure_parameters(
&mut self,
) -> Result<Option<Vec<ProcedureParam>>, ParserError> {

View file

@ -47,6 +47,7 @@ mod test_utils;
#[cfg(test)]
use pretty_assertions::assert_eq;
use sqlparser::ast::ColumnOption::Comment;
use sqlparser::ast::Expr::{Identifier, UnaryOp};
use sqlparser::test_utils::all_dialects_except;
@ -9841,6 +9842,37 @@ fn test_comment_hash_syntax() {
dialects.verified_only_select_with_canonical(sql, canonical);
}
#[test]
fn test_parse_inline_comment() {
let sql =
"CREATE TABLE t0 (id INT COMMENT 'comment without equal') COMMENT = 'comment with equal'";
// Hive dialect doesn't support `=` in table comment, please refer:
// [Hive](https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-CreateTable)
match all_dialects_except(|d| d.is::<HiveDialect>()).verified_stmt(sql) {
Statement::CreateTable(CreateTable {
columns, comment, ..
}) => {
assert_eq!(
columns,
vec![ColumnDef {
name: Ident::new("id".to_string()),
data_type: DataType::Int(None),
collation: None,
options: vec![ColumnOptionDef {
name: None,
option: Comment("comment without equal".to_string()),
}]
}]
);
assert_eq!(
comment.unwrap(),
CommentDef::WithEq("comment with equal".to_string())
);
}
_ => unreachable!(),
}
}
#[test]
fn test_buffer_reuse() {
let d = GenericDialect {};

View file

@ -713,11 +713,11 @@ fn parse_create_table_primary_and_unique_key_characteristic_test() {
#[test]
fn parse_create_table_comment() {
let canonical = "CREATE TABLE foo (bar INT) COMMENT 'baz'";
let without_equal = "CREATE TABLE foo (bar INT) COMMENT 'baz'";
let with_equal = "CREATE TABLE foo (bar INT) COMMENT = 'baz'";
for sql in [canonical, with_equal] {
match mysql().one_statement_parses_to(sql, canonical) {
for sql in [without_equal, with_equal] {
match mysql().verified_stmt(sql) {
Statement::CreateTable(CreateTable { name, comment, .. }) => {
assert_eq!(name.to_string(), "foo");
assert_eq!(comment.expect("Should exist").to_string(), "baz");