Skip to content

Commit 4cf5e57

Browse files
Postgres: Apply ONLY keyword per table in TRUNCATE stmt (#1872)
1 parent de2cc7b commit 4cf5e57

File tree

5 files changed

+44
-14
lines changed

5 files changed

+44
-14
lines changed

src/ast/mod.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3014,9 +3014,6 @@ pub enum Statement {
30143014
/// TABLE - optional keyword;
30153015
table: bool,
30163016
/// Postgres-specific option
3017-
/// [ TRUNCATE TABLE ONLY ]
3018-
only: bool,
3019-
/// Postgres-specific option
30203017
/// [ RESTART IDENTITY | CONTINUE IDENTITY ]
30213018
identity: Option<TruncateIdentityOption>,
30223019
/// Postgres-specific option
@@ -4425,17 +4422,15 @@ impl fmt::Display for Statement {
44254422
table_names,
44264423
partitions,
44274424
table,
4428-
only,
44294425
identity,
44304426
cascade,
44314427
on_cluster,
44324428
} => {
44334429
let table = if *table { "TABLE " } else { "" };
4434-
let only = if *only { "ONLY " } else { "" };
44354430

44364431
write!(
44374432
f,
4438-
"TRUNCATE {table}{only}{table_names}",
4433+
"TRUNCATE {table}{table_names}",
44394434
table_names = display_comma_separated(table_names)
44404435
)?;
44414436

@@ -6106,10 +6101,17 @@ pub struct TruncateTableTarget {
61066101
/// name of the table being truncated
61076102
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
61086103
pub name: ObjectName,
6104+
/// Postgres-specific option
6105+
/// [ TRUNCATE TABLE ONLY ]
6106+
/// <https://www.postgresql.org/docs/current/sql-truncate.html>
6107+
pub only: bool,
61096108
}
61106109

61116110
impl fmt::Display for TruncateTableTarget {
61126111
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6112+
if self.only {
6113+
write!(f, "ONLY ")?;
6114+
};
61136115
write!(f, "{}", self.name)
61146116
}
61156117
}

src/ast/spans.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,6 @@ impl Spanned for Statement {
311311
table_names,
312312
partitions,
313313
table: _,
314-
only: _,
315314
identity: _,
316315
cascade: _,
317316
on_cluster: _,

src/parser/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -960,12 +960,13 @@ impl<'a> Parser<'a> {
960960

961961
pub fn parse_truncate(&mut self) -> Result<Statement, ParserError> {
962962
let table = self.parse_keyword(Keyword::TABLE);
963-
let only = self.parse_keyword(Keyword::ONLY);
964963

965964
let table_names = self
966-
.parse_comma_separated(|p| p.parse_object_name(false))?
965+
.parse_comma_separated(|p| {
966+
Ok((p.parse_keyword(Keyword::ONLY), p.parse_object_name(false)?))
967+
})?
967968
.into_iter()
968-
.map(|n| TruncateTableTarget { name: n })
969+
.map(|(only, name)| TruncateTableTarget { name, only })
969970
.collect();
970971

971972
let mut partitions = None;
@@ -996,7 +997,6 @@ impl<'a> Parser<'a> {
996997
table_names,
997998
partitions,
998999
table,
999-
only,
10001000
identity,
10011001
cascade,
10021002
on_cluster,

tests/sqlparser_common.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15302,3 +15302,31 @@ fn test_open() {
1530215302
})
1530315303
);
1530415304
}
15305+
15306+
#[test]
15307+
fn parse_truncate_only() {
15308+
let truncate = all_dialects().verified_stmt("TRUNCATE TABLE employee, ONLY dept");
15309+
15310+
let table_names = vec![
15311+
TruncateTableTarget {
15312+
name: ObjectName::from(vec![Ident::new("employee")]),
15313+
only: false,
15314+
},
15315+
TruncateTableTarget {
15316+
name: ObjectName::from(vec![Ident::new("dept")]),
15317+
only: true,
15318+
},
15319+
];
15320+
15321+
assert_eq!(
15322+
Statement::Truncate {
15323+
table_names,
15324+
partitions: None,
15325+
table: true,
15326+
identity: None,
15327+
cascade: None,
15328+
on_cluster: None,
15329+
},
15330+
truncate
15331+
);
15332+
}

tests/sqlparser_postgres.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4788,13 +4788,13 @@ fn parse_truncate() {
47884788
let table_name = ObjectName::from(vec![Ident::new("db"), Ident::new("table_name")]);
47894789
let table_names = vec![TruncateTableTarget {
47904790
name: table_name.clone(),
4791+
only: false,
47914792
}];
47924793
assert_eq!(
47934794
Statement::Truncate {
47944795
table_names,
47954796
partitions: None,
47964797
table: false,
4797-
only: false,
47984798
identity: None,
47994799
cascade: None,
48004800
on_cluster: None,
@@ -4811,14 +4811,14 @@ fn parse_truncate_with_options() {
48114811
let table_name = ObjectName::from(vec![Ident::new("db"), Ident::new("table_name")]);
48124812
let table_names = vec![TruncateTableTarget {
48134813
name: table_name.clone(),
4814+
only: true,
48144815
}];
48154816

48164817
assert_eq!(
48174818
Statement::Truncate {
48184819
table_names,
48194820
partitions: None,
48204821
table: true,
4821-
only: true,
48224822
identity: Some(TruncateIdentityOption::Restart),
48234823
cascade: Some(CascadeOption::Cascade),
48244824
on_cluster: None,
@@ -4839,9 +4839,11 @@ fn parse_truncate_with_table_list() {
48394839
let table_names = vec![
48404840
TruncateTableTarget {
48414841
name: table_name_a.clone(),
4842+
only: false,
48424843
},
48434844
TruncateTableTarget {
48444845
name: table_name_b.clone(),
4846+
only: false,
48454847
},
48464848
];
48474849

@@ -4850,7 +4852,6 @@ fn parse_truncate_with_table_list() {
48504852
table_names,
48514853
partitions: None,
48524854
table: true,
4853-
only: false,
48544855
identity: Some(TruncateIdentityOption::Restart),
48554856
cascade: Some(CascadeOption::Cascade),
48564857
on_cluster: None,

0 commit comments

Comments
 (0)