This is an automated email from the ASF dual-hosted git repository.

github-bot pushed a commit to branch 
gh-readonly-queue/main/pr-2166-6060a11d1f728d1639f761d3bb90e136911934f9
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git

commit 2cf33de1ce6f189d28fa52bff88cf3bbde384cca
Author: Andriy Romanov <[email protected]>
AuthorDate: Thu Jan 22 06:50:06 2026 -0800

    Fixed truncate table if exists for snowflake (#2166)
---
 src/ast/ddl.rs               | 7 +++++--
 src/parser/mod.rs            | 2 ++
 tests/sqlparser_common.rs    | 1 +
 tests/sqlparser_postgres.rs  | 3 +++
 tests/sqlparser_snowflake.rs | 7 +++++++
 5 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs
index 23fcc010..fcd14b6d 100644
--- a/src/ast/ddl.rs
+++ b/src/ast/ddl.rs
@@ -4062,7 +4062,7 @@ impl fmt::Display for DropTrigger {
 /// A `TRUNCATE` statement.
 ///
 /// ```sql
-/// TRUNCATE TABLE table_names [PARTITION (partitions)] [RESTART IDENTITY | 
CONTINUE IDENTITY] [CASCADE | RESTRICT] [ON CLUSTER cluster_name]
+/// TRUNCATE TABLE [IF EXISTS] table_names [PARTITION (partitions)] [RESTART 
IDENTITY | CONTINUE IDENTITY] [CASCADE | RESTRICT] [ON CLUSTER cluster_name]
 /// ```
 #[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
@@ -4074,6 +4074,8 @@ pub struct Truncate {
     pub partitions: Option<Vec<Expr>>,
     /// TABLE - optional keyword
     pub table: bool,
+    /// Snowflake/Redshift-specific option: [ IF EXISTS ]
+    pub if_exists: bool,
     /// Postgres-specific option: [ RESTART IDENTITY | CONTINUE IDENTITY ]
     pub identity: Option<super::TruncateIdentityOption>,
     /// Postgres-specific option: [ CASCADE | RESTRICT ]
@@ -4086,10 +4088,11 @@ pub struct Truncate {
 impl fmt::Display for Truncate {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         let table = if self.table { "TABLE " } else { "" };
+        let if_exists = if self.if_exists { "IF EXISTS " } else { "" };
 
         write!(
             f,
-            "TRUNCATE {table}{table_names}",
+            "TRUNCATE {table}{if_exists}{table_names}",
             table_names = display_comma_separated(&self.table_names)
         )?;
 
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 149365c4..733abbbf 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -1054,6 +1054,7 @@ impl<'a> Parser<'a> {
     /// Parse `TRUNCATE` statement.
     pub fn parse_truncate(&mut self) -> Result<Truncate, ParserError> {
         let table = self.parse_keyword(Keyword::TABLE);
+        let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
 
         let table_names = self
             .parse_comma_separated(|p| {
@@ -1091,6 +1092,7 @@ impl<'a> Parser<'a> {
             table_names,
             partitions,
             table,
+            if_exists,
             identity,
             cascade,
             on_cluster,
diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs
index bbbf0d83..c67bcb18 100644
--- a/tests/sqlparser_common.rs
+++ b/tests/sqlparser_common.rs
@@ -16773,6 +16773,7 @@ fn parse_truncate_only() {
             table_names,
             partitions: None,
             table: true,
+            if_exists: false,
             identity: None,
             cascade: None,
             on_cluster: None,
diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs
index 325e3939..57bddc65 100644
--- a/tests/sqlparser_postgres.rs
+++ b/tests/sqlparser_postgres.rs
@@ -5089,6 +5089,7 @@ fn parse_truncate() {
             table_names,
             partitions: None,
             table: false,
+            if_exists: false,
             identity: None,
             cascade: None,
             on_cluster: None,
@@ -5113,6 +5114,7 @@ fn parse_truncate_with_options() {
             table_names,
             partitions: None,
             table: true,
+            if_exists: false,
             identity: Some(TruncateIdentityOption::Restart),
             cascade: Some(CascadeOption::Cascade),
             on_cluster: None,
@@ -5146,6 +5148,7 @@ fn parse_truncate_with_table_list() {
             table_names,
             partitions: None,
             table: true,
+            if_exists: false,
             identity: Some(TruncateIdentityOption::Restart),
             cascade: Some(CascadeOption::Cascade),
             on_cluster: None,
diff --git a/tests/sqlparser_snowflake.rs b/tests/sqlparser_snowflake.rs
index 5889b2bd..72f60f1a 100644
--- a/tests/sqlparser_snowflake.rs
+++ b/tests/sqlparser_snowflake.rs
@@ -4533,3 +4533,10 @@ fn test_alter_external_table() {
     snowflake()
         .verified_stmt("ALTER EXTERNAL TABLE IF EXISTS some_table REFRESH 
'year=2025/month=12/'");
 }
+
+#[test]
+fn test_truncate_table_if_exists() {
+    snowflake().verified_stmt("TRUNCATE TABLE IF EXISTS my_table");
+    snowflake().verified_stmt("TRUNCATE TABLE my_table");
+    snowflake().verified_stmt("TRUNCATE IF EXISTS my_table");
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to