From 65a8ee5a5e6c6ff8b0874fb3b39edecd81220b1f Mon Sep 17 00:00:00 2001 From: Andriy Romanov Date: Fri, 13 Mar 2026 11:26:19 -0700 Subject: [PATCH] Added encode, distkey, sortkey in attributes support for redshift --- src/ast/ddl.rs | 18 ++++++++++++++++++ src/ast/spans.rs | 3 +++ src/keywords.rs | 1 + src/parser/mod.rs | 6 ++++++ tests/sqlparser_redshift.rs | 14 ++++++++++++++ 5 files changed, 42 insertions(+) diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs index f0e79e739..27a32aa5f 100644 --- a/src/ast/ddl.rs +++ b/src/ast/ddl.rs @@ -2001,6 +2001,21 @@ pub enum ColumnOption { /// ``` /// [MySQL]: https://dev.mysql.com/doc/refman/8.4/en/invisible-columns.html Invisible, + /// Redshift specific: Column compression encoding + /// Syntax: `ENCODE encoding` + /// + /// [Redshift]: https://docs.aws.amazon.com/redshift/latest/dg/c_Compression_encodings.html + Encode(Ident), + /// Redshift specific: Column-level `DISTKEY` attribute + /// Syntax: `DISTKEY` + /// + /// [Redshift]: https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_TABLE_NEW.html + DistKey, + /// Redshift specific: Column-level `SORTKEY` attribute + /// Syntax: `SORTKEY` + /// + /// [Redshift]: https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_TABLE_NEW.html + SortKey, } impl From for ColumnOption { @@ -2150,6 +2165,9 @@ impl fmt::Display for ColumnOption { Invisible => { write!(f, "INVISIBLE") } + Encode(encoding) => write!(f, "ENCODE {encoding}"), + DistKey => write!(f, "DISTKEY"), + SortKey => write!(f, "SORTKEY"), } } } diff --git a/src/ast/spans.rs b/src/ast/spans.rs index 74f731a78..99eb53dc8 100644 --- a/src/ast/spans.rs +++ b/src/ast/spans.rs @@ -825,6 +825,9 @@ impl Spanned for ColumnOption { ColumnOption::Tags(..) => Span::empty(), ColumnOption::Srid(..) => Span::empty(), ColumnOption::Invisible => Span::empty(), + ColumnOption::Encode(_) => Span::empty(), + ColumnOption::DistKey => Span::empty(), + ColumnOption::SortKey => Span::empty(), } } } diff --git a/src/keywords.rs b/src/keywords.rs index 94458ccb4..6674fb5db 100644 --- a/src/keywords.rs +++ b/src/keywords.rs @@ -360,6 +360,7 @@ define_keywords!( EMPTYASNULL, ENABLE, ENABLE_SCHEMA_EVOLUTION, + ENCODE, ENCODING, ENCRYPTED, ENCRYPTION, diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 6adecb0c6..5b109e77e 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -9331,6 +9331,12 @@ impl<'a> Parser<'a> { ))) } else if self.parse_keyword(Keyword::INVISIBLE) { Ok(Some(ColumnOption::Invisible)) + } else if self.parse_keyword(Keyword::ENCODE) { + Ok(Some(ColumnOption::Encode(self.parse_identifier()?))) + } else if self.parse_keyword(Keyword::DISTKEY) { + Ok(Some(ColumnOption::DistKey)) + } else if self.parse_keyword(Keyword::SORTKEY) { + Ok(Some(ColumnOption::SortKey)) } else { Ok(None) } diff --git a/tests/sqlparser_redshift.rs b/tests/sqlparser_redshift.rs index 184aa5b69..0a0005af5 100644 --- a/tests/sqlparser_redshift.rs +++ b/tests/sqlparser_redshift.rs @@ -500,3 +500,17 @@ fn test_alter_table_alter_sortkey() { redshift().verified_stmt("ALTER TABLE users ALTER SORTKEY(created_at)"); redshift().verified_stmt("ALTER TABLE users ALTER SORTKEY(c1, c2)"); } + +#[test] +fn test_create_table_with_column_options() { + // Column-level ENCODE, DISTKEY, SORTKEY + redshift().verified_stmt( + "CREATE TABLE player_activity (date DATE ENCODE raw DISTKEY NOT NULL, userid INTEGER ENCODE az64 NOT NULL) DISTSTYLE KEY SORTKEY(date, userid)", + ); + + redshift().verified_stmt("CREATE TABLE t1 (c1 INT DISTKEY, c2 INT SORTKEY)"); + + redshift().verified_stmt( + "CREATE TABLE t1 (c1 INT ENCODE az64 NOT NULL, c2 VARCHAR(100) ENCODE lzo DEFAULT 'x')", + ); +}