Allow to use ON CLUSTER cluster_name in TRUNCATE syntax (#1428)

This commit is contained in:
hulk 2024-09-19 18:56:00 +08:00 committed by GitHub
parent 246838a69f
commit 1c505ce736
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 38 additions and 2 deletions

View file

@ -2172,6 +2172,11 @@ pub enum Statement {
/// Postgres-specific option /// Postgres-specific option
/// [ CASCADE | RESTRICT ] /// [ CASCADE | RESTRICT ]
cascade: Option<TruncateCascadeOption>, cascade: Option<TruncateCascadeOption>,
/// ClickHouse-specific option
/// [ ON CLUSTER cluster_name ]
///
/// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/truncate/)
on_cluster: Option<Ident>,
}, },
/// ```sql /// ```sql
/// MSCK /// MSCK
@ -3293,6 +3298,7 @@ impl fmt::Display for Statement {
only, only,
identity, identity,
cascade, cascade,
on_cluster,
} => { } => {
let table = if *table { "TABLE " } else { "" }; let table = if *table { "TABLE " } else { "" };
let only = if *only { "ONLY " } else { "" }; let only = if *only { "ONLY " } else { "" };
@ -3321,6 +3327,9 @@ impl fmt::Display for Statement {
write!(f, " PARTITION ({})", display_comma_separated(parts))?; write!(f, " PARTITION ({})", display_comma_separated(parts))?;
} }
} }
if let Some(on_cluster) = on_cluster {
write!(f, " ON CLUSTER {on_cluster}")?;
}
Ok(()) Ok(())
} }
Statement::AttachDatabase { Statement::AttachDatabase {

View file

@ -708,6 +708,8 @@ impl<'a> Parser<'a> {
}; };
}; };
let on_cluster = self.parse_optional_on_cluster()?;
Ok(Statement::Truncate { Ok(Statement::Truncate {
table_names, table_names,
partitions, partitions,
@ -715,6 +717,7 @@ impl<'a> Parser<'a> {
only, only,
identity, identity,
cascade, cascade,
on_cluster,
}) })
} }

View file

@ -10804,3 +10804,24 @@ fn test_extract_seconds_single_quote_err() {
"sql parser error: Expected: date/time field, found: 'seconds'" "sql parser error: Expected: date/time field, found: 'seconds'"
); );
} }
#[test]
fn test_truncate_table_with_on_cluster() {
let sql = "TRUNCATE TABLE t ON CLUSTER cluster_name";
match all_dialects().verified_stmt(sql) {
Statement::Truncate { on_cluster, .. } => {
assert_eq!(on_cluster, Some(Ident::new("cluster_name")));
}
_ => panic!("Expected: TRUNCATE TABLE statement"),
}
// Omit ON CLUSTER is allowed
all_dialects().verified_stmt("TRUNCATE TABLE t");
assert_eq!(
ParserError::ParserError("Expected: identifier, found: EOF".to_string()),
all_dialects()
.parse_sql_statements("TRUNCATE TABLE t ON CLUSTER")
.unwrap_err()
);
}

View file

@ -4010,6 +4010,7 @@ fn parse_truncate() {
only: false, only: false,
identity: None, identity: None,
cascade: None, cascade: None,
on_cluster: None,
}, },
truncate truncate
); );
@ -4032,7 +4033,8 @@ fn parse_truncate_with_options() {
table: true, table: true,
only: true, only: true,
identity: Some(TruncateIdentityOption::Restart), identity: Some(TruncateIdentityOption::Restart),
cascade: Some(TruncateCascadeOption::Cascade) cascade: Some(TruncateCascadeOption::Cascade),
on_cluster: None,
}, },
truncate truncate
); );
@ -4063,7 +4065,8 @@ fn parse_truncate_with_table_list() {
table: true, table: true,
only: false, only: false,
identity: Some(TruncateIdentityOption::Restart), identity: Some(TruncateIdentityOption::Restart),
cascade: Some(TruncateCascadeOption::Cascade) cascade: Some(TruncateCascadeOption::Cascade),
on_cluster: None,
}, },
truncate truncate
); );