mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-12-23 11:12:51 +00:00
Added alter external table support for snowflake (#2122)
This commit is contained in:
parent
adbfc46177
commit
048bc8f09d
4 changed files with 74 additions and 8 deletions
|
|
@ -371,10 +371,15 @@ pub enum AlterTableOperation {
|
|||
DropClusteringKey,
|
||||
SuspendRecluster,
|
||||
ResumeRecluster,
|
||||
/// `REFRESH`
|
||||
/// `REFRESH [ '<subpath>' ]`
|
||||
///
|
||||
/// Note: this is Snowflake specific for dynamic tables <https://docs.snowflake.com/en/sql-reference/sql/alter-table>
|
||||
Refresh,
|
||||
/// Note: this is Snowflake specific for dynamic/external tables
|
||||
/// <https://docs.snowflake.com/en/sql-reference/sql/alter-dynamic-table>
|
||||
/// <https://docs.snowflake.com/en/sql-reference/sql/alter-external-table>
|
||||
Refresh {
|
||||
/// Optional subpath for external table refresh
|
||||
subpath: Option<String>,
|
||||
},
|
||||
/// `SUSPEND`
|
||||
///
|
||||
/// Note: this is Snowflake specific for dynamic tables <https://docs.snowflake.com/en/sql-reference/sql/alter-table>
|
||||
|
|
@ -863,8 +868,12 @@ impl fmt::Display for AlterTableOperation {
|
|||
write!(f, "RESUME RECLUSTER")?;
|
||||
Ok(())
|
||||
}
|
||||
AlterTableOperation::Refresh => {
|
||||
write!(f, "REFRESH")
|
||||
AlterTableOperation::Refresh { subpath } => {
|
||||
write!(f, "REFRESH")?;
|
||||
if let Some(path) = subpath {
|
||||
write!(f, " '{path}'")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
AlterTableOperation::Suspend => {
|
||||
write!(f, "SUSPEND")
|
||||
|
|
@ -3977,8 +3986,11 @@ pub enum AlterTableType {
|
|||
/// <https://docs.snowflake.com/en/sql-reference/sql/alter-iceberg-table>
|
||||
Iceberg,
|
||||
/// Dynamic table type
|
||||
/// <https://docs.snowflake.com/en/sql-reference/sql/alter-table>
|
||||
/// <https://docs.snowflake.com/en/sql-reference/sql/alter-dynamic-table>
|
||||
Dynamic,
|
||||
/// External table type
|
||||
/// <https://docs.snowflake.com/en/sql-reference/sql/alter-external-table>
|
||||
External,
|
||||
}
|
||||
|
||||
/// ALTER TABLE statement
|
||||
|
|
@ -4008,6 +4020,7 @@ impl fmt::Display for AlterTable {
|
|||
match &self.table_type {
|
||||
Some(AlterTableType::Iceberg) => write!(f, "ALTER ICEBERG TABLE ")?,
|
||||
Some(AlterTableType::Dynamic) => write!(f, "ALTER DYNAMIC TABLE ")?,
|
||||
Some(AlterTableType::External) => write!(f, "ALTER EXTERNAL TABLE ")?,
|
||||
None => write!(f, "ALTER TABLE ")?,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1145,7 +1145,7 @@ impl Spanned for AlterTableOperation {
|
|||
AlterTableOperation::DropClusteringKey => Span::empty(),
|
||||
AlterTableOperation::SuspendRecluster => Span::empty(),
|
||||
AlterTableOperation::ResumeRecluster => Span::empty(),
|
||||
AlterTableOperation::Refresh => Span::empty(),
|
||||
AlterTableOperation::Refresh { .. } => Span::empty(),
|
||||
AlterTableOperation::Suspend => Span::empty(),
|
||||
AlterTableOperation::Resume => Span::empty(),
|
||||
AlterTableOperation::Algorithm { .. } => Span::empty(),
|
||||
|
|
|
|||
|
|
@ -221,6 +221,11 @@ impl Dialect for SnowflakeDialect {
|
|||
return Some(parse_alter_dynamic_table(parser));
|
||||
}
|
||||
|
||||
if parser.parse_keywords(&[Keyword::ALTER, Keyword::EXTERNAL, Keyword::TABLE]) {
|
||||
// ALTER EXTERNAL TABLE
|
||||
return Some(parse_alter_external_table(parser));
|
||||
}
|
||||
|
||||
if parser.parse_keywords(&[Keyword::ALTER, Keyword::SESSION]) {
|
||||
// ALTER SESSION
|
||||
let set = match parser.parse_one_of_keywords(&[Keyword::SET, Keyword::UNSET]) {
|
||||
|
|
@ -619,7 +624,7 @@ fn parse_alter_dynamic_table(parser: &mut Parser) -> Result<Statement, ParserErr
|
|||
|
||||
// Parse the operation (REFRESH, SUSPEND, or RESUME)
|
||||
let operation = if parser.parse_keyword(Keyword::REFRESH) {
|
||||
AlterTableOperation::Refresh
|
||||
AlterTableOperation::Refresh { subpath: None }
|
||||
} else if parser.parse_keyword(Keyword::SUSPEND) {
|
||||
AlterTableOperation::Suspend
|
||||
} else if parser.parse_keyword(Keyword::RESUME) {
|
||||
|
|
@ -649,6 +654,45 @@ fn parse_alter_dynamic_table(parser: &mut Parser) -> Result<Statement, ParserErr
|
|||
}))
|
||||
}
|
||||
|
||||
/// Parse snowflake alter external table.
|
||||
/// <https://docs.snowflake.com/en/sql-reference/sql/alter-external-table>
|
||||
fn parse_alter_external_table(parser: &mut Parser) -> Result<Statement, ParserError> {
|
||||
let if_exists = parser.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
|
||||
let table_name = parser.parse_object_name(true)?;
|
||||
|
||||
// Parse the operation (REFRESH for now)
|
||||
let operation = if parser.parse_keyword(Keyword::REFRESH) {
|
||||
// Optional subpath for refreshing specific partitions
|
||||
let subpath = match parser.peek_token().token {
|
||||
Token::SingleQuotedString(s) => {
|
||||
parser.next_token();
|
||||
Some(s)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
AlterTableOperation::Refresh { subpath }
|
||||
} else {
|
||||
return parser.expected("REFRESH after ALTER EXTERNAL TABLE", parser.peek_token());
|
||||
};
|
||||
|
||||
let end_token = if parser.peek_token_ref().token == Token::SemiColon {
|
||||
parser.peek_token_ref().clone()
|
||||
} else {
|
||||
parser.get_current_token().clone()
|
||||
};
|
||||
|
||||
Ok(Statement::AlterTable(AlterTable {
|
||||
name: table_name,
|
||||
if_exists,
|
||||
only: false,
|
||||
operations: vec![operation],
|
||||
location: None,
|
||||
on_cluster: None,
|
||||
table_type: Some(AlterTableType::External),
|
||||
end_token: AttachedToken(end_token),
|
||||
}))
|
||||
}
|
||||
|
||||
/// Parse snowflake alter session.
|
||||
/// <https://docs.snowflake.com/en/sql-reference/sql/alter-session>
|
||||
fn parse_alter_session(parser: &mut Parser, set: bool) -> Result<Statement, ParserError> {
|
||||
|
|
|
|||
|
|
@ -4635,3 +4635,12 @@ fn test_alter_dynamic_table() {
|
|||
snowflake().verified_stmt("ALTER DYNAMIC TABLE my_dyn_table SUSPEND");
|
||||
snowflake().verified_stmt("ALTER DYNAMIC TABLE my_dyn_table RESUME");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_alter_external_table() {
|
||||
snowflake().verified_stmt("ALTER EXTERNAL TABLE some_table REFRESH");
|
||||
snowflake().verified_stmt("ALTER EXTERNAL TABLE some_table REFRESH 'year=2025/month=12/'");
|
||||
snowflake().verified_stmt("ALTER EXTERNAL TABLE IF EXISTS some_table REFRESH");
|
||||
snowflake()
|
||||
.verified_stmt("ALTER EXTERNAL TABLE IF EXISTS some_table REFRESH 'year=2025/month=12/'");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue