Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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' }
Expand Down Expand Up @@ -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
Expand All @@ -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() {
Expand Down Expand Up @@ -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 {
Expand Down
4 changes: 4 additions & 0 deletions src/keywords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ define_keywords!(
COMMITTED,
COMPATIBLE,
COMPRESSION,
COMPUPDATE,
COMPUTE,
CONCURRENTLY,
CONDITION,
Expand Down Expand Up @@ -749,6 +750,7 @@ define_keywords!(
PRECISION,
PREPARE,
PRESERVE,
PRESET,
PREWHERE,
PRIMARY,
PRINT,
Expand Down Expand Up @@ -801,6 +803,7 @@ define_keywords!(
RELEASES,
REMOTE,
REMOVE,
REMOVEQUOTES,
RENAME,
REORG,
REPAIR,
Expand Down Expand Up @@ -915,6 +918,7 @@ define_keywords!(
STATS_AUTO_RECALC,
STATS_PERSISTENT,
STATS_SAMPLE_PAGES,
STATUPDATE,
STATUS,
STDDEV_POP,
STDDEV_SAMP,
Expand Down
31 changes: 31 additions & 0 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9741,6 +9741,7 @@ impl<'a> Parser<'a> {
Keyword::BLANKSASNULL,
Keyword::BZIP2,
Keyword::CLEANPATH,
Keyword::COMPUPDATE,
Keyword::CSV,
Keyword::DATEFORMAT,
Keyword::DELIMITER,
Expand All @@ -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,
Expand All @@ -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) =
Expand Down Expand Up @@ -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(_)) {
Expand Down
28 changes: 26 additions & 2 deletions tests/sqlparser_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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' ",
Expand All @@ -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(
Expand Down