Skip to content

Commit 43295c8

Browse files
committed
Redshift: Add support for IAM_ROLE and IGNOREHEADER COPY options
1 parent b2f9773 commit 43295c8

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
@@ -9508,6 +9508,8 @@ impl<'a> Parser<'a> {
95089508
Keyword::DELIMITER,
95099509
Keyword::NULL,
95109510
Keyword::CSV,
9511+
Keyword::IAM_ROLE,
9512+
Keyword::IGNOREHEADER,
95119513
]) {
95129514
Some(Keyword::BINARY) => CopyLegacyOption::Binary,
95139515
Some(Keyword::DELIMITER) => {
@@ -9527,6 +9529,19 @@ impl<'a> Parser<'a> {
95279529
}
95289530
opts
95299531
}),
9532+
Some(Keyword::IAM_ROLE) => {
9533+
if self.parse_keyword(Keyword::DEFAULT) {
9534+
CopyLegacyOption::IamRole(None)
9535+
} else {
9536+
let role = self.parse_literal_string()?;
9537+
CopyLegacyOption::IamRole(Some(role))
9538+
}
9539+
}
9540+
Some(Keyword::IGNOREHEADER) => {
9541+
let _ = self.parse_keyword(Keyword::AS);
9542+
let num_rows = self.parse_literal_uint()?;
9543+
CopyLegacyOption::IgnoreHeader(num_rows)
9544+
}
95309545
_ => self.expected("option", self.peek_token())?,
95319546
};
95329547
Ok(ret)

tests/sqlparser_common.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16598,3 +16598,25 @@ fn parse_create_view_if_not_exists() {
1659816598
res.unwrap_err()
1659916599
);
1660016600
}
16601+
16602+
#[test]
16603+
fn pares_copy_options() {
16604+
let copy = verified_stmt(
16605+
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"#,
16606+
);
16607+
match copy {
16608+
Statement::Copy { legacy_options, .. } => {
16609+
assert_eq!(
16610+
legacy_options,
16611+
vec![
16612+
CopyLegacyOption::IamRole(Some(
16613+
"arn:aws:iam::123456789:role/role1".to_string()
16614+
)),
16615+
CopyLegacyOption::Csv(vec![]),
16616+
CopyLegacyOption::IgnoreHeader(1),
16617+
]
16618+
);
16619+
}
16620+
_ => unreachable!(),
16621+
}
16622+
}

0 commit comments

Comments
 (0)