From 420471ebbd0e9c95462872c5bd9cec36b294104f Mon Sep 17 00:00:00 2001 From: Andriy Romanov Date: Tue, 3 Mar 2026 17:06:03 -0800 Subject: [PATCH] Fix parsing CREDENTIALS keyword for redshift --- src/ast/mod.rs | 4 ++++ src/parser/mod.rs | 4 ++++ tests/sqlparser_redshift.rs | 7 +++++++ 3 files changed, 15 insertions(+) diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 6a2f9bd96..e201f7842 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -9217,6 +9217,9 @@ pub enum CopyLegacyOption { TruncateColumns, /// ZSTD Zstd, + /// Redshift `CREDENTIALS 'auth-args'` + /// + Credentials(String), } impl fmt::Display for CopyLegacyOption { @@ -9327,6 +9330,7 @@ impl fmt::Display for CopyLegacyOption { } TruncateColumns => write!(f, "TRUNCATECOLUMNS"), Zstd => write!(f, "ZSTD"), + Credentials(s) => write!(f, "CREDENTIALS '{}'", value::escape_single_quote_string(s)), } } } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 2749969c0..094d6ed47 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -11176,6 +11176,7 @@ impl<'a> Parser<'a> { Keyword::BZIP2, Keyword::CLEANPATH, Keyword::COMPUPDATE, + Keyword::CREDENTIALS, Keyword::CSV, Keyword::DATEFORMAT, Keyword::DELIMITER, @@ -11233,6 +11234,9 @@ impl<'a> Parser<'a> { }; CopyLegacyOption::CompUpdate { preset, enabled } } + Some(Keyword::CREDENTIALS) => { + CopyLegacyOption::Credentials(self.parse_literal_string()?) + } Some(Keyword::CSV) => CopyLegacyOption::Csv({ let mut opts = vec![]; while let Some(opt) = diff --git a/tests/sqlparser_redshift.rs b/tests/sqlparser_redshift.rs index 03dfda2c0..243b0646c 100644 --- a/tests/sqlparser_redshift.rs +++ b/tests/sqlparser_redshift.rs @@ -467,3 +467,10 @@ fn test_create_table_diststyle() { redshift().verified_stmt("CREATE TABLE t1 (c1 INT) DISTSTYLE KEY DISTKEY(c1)"); redshift().verified_stmt("CREATE TABLE t1 (c1 INT) DISTSTYLE ALL"); } + +#[test] +fn test_copy_credentials() { + redshift().verified_stmt( + "COPY t1 FROM 's3://bucket/file.csv' CREDENTIALS 'aws_access_key_id=AK;aws_secret_access_key=SK' CSV", + ); +}