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]