Skip to content

Commit 2094afc

Browse files
committed
Redshift: Add support for IAM_ROLE and IGNOREHEADER COPY options
1 parent 60a5c8d commit 2094afc

File tree

4 files changed

+58
-1
lines changed

4 files changed

+58
-1
lines changed

src/ast/mod.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8772,6 +8772,10 @@ pub enum CopyLegacyOption {
87728772
Null(String),
87738773
/// CSV ...
87748774
Csv(Vec<CopyLegacyCsvOption>),
8775+
/// IAM_ROLE { DEFAULT | 'arn:aws:iam::AWS_ACCOUNT_ID:role/ROLE_NAME' }
8776+
IamRole(Option<String>),
8777+
/// IGNOREHEADER \[ AS \] number_rows
8778+
IgnoreHeader(u64),
87758779
}
87768780

87778781
impl fmt::Display for CopyLegacyOption {
@@ -8781,7 +8785,21 @@ impl fmt::Display for CopyLegacyOption {
87818785
Binary => write!(f, "BINARY"),
87828786
Delimiter(char) => write!(f, "DELIMITER '{char}'"),
87838787
Null(string) => write!(f, "NULL '{}'", value::escape_single_quote_string(string)),
8784-
Csv(opts) => write!(f, "CSV {}", display_separated(opts, " ")),
8788+
Csv(opts) => {
8789+
write!(f, "CSV")?;
8790+
if !opts.is_empty() {
8791+
write!(f, " {}", display_separated(opts, " "))?;
8792+
}
8793+
Ok(())
8794+
}
8795+
IamRole(role) => {
8796+
write!(f, "IAM_ROLE")?;
8797+
match role {
8798+
Some(role) => write!(f, " '{role}'"),
8799+
None => write!(f, " default"),
8800+
}
8801+
}
8802+
IgnoreHeader(num_rows) => write!(f, "IGNOREHEADER {num_rows}"),
87858803
}
87868804
}
87878805
}

src/keywords.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,12 +427,14 @@ define_keywords!(
427427
HOUR,
428428
HOURS,
429429
HUGEINT,
430+
IAM_ROLE,
430431
ICEBERG,
431432
ID,
432433
IDENTITY,
433434
IDENTITY_INSERT,
434435
IF,
435436
IGNORE,
437+
IGNOREHEADER,
436438
ILIKE,
437439
IMMEDIATE,
438440
IMMUTABLE,

src/parser/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9509,6 +9509,8 @@ impl<'a> Parser<'a> {
95099509
Keyword::DELIMITER,
95109510
Keyword::NULL,
95119511
Keyword::CSV,
9512+
Keyword::IAM_ROLE,
9513+
Keyword::IGNOREHEADER,
95129514
]) {
95139515
Some(Keyword::BINARY) => CopyLegacyOption::Binary,
95149516
Some(Keyword::DELIMITER) => {
@@ -9528,6 +9530,19 @@ impl<'a> Parser<'a> {
95289530
}
95299531
opts
95309532
}),
9533+
Some(Keyword::IAM_ROLE) => {
9534+
if self.parse_keyword(Keyword::DEFAULT) {
9535+
CopyLegacyOption::IamRole(None)
9536+
} else {
9537+
let role = self.parse_literal_string()?;
9538+
CopyLegacyOption::IamRole(Some(role))
9539+
}
9540+
}
9541+
Some(Keyword::IGNOREHEADER) => {
9542+
let _ = self.parse_keyword(Keyword::AS);
9543+
let num_rows = self.parse_literal_uint()?;
9544+
CopyLegacyOption::IgnoreHeader(num_rows)
9545+
}
95319546
_ => self.expected("option", self.peek_token())?,
95329547
};
95339548
Ok(ret)

tests/sqlparser_common.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16655,3 +16655,25 @@ fn test_parse_default_with_collate_column_option() {
1665516655
panic!("Expected create table statement");
1665616656
}
1665716657
}
16658+
16659+
#[test]
16660+
fn pares_copy_options() {
16661+
let copy = verified_stmt(
16662+
r#"COPY dst (c1, c2, c3) FROM 's3://redshift-downloads/tickit/category_pipe.txt' IAM_ROLE 'arn:aws:iam::123456789:role/role1' CSV IGNOREHEADER 1"#,
16663+
);
16664+
match copy {
16665+
Statement::Copy { legacy_options, .. } => {
16666+
assert_eq!(
16667+
legacy_options,
16668+
vec![
16669+
CopyLegacyOption::IamRole(Some(
16670+
"arn:aws:iam::123456789:role/role1".to_string()
16671+
)),
16672+
CopyLegacyOption::Csv(vec![]),
16673+
CopyLegacyOption::IgnoreHeader(1),
16674+
]
16675+
);
16676+
}
16677+
_ => unreachable!(),
16678+
}
16679+
}

0 commit comments

Comments
 (0)