Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/dialect/snowflake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ impl Dialect for SnowflakeDialect {

fn is_column_alias(&self, kw: &Keyword, parser: &mut Parser) -> bool {
match kw {
// The following keywords can be considered an alias as long as
// The following keywords can be considered an alias as long as
// they are not followed by other tokens that may change their meaning
// e.g. `SELECT * EXCEPT (col1) FROM tbl`
Keyword::EXCEPT
Expand All @@ -408,7 +408,7 @@ impl Dialect for SnowflakeDialect {
Keyword::LIMIT | Keyword::OFFSET if peek_for_limit_options(parser) => false,

// `FETCH` can be considered an alias as long as it's not followed by `FIRST`` or `NEXT`
// which would give it a different meanings, for example:
// which would give it a different meanings, for example:
// `SELECT 1 FETCH FIRST 10 ROWS` - not an alias
// `SELECT 1 FETCH 10` - not an alias
Keyword::FETCH if parser.peek_one_of_keywords(&[Keyword::FIRST, Keyword::NEXT]).is_some()
Expand All @@ -417,8 +417,8 @@ impl Dialect for SnowflakeDialect {
false
}

// Reserved keywords by the Snowflake dialect, which seem to be less strictive
// than what is listed in `keywords::RESERVED_FOR_COLUMN_ALIAS`. The following
// Reserved keywords by the Snowflake dialect, which seem to be less strictive
// than what is listed in `keywords::RESERVED_FOR_COLUMN_ALIAS`. The following
// keywords were tested with the this statement: `SELECT 1 <KW>`.
Keyword::FROM
| Keyword::GROUP
Expand Down Expand Up @@ -688,7 +688,7 @@ pub fn parse_create_table(
.iceberg(iceberg)
.global(global)
.dynamic(dynamic)
.hive_formats(Some(Default::default()));
.hive_formats(None);

// Snowflake does not enforce order of the parameters in the statement. The parser needs to
// parse the statement in a loop.
Expand Down
45 changes: 28 additions & 17 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5831,15 +5831,19 @@ impl<'a> Parser<'a> {
let hive_distribution = self.parse_hive_distribution()?;
let hive_formats = self.parse_hive_formats()?;

let file_format = if let Some(ff) = &hive_formats.storage {
match ff {
HiveIOFormat::FileFormat { format } => Some(*format),
_ => None,
let file_format = if let Some(ref hf) = hive_formats {
if let Some(ref ff) = hf.storage {
match ff {
HiveIOFormat::FileFormat { format } => Some(*format),
_ => None,
}
} else {
None
}
} else {
None
};
let location = hive_formats.location.clone();
let location = hive_formats.as_ref().and_then(|hf| hf.location.clone());
let table_properties = self.parse_options(Keyword::TBLPROPERTIES)?;
let table_options = if !table_properties.is_empty() {
CreateTableOptions::TableProperties(table_properties)
Expand All @@ -5850,7 +5854,7 @@ impl<'a> Parser<'a> {
.columns(columns)
.constraints(constraints)
.hive_distribution(hive_distribution)
.hive_formats(Some(hive_formats))
.hive_formats(hive_formats)
.table_options(table_options)
.or_replace(or_replace)
.if_not_exists(if_not_exists)
Expand Down Expand Up @@ -7537,8 +7541,8 @@ impl<'a> Parser<'a> {
}
}

pub fn parse_hive_formats(&mut self) -> Result<HiveFormat, ParserError> {
let mut hive_format = HiveFormat::default();
pub fn parse_hive_formats(&mut self) -> Result<Option<HiveFormat>, ParserError> {
let mut hive_format: Option<HiveFormat> = None;
loop {
match self.parse_one_of_keywords(&[
Keyword::ROW,
Expand All @@ -7547,32 +7551,39 @@ impl<'a> Parser<'a> {
Keyword::WITH,
]) {
Some(Keyword::ROW) => {
hive_format.row_format = Some(self.parse_row_format()?);
hive_format
.get_or_insert_with(HiveFormat::default)
.row_format = Some(self.parse_row_format()?);
}
Some(Keyword::STORED) => {
self.expect_keyword_is(Keyword::AS)?;
if self.parse_keyword(Keyword::INPUTFORMAT) {
let input_format = self.parse_expr()?;
self.expect_keyword_is(Keyword::OUTPUTFORMAT)?;
let output_format = self.parse_expr()?;
hive_format.storage = Some(HiveIOFormat::IOF {
input_format,
output_format,
});
hive_format.get_or_insert_with(HiveFormat::default).storage =
Some(HiveIOFormat::IOF {
input_format,
output_format,
});
} else {
let format = self.parse_file_format()?;
hive_format.storage = Some(HiveIOFormat::FileFormat { format });
hive_format.get_or_insert_with(HiveFormat::default).storage =
Some(HiveIOFormat::FileFormat { format });
}
}
Some(Keyword::LOCATION) => {
hive_format.location = Some(self.parse_literal_string()?);
hive_format.get_or_insert_with(HiveFormat::default).location =
Some(self.parse_literal_string()?);
}
Some(Keyword::WITH) => {
self.prev_token();
let properties = self
.parse_options_with_keywords(&[Keyword::WITH, Keyword::SERDEPROPERTIES])?;
if !properties.is_empty() {
hive_format.serde_properties = Some(properties);
hive_format
.get_or_insert_with(HiveFormat::default)
.serde_properties = Some(properties);
} else {
break;
}
Expand Down Expand Up @@ -7787,7 +7798,7 @@ impl<'a> Parser<'a> {
.if_not_exists(if_not_exists)
.transient(transient)
.hive_distribution(hive_distribution)
.hive_formats(Some(hive_formats))
.hive_formats(hive_formats)
.global(global)
.query(query)
.without_rowid(without_rowid)
Expand Down
11 changes: 11 additions & 0 deletions tests/sqlparser_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4724,6 +4724,17 @@ fn parse_create_external_table_lowercase() {
assert_matches!(ast, Statement::CreateTable(CreateTable { .. }));
}

#[test]
fn parse_create_table_hive_formats_none_when_no_options() {
let sql = "CREATE TABLE simple_table (id INT, name VARCHAR(100))";
match verified_stmt(sql) {
Statement::CreateTable(CreateTable { hive_formats, .. }) => {
assert_eq!(hive_formats, None);
}
_ => unreachable!(),
}
}

#[test]
fn parse_alter_table() {
let add_column = "ALTER TABLE tab ADD COLUMN foo TEXT;";
Expand Down
7 changes: 1 addition & 6 deletions tests/sqlparser_duckdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -739,12 +739,7 @@ fn test_duckdb_union_datatype() {
],
constraints: Default::default(),
hive_distribution: HiveDistributionStyle::NONE,
hive_formats: Some(HiveFormat {
row_format: Default::default(),
serde_properties: Default::default(),
storage: Default::default(),
location: Default::default()
}),
hive_formats: None,
file_format: Default::default(),
location: Default::default(),
query: Default::default(),
Expand Down
14 changes: 2 additions & 12 deletions tests/sqlparser_mssql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1881,12 +1881,7 @@ fn parse_create_table_with_valid_options() {
],
constraints: vec![],
hive_distribution: HiveDistributionStyle::NONE,
hive_formats: Some(HiveFormat {
row_format: None,
serde_properties: None,
storage: None,
location: None,
},),
hive_formats: None,
file_format: None,
location: None,
query: None,
Expand Down Expand Up @@ -2053,12 +2048,7 @@ fn parse_create_table_with_identity_column() {
},],
constraints: vec![],
hive_distribution: HiveDistributionStyle::NONE,
hive_formats: Some(HiveFormat {
row_format: None,
serde_properties: None,
storage: None,
location: None,
},),
hive_formats: None,
file_format: None,
location: None,
query: None,
Expand Down
7 changes: 1 addition & 6 deletions tests/sqlparser_postgres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6015,12 +6015,7 @@ fn parse_trigger_related_functions() {
],
constraints: vec![],
hive_distribution: HiveDistributionStyle::NONE,
hive_formats: Some(HiveFormat {
row_format: None,
serde_properties: None,
storage: None,
location: None
}),
hive_formats: None,
file_format: None,
location: None,
query: None,
Expand Down