mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-07-07 17:04:59 +00:00
Redshift alter column type no set (#1912)
This commit is contained in:
parent
a3398223d7
commit
015caca611
7 changed files with 59 additions and 28 deletions
|
@ -893,7 +893,10 @@ pub enum AlterColumnOperation {
|
||||||
data_type: DataType,
|
data_type: DataType,
|
||||||
/// PostgreSQL specific
|
/// PostgreSQL specific
|
||||||
using: Option<Expr>,
|
using: Option<Expr>,
|
||||||
|
/// Set to true if the statement includes the `SET DATA TYPE` keywords
|
||||||
|
had_set: bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// `ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ]`
|
/// `ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ]`
|
||||||
///
|
///
|
||||||
/// Note: this is a PostgreSQL-specific operation.
|
/// Note: this is a PostgreSQL-specific operation.
|
||||||
|
@ -914,12 +917,19 @@ impl fmt::Display for AlterColumnOperation {
|
||||||
AlterColumnOperation::DropDefault => {
|
AlterColumnOperation::DropDefault => {
|
||||||
write!(f, "DROP DEFAULT")
|
write!(f, "DROP DEFAULT")
|
||||||
}
|
}
|
||||||
AlterColumnOperation::SetDataType { data_type, using } => {
|
AlterColumnOperation::SetDataType {
|
||||||
if let Some(expr) = using {
|
data_type,
|
||||||
write!(f, "SET DATA TYPE {data_type} USING {expr}")
|
using,
|
||||||
} else {
|
had_set,
|
||||||
write!(f, "SET DATA TYPE {data_type}")
|
} => {
|
||||||
|
if *had_set {
|
||||||
|
write!(f, "SET DATA ")?;
|
||||||
}
|
}
|
||||||
|
write!(f, "TYPE {data_type}")?;
|
||||||
|
if let Some(expr) = using {
|
||||||
|
write!(f, " USING {expr}")?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
AlterColumnOperation::AddGenerated {
|
AlterColumnOperation::AddGenerated {
|
||||||
generated_as,
|
generated_as,
|
||||||
|
|
|
@ -924,6 +924,7 @@ impl Spanned for AlterColumnOperation {
|
||||||
AlterColumnOperation::SetDataType {
|
AlterColumnOperation::SetDataType {
|
||||||
data_type: _,
|
data_type: _,
|
||||||
using,
|
using,
|
||||||
|
had_set: _,
|
||||||
} => using.as_ref().map_or(Span::empty(), |u| u.span()),
|
} => using.as_ref().map_or(Span::empty(), |u| u.span()),
|
||||||
AlterColumnOperation::AddGenerated { .. } => Span::empty(),
|
AlterColumnOperation::AddGenerated { .. } => Span::empty(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1060,6 +1060,15 @@ pub trait Dialect: Debug + Any {
|
||||||
fn supports_space_separated_column_options(&self) -> bool {
|
fn supports_space_separated_column_options(&self) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the dialect supports the `USING` clause in an `ALTER COLUMN` statement.
|
||||||
|
/// Example:
|
||||||
|
/// ```sql
|
||||||
|
/// ALTER TABLE tbl ALTER COLUMN col SET DATA TYPE <type> USING <exp>`
|
||||||
|
/// ```
|
||||||
|
fn supports_alter_column_type_using(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This represents the operators for which precedence must be defined
|
/// This represents the operators for which precedence must be defined
|
||||||
|
|
|
@ -258,4 +258,8 @@ impl Dialect for PostgreSqlDialect {
|
||||||
fn supports_set_names(&self) -> bool {
|
fn supports_set_names(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn supports_alter_column_type_using(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8734,16 +8734,10 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
} else if self.parse_keywords(&[Keyword::DROP, Keyword::DEFAULT]) {
|
} else if self.parse_keywords(&[Keyword::DROP, Keyword::DEFAULT]) {
|
||||||
AlterColumnOperation::DropDefault {}
|
AlterColumnOperation::DropDefault {}
|
||||||
} else if self.parse_keywords(&[Keyword::SET, Keyword::DATA, Keyword::TYPE])
|
} else if self.parse_keywords(&[Keyword::SET, Keyword::DATA, Keyword::TYPE]) {
|
||||||
|| (is_postgresql && self.parse_keyword(Keyword::TYPE))
|
self.parse_set_data_type(true)?
|
||||||
{
|
} else if self.parse_keyword(Keyword::TYPE) {
|
||||||
let data_type = self.parse_data_type()?;
|
self.parse_set_data_type(false)?
|
||||||
let using = if is_postgresql && self.parse_keyword(Keyword::USING) {
|
|
||||||
Some(self.parse_expr()?)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
AlterColumnOperation::SetDataType { data_type, using }
|
|
||||||
} else if self.parse_keywords(&[Keyword::ADD, Keyword::GENERATED]) {
|
} else if self.parse_keywords(&[Keyword::ADD, Keyword::GENERATED]) {
|
||||||
let generated_as = if self.parse_keyword(Keyword::ALWAYS) {
|
let generated_as = if self.parse_keyword(Keyword::ALWAYS) {
|
||||||
Some(GeneratedAs::Always)
|
Some(GeneratedAs::Always)
|
||||||
|
@ -8909,6 +8903,22 @@ impl<'a> Parser<'a> {
|
||||||
Ok(operation)
|
Ok(operation)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_set_data_type(&mut self, had_set: bool) -> Result<AlterColumnOperation, ParserError> {
|
||||||
|
let data_type = self.parse_data_type()?;
|
||||||
|
let using = if self.dialect.supports_alter_column_type_using()
|
||||||
|
&& self.parse_keyword(Keyword::USING)
|
||||||
|
{
|
||||||
|
Some(self.parse_expr()?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
Ok(AlterColumnOperation::SetDataType {
|
||||||
|
data_type,
|
||||||
|
using,
|
||||||
|
had_set,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_part_or_partition(&mut self) -> Result<Partition, ParserError> {
|
fn parse_part_or_partition(&mut self) -> Result<Partition, ParserError> {
|
||||||
let keyword = self.expect_one_of_keywords(&[Keyword::PART, Keyword::PARTITION])?;
|
let keyword = self.expect_one_of_keywords(&[Keyword::PART, Keyword::PARTITION])?;
|
||||||
match keyword {
|
match keyword {
|
||||||
|
|
|
@ -5057,22 +5057,21 @@ fn parse_alter_table_alter_column_type() {
|
||||||
AlterColumnOperation::SetDataType {
|
AlterColumnOperation::SetDataType {
|
||||||
data_type: DataType::Text,
|
data_type: DataType::Text,
|
||||||
using: None,
|
using: None,
|
||||||
|
had_set: true,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
verified_stmt(&format!("{alter_stmt} ALTER COLUMN is_active TYPE TEXT"));
|
||||||
|
|
||||||
let dialect = TestedDialects::new(vec![Box::new(GenericDialect {})]);
|
let dialects = all_dialects_where(|d| d.supports_alter_column_type_using());
|
||||||
|
dialects.verified_stmt(&format!(
|
||||||
|
"{alter_stmt} ALTER COLUMN is_active SET DATA TYPE TEXT USING 'text'"
|
||||||
|
));
|
||||||
|
|
||||||
let res =
|
let dialects = all_dialects_except(|d| d.supports_alter_column_type_using());
|
||||||
dialect.parse_sql_statements(&format!("{alter_stmt} ALTER COLUMN is_active TYPE TEXT"));
|
let res = dialects.parse_sql_statements(&format!(
|
||||||
assert_eq!(
|
|
||||||
ParserError::ParserError("Expected: SET/DROP NOT NULL, SET DEFAULT, or SET DATA TYPE after ALTER COLUMN, found: TYPE".to_string()),
|
|
||||||
res.unwrap_err()
|
|
||||||
);
|
|
||||||
|
|
||||||
let res = dialect.parse_sql_statements(&format!(
|
|
||||||
"{alter_stmt} ALTER COLUMN is_active SET DATA TYPE TEXT USING 'text'"
|
"{alter_stmt} ALTER COLUMN is_active SET DATA TYPE TEXT USING 'text'"
|
||||||
));
|
));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
@ -764,10 +764,7 @@ fn parse_drop_extension() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_alter_table_alter_column() {
|
fn parse_alter_table_alter_column() {
|
||||||
pg().one_statement_parses_to(
|
pg().verified_stmt("ALTER TABLE tab ALTER COLUMN is_active TYPE TEXT USING 'text'");
|
||||||
"ALTER TABLE tab ALTER COLUMN is_active TYPE TEXT USING 'text'",
|
|
||||||
"ALTER TABLE tab ALTER COLUMN is_active SET DATA TYPE TEXT USING 'text'",
|
|
||||||
);
|
|
||||||
|
|
||||||
match alter_table_op(
|
match alter_table_op(
|
||||||
pg().verified_stmt(
|
pg().verified_stmt(
|
||||||
|
@ -783,6 +780,7 @@ fn parse_alter_table_alter_column() {
|
||||||
AlterColumnOperation::SetDataType {
|
AlterColumnOperation::SetDataType {
|
||||||
data_type: DataType::Text,
|
data_type: DataType::Text,
|
||||||
using: Some(using_expr),
|
using: Some(using_expr),
|
||||||
|
had_set: true,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue