mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-10-03 18:54: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
|
// we only return some custom value here when the behaviour (not merely the numeric value) differs
|
||||||
// from the default implementation
|
// from the default implementation
|
||||||
match token.token {
|
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::LBracket => Some(Ok(BRACKET_PREC)),
|
||||||
Token::Arrow
|
Token::Arrow
|
||||||
| Token::LongArrow
|
| Token::LongArrow
|
||||||
|
|
|
@ -1722,7 +1722,7 @@ impl<'a> Parser<'a> {
|
||||||
_ => self.expected_at("an expression", next_token_index),
|
_ => 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 {
|
Ok(Expr::Collate {
|
||||||
expr: Box::new(expr),
|
expr: Box::new(expr),
|
||||||
collation: self.parse_object_name(false)?,
|
collation: self.parse_object_name(false)?,
|
||||||
|
@ -3372,6 +3372,7 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
self.advance_token();
|
self.advance_token();
|
||||||
let tok = self.get_current_token();
|
let tok = self.get_current_token();
|
||||||
|
debug!("infix: {tok:?}");
|
||||||
let tok_index = self.get_current_index();
|
let tok_index = self.get_current_index();
|
||||||
let span = tok.span;
|
let span = tok.span;
|
||||||
let regular_binary_operator = match &tok.token {
|
let regular_binary_operator = match &tok.token {
|
||||||
|
@ -17822,30 +17823,6 @@ mod tests {
|
||||||
assert!(Parser::parse_sql(&MySqlDialect {}, sql).is_err());
|
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]
|
#[test]
|
||||||
fn test_placeholder_invalid_whitespace() {
|
fn test_placeholder_invalid_whitespace() {
|
||||||
for w in [" ", "/*invalid*/"] {
|
for w in [" ", "/*invalid*/"] {
|
||||||
|
|
|
@ -16598,3 +16598,60 @@ fn parse_create_view_if_not_exists() {
|
||||||
res.unwrap_err()
|
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