mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-10-03 02:34:36 +00:00
Fix column definition COLLATE
parsing (#1986)
Some checks failed
Rust / lint (push) Has been cancelled
license / Release Audit Tool (RAT) (push) Has been cancelled
Rust / codestyle (push) Has been cancelled
Rust / test (beta) (push) Has been cancelled
Rust / test (nightly) (push) Has been cancelled
Rust / test (stable) (push) Has been cancelled
Rust / benchmark-lint (push) Has been cancelled
Rust / compile (push) Has been cancelled
Rust / docs (push) Has been cancelled
Rust / compile-no-std (push) Has been cancelled
Some checks failed
Rust / lint (push) Has been cancelled
license / Release Audit Tool (RAT) (push) Has been cancelled
Rust / codestyle (push) Has been cancelled
Rust / test (beta) (push) Has been cancelled
Rust / test (nightly) (push) Has been cancelled
Rust / test (stable) (push) Has been cancelled
Rust / benchmark-lint (push) Has been cancelled
Rust / compile (push) Has been cancelled
Rust / docs (push) Has been cancelled
Rust / compile-no-std (push) Has been cancelled
This commit is contained in:
parent
b2f977384c
commit
60a5c8d42a
3 changed files with 64 additions and 26 deletions
|
@ -110,7 +110,11 @@ impl Dialect for PostgreSqlDialect {
|
|||
// we only return some custom value here when the behaviour (not merely the numeric value) differs
|
||||
// from the default implementation
|
||||
match token.token {
|
||||
Token::Word(w) if w.keyword == Keyword::COLLATE => Some(Ok(COLLATE_PREC)),
|
||||
Token::Word(w)
|
||||
if w.keyword == Keyword::COLLATE && !parser.in_column_definition_state() =>
|
||||
{
|
||||
Some(Ok(COLLATE_PREC))
|
||||
}
|
||||
Token::LBracket => Some(Ok(BRACKET_PREC)),
|
||||
Token::Arrow
|
||||
| Token::LongArrow
|
||||
|
|
|
@ -1722,7 +1722,7 @@ impl<'a> Parser<'a> {
|
|||
_ => self.expected_at("an expression", next_token_index),
|
||||
}?;
|
||||
|
||||
if self.parse_keyword(Keyword::COLLATE) {
|
||||
if !self.in_column_definition_state() && self.parse_keyword(Keyword::COLLATE) {
|
||||
Ok(Expr::Collate {
|
||||
expr: Box::new(expr),
|
||||
collation: self.parse_object_name(false)?,
|
||||
|
@ -3372,6 +3372,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
self.advance_token();
|
||||
let tok = self.get_current_token();
|
||||
debug!("infix: {tok:?}");
|
||||
let tok_index = self.get_current_index();
|
||||
let span = tok.span;
|
||||
let regular_binary_operator = match &tok.token {
|
||||
|
@ -17822,30 +17823,6 @@ mod tests {
|
|||
assert!(Parser::parse_sql(&MySqlDialect {}, sql).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_not_null_in_column_options() {
|
||||
let canonical = concat!(
|
||||
"CREATE TABLE foo (",
|
||||
"abc INT DEFAULT (42 IS NOT NULL) NOT NULL,",
|
||||
" def INT,",
|
||||
" def_null BOOL GENERATED ALWAYS AS (def IS NOT NULL) STORED,",
|
||||
" CHECK (abc IS NOT NULL)",
|
||||
")"
|
||||
);
|
||||
all_dialects().verified_stmt(canonical);
|
||||
all_dialects().one_statement_parses_to(
|
||||
concat!(
|
||||
"CREATE TABLE foo (",
|
||||
"abc INT DEFAULT (42 NOT NULL) NOT NULL,",
|
||||
" def INT,",
|
||||
" def_null BOOL GENERATED ALWAYS AS (def NOT NULL) STORED,",
|
||||
" CHECK (abc NOT NULL)",
|
||||
")"
|
||||
),
|
||||
canonical,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_placeholder_invalid_whitespace() {
|
||||
for w in [" ", "/*invalid*/"] {
|
||||
|
|
|
@ -16598,3 +16598,60 @@ fn parse_create_view_if_not_exists() {
|
|||
res.unwrap_err()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_not_null_in_column_options() {
|
||||
let canonical = concat!(
|
||||
"CREATE TABLE foo (",
|
||||
"abc INT DEFAULT (42 IS NOT NULL) NOT NULL,",
|
||||
" def INT,",
|
||||
" def_null BOOL GENERATED ALWAYS AS (def IS NOT NULL) STORED,",
|
||||
" CHECK (abc IS NOT NULL)",
|
||||
")"
|
||||
);
|
||||
all_dialects().verified_stmt(canonical);
|
||||
all_dialects().one_statement_parses_to(
|
||||
concat!(
|
||||
"CREATE TABLE foo (",
|
||||
"abc INT DEFAULT (42 NOT NULL) NOT NULL,",
|
||||
" def INT,",
|
||||
" def_null BOOL GENERATED ALWAYS AS (def NOT NULL) STORED,",
|
||||
" CHECK (abc NOT NULL)",
|
||||
")"
|
||||
),
|
||||
canonical,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_default_with_collate_column_option() {
|
||||
let sql = "CREATE TABLE foo (abc TEXT DEFAULT 'foo' COLLATE 'en_US')";
|
||||
let stmt = all_dialects().verified_stmt(sql);
|
||||
if let Statement::CreateTable(CreateTable { mut columns, .. }) = stmt {
|
||||
let mut column = columns.pop().unwrap();
|
||||
assert_eq!(&column.name.value, "abc");
|
||||
assert_eq!(column.data_type, DataType::Text);
|
||||
let collate_option = column.options.pop().unwrap();
|
||||
if let ColumnOptionDef {
|
||||
name: None,
|
||||
option: ColumnOption::Collation(collate),
|
||||
} = collate_option
|
||||
{
|
||||
assert_eq!(collate.to_string(), "'en_US'");
|
||||
} else {
|
||||
panic!("Expected collate column option, got {collate_option}");
|
||||
}
|
||||
let default_option = column.options.pop().unwrap();
|
||||
if let ColumnOptionDef {
|
||||
name: None,
|
||||
option: ColumnOption::Default(Expr::Value(value)),
|
||||
} = default_option
|
||||
{
|
||||
assert_eq!(value.to_string(), "'foo'");
|
||||
} else {
|
||||
panic!("Expected default column option, got {default_option}");
|
||||
}
|
||||
} else {
|
||||
panic!("Expected create table statement");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue