Skip to content

Commit cdba474

Browse files
committed
Redshift: Add support for IAM_ROLE and IGNOREHEADER COPY options
1 parent 12c0878 commit cdba474

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
@@ -429,12 +429,14 @@ define_keywords!(
429429
HOUR,
430430
HOURS,
431431
HUGEINT,
432+
IAM_ROLE,
432433
ICEBERG,
433434
ID,
434435
IDENTITY,
435436
IDENTITY_INSERT,
436437
IF,
437438
IGNORE,
439+
IGNOREHEADER,
438440
ILIKE,
439441
IMMEDIATE,
440442
IMMUTABLE,

src/parser/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9548,6 +9548,8 @@ impl<'a> Parser<'a> {
95489548
Keyword::DELIMITER,
95499549
Keyword::NULL,
95509550
Keyword::CSV,
9551+
Keyword::IAM_ROLE,
9552+
Keyword::IGNOREHEADER,
95519553
]) {
95529554
Some(Keyword::BINARY) => CopyLegacyOption::Binary,
95539555
Some(Keyword::DELIMITER) => {
@@ -9567,6 +9569,19 @@ impl<'a> Parser<'a> {
95679569
}
95689570
opts
95699571
}),
9572+
Some(Keyword::IAM_ROLE) => {
9573+
if self.parse_keyword(Keyword::DEFAULT) {
9574+
CopyLegacyOption::IamRole(None)
9575+
} else {
9576+
let role = self.parse_literal_string()?;
9577+
CopyLegacyOption::IamRole(Some(role))
9578+
}
9579+
}
9580+
Some(Keyword::IGNOREHEADER) => {
9581+
let _ = self.parse_keyword(Keyword::AS);
9582+
let num_rows = self.parse_literal_uint()?;
9583+
CopyLegacyOption::IgnoreHeader(num_rows)
9584+
}
95709585
_ => self.expected("option", self.peek_token())?,
95719586
};
95729587
Ok(ret)

tests/sqlparser_common.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16729,3 +16729,25 @@ fn parse_create_table_like() {
1672916729
_ => unreachable!(),
1673016730
}
1673116731
}
16732+
16733+
#[test]
16734+
fn pares_copy_options() {
16735+
let copy = verified_stmt(
16736+
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"#,
16737+
);
16738+
match copy {
16739+
Statement::Copy { legacy_options, .. } => {
16740+
assert_eq!(
16741+
legacy_options,
16742+
vec![
16743+
CopyLegacyOption::IamRole(Some(
16744+
"arn:aws:iam::123456789:role/role1".to_string()
16745+
)),
16746+
CopyLegacyOption::Csv(vec![]),
16747+
CopyLegacyOption::IgnoreHeader(1),
16748+
]
16749+
);
16750+
}
16751+
_ => unreachable!(),
16752+
}
16753+
}

0 commit comments

Comments
 (0)