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

github-bot pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git


The following commit(s) were added to refs/heads/main by this push:
     new 6b352eaf Redshift: more copy options (#2072)
6b352eaf is described below

commit 6b352eaffdd6e8339d062ca8bc671c2c9b415c1e
Author: Yoav Cohen <[email protected]>
AuthorDate: Wed Oct 22 11:11:19 2025 +0200

    Redshift: more copy options (#2072)
---
 src/ast/mod.rs            | 34 ++++++++++++++++++++++++++++++++++
 src/keywords.rs           |  4 ++++
 src/parser/mod.rs         | 31 +++++++++++++++++++++++++++++++
 tests/sqlparser_common.rs | 28 ++++++++++++++++++++++++++--
 4 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/src/ast/mod.rs b/src/ast/mod.rs
index f4e2825d..176d3654 100644
--- a/src/ast/mod.rs
+++ b/src/ast/mod.rs
@@ -8210,6 +8210,8 @@ pub enum CopyLegacyOption {
     Bzip2,
     /// CLEANPATH
     CleanPath,
+    /// COMPUPDATE [ PRESET | { ON | TRUE } | { OFF | FALSE } ]
+    CompUpdate { preset: bool, enabled: Option<bool> },
     /// CSV ...
     Csv(Vec<CopyLegacyCsvOption>),
     /// DATEFORMAT \[ AS \] {'dateformat_string' | 'auto' }
@@ -8250,8 +8252,12 @@ pub enum CopyLegacyOption {
     PartitionBy(UnloadPartitionBy),
     /// REGION \[ AS \] 'aws-region' }
     Region(String),
+    /// REMOVEQUOTES
+    RemoveQuotes,
     /// ROWGROUPSIZE \[ AS \] size \[ MB | GB \]
     RowGroupSize(FileSize),
+    /// STATUPDATE [ { ON | TRUE } | { OFF | FALSE } ]
+    StatUpdate(Option<bool>),
     /// TIMEFORMAT \[ AS \] {'timeformat_string' | 'auto' | 'epochsecs' | 
'epochmillisecs' }
     TimeFormat(Option<String>),
     /// TRUNCATECOLUMNS
@@ -8278,6 +8284,22 @@ impl fmt::Display for CopyLegacyOption {
             BlankAsNull => write!(f, "BLANKSASNULL"),
             Bzip2 => write!(f, "BZIP2"),
             CleanPath => write!(f, "CLEANPATH"),
+            CompUpdate { preset, enabled } => {
+                write!(f, "COMPUPDATE")?;
+                if *preset {
+                    write!(f, " PRESET")?;
+                } else if let Some(enabled) = enabled {
+                    write!(
+                        f,
+                        "{}",
+                        match enabled {
+                            true => " TRUE",
+                            false => " FALSE",
+                        }
+                    )?;
+                }
+                Ok(())
+            }
             Csv(opts) => {
                 write!(f, "CSV")?;
                 if !opts.is_empty() {
@@ -8324,7 +8346,19 @@ impl fmt::Display for CopyLegacyOption {
             Parquet => write!(f, "PARQUET"),
             PartitionBy(p) => write!(f, "{p}"),
             Region(region) => write!(f, "REGION '{}'", 
value::escape_single_quote_string(region)),
+            RemoveQuotes => write!(f, "REMOVEQUOTES"),
             RowGroupSize(file_size) => write!(f, "ROWGROUPSIZE {file_size}"),
+            StatUpdate(enabled) => {
+                write!(
+                    f,
+                    "STATUPDATE{}",
+                    match enabled {
+                        Some(true) => " TRUE",
+                        Some(false) => " FALSE",
+                        _ => "",
+                    }
+                )
+            }
             TimeFormat(fmt) => {
                 write!(f, "TIMEFORMAT")?;
                 if let Some(fmt) = fmt {
diff --git a/src/keywords.rs b/src/keywords.rs
index 35bf616d..319c5782 100644
--- a/src/keywords.rs
+++ b/src/keywords.rs
@@ -215,6 +215,7 @@ define_keywords!(
     COMMITTED,
     COMPATIBLE,
     COMPRESSION,
+    COMPUPDATE,
     COMPUTE,
     CONCURRENTLY,
     CONDITION,
@@ -749,6 +750,7 @@ define_keywords!(
     PRECISION,
     PREPARE,
     PRESERVE,
+    PRESET,
     PREWHERE,
     PRIMARY,
     PRINT,
@@ -801,6 +803,7 @@ define_keywords!(
     RELEASES,
     REMOTE,
     REMOVE,
+    REMOVEQUOTES,
     RENAME,
     REORG,
     REPAIR,
@@ -915,6 +918,7 @@ define_keywords!(
     STATS_AUTO_RECALC,
     STATS_PERSISTENT,
     STATS_SAMPLE_PAGES,
+    STATUPDATE,
     STATUS,
     STDDEV_POP,
     STDDEV_SAMP,
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index e1dd8c0e..b7d69f30 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -9741,6 +9741,7 @@ impl<'a> Parser<'a> {
             Keyword::BLANKSASNULL,
             Keyword::BZIP2,
             Keyword::CLEANPATH,
+            Keyword::COMPUPDATE,
             Keyword::CSV,
             Keyword::DATEFORMAT,
             Keyword::DELIMITER,
@@ -9761,7 +9762,9 @@ impl<'a> Parser<'a> {
             Keyword::PARQUET,
             Keyword::PARTITION,
             Keyword::REGION,
+            Keyword::REMOVEQUOTES,
             Keyword::ROWGROUPSIZE,
+            Keyword::STATUPDATE,
             Keyword::TIMEFORMAT,
             Keyword::TRUNCATECOLUMNS,
             Keyword::ZSTD,
@@ -9782,6 +9785,20 @@ impl<'a> Parser<'a> {
             Some(Keyword::BLANKSASNULL) => CopyLegacyOption::BlankAsNull,
             Some(Keyword::BZIP2) => CopyLegacyOption::Bzip2,
             Some(Keyword::CLEANPATH) => CopyLegacyOption::CleanPath,
+            Some(Keyword::COMPUPDATE) => {
+                let preset = self.parse_keyword(Keyword::PRESET);
+                let enabled = match self.parse_one_of_keywords(&[
+                    Keyword::TRUE,
+                    Keyword::FALSE,
+                    Keyword::ON,
+                    Keyword::OFF,
+                ]) {
+                    Some(Keyword::TRUE) | Some(Keyword::ON) => Some(true),
+                    Some(Keyword::FALSE) | Some(Keyword::OFF) => Some(false),
+                    _ => None,
+                };
+                CopyLegacyOption::CompUpdate { preset, enabled }
+            }
             Some(Keyword::CSV) => CopyLegacyOption::Csv({
                 let mut opts = vec![];
                 while let Some(opt) =
@@ -9870,11 +9887,25 @@ impl<'a> Parser<'a> {
                 let region = self.parse_literal_string()?;
                 CopyLegacyOption::Region(region)
             }
+            Some(Keyword::REMOVEQUOTES) => CopyLegacyOption::RemoveQuotes,
             Some(Keyword::ROWGROUPSIZE) => {
                 let _ = self.parse_keyword(Keyword::AS);
                 let file_size = self.parse_file_size()?;
                 CopyLegacyOption::RowGroupSize(file_size)
             }
+            Some(Keyword::STATUPDATE) => {
+                let enabled = match self.parse_one_of_keywords(&[
+                    Keyword::TRUE,
+                    Keyword::FALSE,
+                    Keyword::ON,
+                    Keyword::OFF,
+                ]) {
+                    Some(Keyword::TRUE) | Some(Keyword::ON) => Some(true),
+                    Some(Keyword::FALSE) | Some(Keyword::OFF) => Some(false),
+                    _ => None,
+                };
+                CopyLegacyOption::StatUpdate(enabled)
+            }
             Some(Keyword::TIMEFORMAT) => {
                 let _ = self.parse_keyword(Keyword::AS);
                 let fmt = if matches!(self.peek_token().token, 
Token::SingleQuotedString(_)) {
diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs
index 659b37ca..99b7ac3f 100644
--- a/tests/sqlparser_common.rs
+++ b/tests/sqlparser_common.rs
@@ -17126,7 +17126,19 @@ fn parse_copy_options() {
             "IAM_ROLE DEFAULT ",
             "IGNOREHEADER AS 1 ",
             "TIMEFORMAT AS 'auto' ",
-            "TRUNCATECOLUMNS",
+            "TRUNCATECOLUMNS ",
+            "REMOVEQUOTES ",
+            "COMPUPDATE ",
+            "COMPUPDATE PRESET ",
+            "COMPUPDATE ON ",
+            "COMPUPDATE OFF ",
+            "COMPUPDATE TRUE ",
+            "COMPUPDATE FALSE ",
+            "STATUPDATE ",
+            "STATUPDATE ON ",
+            "STATUPDATE OFF ",
+            "STATUPDATE TRUE ",
+            "STATUPDATE FALSE",
         ),
         concat!(
             "COPY dst (c1, c2, c3) FROM 
's3://redshift-downloads/tickit/category_pipe.txt' ",
@@ -17139,7 +17151,19 @@ fn parse_copy_options() {
             "IAM_ROLE DEFAULT ",
             "IGNOREHEADER 1 ",
             "TIMEFORMAT 'auto' ",
-            "TRUNCATECOLUMNS",
+            "TRUNCATECOLUMNS ",
+            "REMOVEQUOTES ",
+            "COMPUPDATE ",
+            "COMPUPDATE PRESET ",
+            "COMPUPDATE TRUE ",
+            "COMPUPDATE FALSE ",
+            "COMPUPDATE TRUE ",
+            "COMPUPDATE FALSE ",
+            "STATUPDATE ",
+            "STATUPDATE TRUE ",
+            "STATUPDATE FALSE ",
+            "STATUPDATE TRUE ",
+            "STATUPDATE FALSE",
         ),
     );
     one_statement_parses_to(


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

Reply via email to