Skip to content
This repository was archived by the owner on Jun 20, 2025. It is now read-only.

Commit 1c3476f

Browse files
committed
Support pg truncate: list of table names
1 parent e0b438b commit 1c3476f

File tree

3 files changed

+63
-6
lines changed

3 files changed

+63
-6
lines changed

src/ast/mod.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2013,11 +2013,12 @@ pub enum Statement {
20132013
Truncate {
20142014
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
20152015
table_name: ObjectName,
2016+
table_names: Vec<ObjectName>,
20162017
partitions: Option<Vec<Expr>>,
20172018
/// TABLE - optional keyword;
20182019
table: bool,
20192020
/// Postgres-specific option
2020-
/// TRUNCATE [ TABLE ] [ ONLY ] name
2021+
/// [ TRUNCATE TABLE ONLY ]
20212022
only: bool,
20222023
/// Postgres-specific option
20232024
/// [ RESTART IDENTITY | CONTINUE IDENTITY ]
@@ -3140,7 +3141,8 @@ impl fmt::Display for Statement {
31403141
Ok(())
31413142
}
31423143
Statement::Truncate {
3143-
table_name,
3144+
table_name: _,
3145+
table_names,
31443146
partitions,
31453147
table,
31463148
only,
@@ -3149,7 +3151,15 @@ impl fmt::Display for Statement {
31493151
} => {
31503152
let table = if *table { "TABLE " } else { "" };
31513153
let only = if *only { "ONLY " } else { "" };
3152-
write!(f, "TRUNCATE {table}{only}{table_name}")?;
3154+
3155+
let table_names = table_names
3156+
.iter()
3157+
.map(|table_name| table_name.to_string()) // replace `to_string()` with the appropriate method if necessary
3158+
.collect::<Vec<String>>()
3159+
.join(", ");
3160+
3161+
write!(f, "TRUNCATE {table}{only}{table_names}")?;
3162+
31533163
if let Some(identity) = identity {
31543164
match identity {
31553165
TruncateIdentityOption::Restart => write!(f, " RESTART IDENTITY")?,

src/parser/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,11 @@ impl<'a> Parser<'a> {
682682
pub fn parse_truncate(&mut self) -> Result<Statement, ParserError> {
683683
let table = self.parse_keyword(Keyword::TABLE);
684684
let only = self.parse_keyword(Keyword::ONLY);
685-
let table_name = self.parse_object_name(false)?;
685+
686+
let table_names = self.parse_comma_separated(|p| p.parse_object_name(false))?;
687+
688+
// Unwrap is safe - the preceding parse fails if there is not at least one table name
689+
let table_name = table_names.first().unwrap().clone();
686690

687691
let mut partitions = None;
688692
if self.parse_keyword(Keyword::PARTITION) {
@@ -714,6 +718,7 @@ impl<'a> Parser<'a> {
714718

715719
Ok(Statement::Truncate {
716720
table_name,
721+
table_names,
717722
partitions,
718723
table,
719724
only,

tests/sqlparser_postgres.rs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,13 @@ fn parse_alter_table_enable() {
593593
pg_and_generic().verified_stmt("ALTER TABLE tab ENABLE TRIGGER trigger_name");
594594
}
595595

596+
#[test]
597+
fn parse_truncate_table() {
598+
pg_and_generic()
599+
.verified_stmt("TRUNCATE TABLE \"users\", \"orders\" RESTART IDENTITY RESTRICT");
600+
pg_and_generic().verified_stmt("TRUNCATE users, orders RESTART IDENTITY");
601+
}
602+
596603
#[test]
597604
fn parse_create_extension() {
598605
pg_and_generic().verified_stmt("CREATE EXTENSION extension_name");
@@ -3957,9 +3964,12 @@ fn parse_select_group_by_cube() {
39573964
#[test]
39583965
fn parse_truncate() {
39593966
let truncate = pg_and_generic().verified_stmt("TRUNCATE db.table_name");
3967+
let table_name = ObjectName(vec![Ident::new("db"), Ident::new("table_name")]);
3968+
let table_names = vec![table_name.clone()];
39603969
assert_eq!(
39613970
Statement::Truncate {
3962-
table_name: ObjectName(vec![Ident::new("db"), Ident::new("table_name")]),
3971+
table_name,
3972+
table_names,
39633973
partitions: None,
39643974
table: false,
39653975
only: false,
@@ -3974,9 +3984,14 @@ fn parse_truncate() {
39743984
fn parse_truncate_with_options() {
39753985
let truncate = pg_and_generic()
39763986
.verified_stmt("TRUNCATE TABLE ONLY db.table_name RESTART IDENTITY CASCADE");
3987+
3988+
let table_name = ObjectName(vec![Ident::new("db"), Ident::new("table_name")]);
3989+
let table_names = vec![table_name.clone()];
3990+
39773991
assert_eq!(
39783992
Statement::Truncate {
3979-
table_name: ObjectName(vec![Ident::new("db"), Ident::new("table_name")]),
3993+
table_name,
3994+
table_names,
39803995
partitions: None,
39813996
table: true,
39823997
only: true,
@@ -3987,6 +4002,33 @@ fn parse_truncate_with_options() {
39874002
);
39884003
}
39894004

4005+
#[test]
4006+
fn parse_truncate_with_table_list() {
4007+
let truncate = pg().verified_stmt(
4008+
"TRUNCATE TABLE db.table_name, db.other_table_name RESTART IDENTITY CASCADE",
4009+
);
4010+
4011+
let table_name = ObjectName(vec![Ident::new("db"), Ident::new("table_name")]);
4012+
4013+
let table_names = vec![
4014+
table_name.clone(),
4015+
ObjectName(vec![Ident::new("db"), Ident::new("other_table_name")]),
4016+
];
4017+
4018+
assert_eq!(
4019+
Statement::Truncate {
4020+
table_name,
4021+
table_names,
4022+
partitions: None,
4023+
table: true,
4024+
only: false,
4025+
identity: Some(TruncateIdentityOption::Restart),
4026+
cascade: Some(TruncateCascadeOption::Cascade)
4027+
},
4028+
truncate
4029+
);
4030+
}
4031+
39904032
#[test]
39914033
fn parse_select_regexp_as_column_name() {
39924034
pg_and_generic().verified_only_select(

0 commit comments

Comments
 (0)