This is an automated email from the ASF dual-hosted git repository.

github-bot pushed a commit to branch 
gh-readonly-queue/main/pr-2141-3af9988c432e3dae1a2343d60e64394f3ad9fa42
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git

commit d80c0b9b6c8bcbfe880e60daa1957674f0fcaa09
Author: Yoav Cohen <[email protected]>
AuthorDate: Fri Jan 9 10:20:21 2026 +0100

    Redshift: Add support for optional JSON format in copy option (#2141)
---
 src/ast/mod.rs            | 12 +++++++++---
 src/parser/mod.rs         | 10 +++++++++-
 tests/sqlparser_common.rs |  6 ++++++
 3 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/src/ast/mod.rs b/src/ast/mod.rs
index c8d9c6be..114dee11 100644
--- a/src/ast/mod.rs
+++ b/src/ast/mod.rs
@@ -8296,8 +8296,8 @@ pub enum CopyLegacyOption {
     IamRole(IamRoleKind),
     /// IGNOREHEADER \[ AS \] number_rows
     IgnoreHeader(u64),
-    /// JSON
-    Json,
+    /// JSON \[ AS \] 'json_option'
+    Json(Option<String>),
     /// MANIFEST \[ VERBOSE \]
     Manifest { verbose: bool },
     /// MAXFILESIZE \[ AS \] max-size \[ MB | GB \]
@@ -8388,7 +8388,13 @@ impl fmt::Display for CopyLegacyOption {
             Header => write!(f, "HEADER"),
             IamRole(role) => write!(f, "IAM_ROLE {role}"),
             IgnoreHeader(num_rows) => write!(f, "IGNOREHEADER {num_rows}"),
-            Json => write!(f, "JSON"),
+            Json(opt) => {
+                write!(f, "JSON")?;
+                if let Some(opt) = opt {
+                    write!(f, " AS '{}'", 
value::escape_single_quote_string(opt))?;
+                }
+                Ok(())
+            }
             Manifest { verbose } => write!(f, "MANIFEST{}", if *verbose { " 
VERBOSE" } else { "" }),
             MaxFileSize(file_size) => write!(f, "MAXFILESIZE {file_size}"),
             Null(string) => write!(f, "NULL '{}'", 
value::escape_single_quote_string(string)),
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 3294acf6..3a31d925 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -10747,7 +10747,15 @@ impl<'a> Parser<'a> {
                 let num_rows = self.parse_literal_uint()?;
                 CopyLegacyOption::IgnoreHeader(num_rows)
             }
-            Some(Keyword::JSON) => CopyLegacyOption::Json,
+            Some(Keyword::JSON) => {
+                let _ = self.parse_keyword(Keyword::AS);
+                let fmt = if matches!(self.peek_token().token, 
Token::SingleQuotedString(_)) {
+                    Some(self.parse_literal_string()?)
+                } else {
+                    None
+                };
+                CopyLegacyOption::Json(fmt)
+            }
             Some(Keyword::MANIFEST) => {
                 let verbose = self.parse_keyword(Keyword::VERBOSE);
                 CopyLegacyOption::Manifest { verbose }
diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs
index 365bddb0..9ed59eac 100644
--- a/tests/sqlparser_common.rs
+++ b/tests/sqlparser_common.rs
@@ -17421,6 +17421,9 @@ fn parse_copy_options() {
             "EMPTYASNULL ",
             "IAM_ROLE DEFAULT ",
             "IGNOREHEADER AS 1 ",
+            "JSON ",
+            "JSON 'auto' ",
+            "JSON AS 'auto' ",
             "TIMEFORMAT AS 'auto' ",
             "TRUNCATECOLUMNS ",
             "REMOVEQUOTES ",
@@ -17446,6 +17449,9 @@ fn parse_copy_options() {
             "EMPTYASNULL ",
             "IAM_ROLE DEFAULT ",
             "IGNOREHEADER 1 ",
+            "JSON ",
+            "JSON AS 'auto' ",
+            "JSON AS 'auto' ",
             "TIMEFORMAT 'auto' ",
             "TRUNCATECOLUMNS ",
             "REMOVEQUOTES ",


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to