Skip to content

Commit f2c8f6a

Browse files
committed
Only set hive_formats on CreateTable if formats are present
Although the AST field was already an `Option`, we were setting it to `Some` all the time. Make `parse_hive_formats` return an `Option` and use that directly.
1 parent 2ceae00 commit f2c8f6a

File tree

6 files changed

+52
-46
lines changed

6 files changed

+52
-46
lines changed

src/dialect/snowflake.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ impl Dialect for SnowflakeDialect {
393393

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

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

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

693693
// Snowflake does not enforce order of the parameters in the statement. The parser needs to
694694
// parse the statement in a loop.

src/parser/mod.rs

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5831,15 +5831,19 @@ impl<'a> Parser<'a> {
58315831
let hive_distribution = self.parse_hive_distribution()?;
58325832
let hive_formats = self.parse_hive_formats()?;
58335833

5834-
let file_format = if let Some(ff) = &hive_formats.storage {
5835-
match ff {
5836-
HiveIOFormat::FileFormat { format } => Some(*format),
5837-
_ => None,
5834+
let file_format = if let Some(ref hf) = hive_formats {
5835+
if let Some(ref ff) = hf.storage {
5836+
match ff {
5837+
HiveIOFormat::FileFormat { format } => Some(*format),
5838+
_ => None,
5839+
}
5840+
} else {
5841+
None
58385842
}
58395843
} else {
58405844
None
58415845
};
5842-
let location = hive_formats.location.clone();
5846+
let location = hive_formats.as_ref().and_then(|hf| hf.location.clone());
58435847
let table_properties = self.parse_options(Keyword::TBLPROPERTIES)?;
58445848
let table_options = if !table_properties.is_empty() {
58455849
CreateTableOptions::TableProperties(table_properties)
@@ -5850,7 +5854,7 @@ impl<'a> Parser<'a> {
58505854
.columns(columns)
58515855
.constraints(constraints)
58525856
.hive_distribution(hive_distribution)
5853-
.hive_formats(Some(hive_formats))
5857+
.hive_formats(hive_formats)
58545858
.table_options(table_options)
58555859
.or_replace(or_replace)
58565860
.if_not_exists(if_not_exists)
@@ -7537,8 +7541,8 @@ impl<'a> Parser<'a> {
75377541
}
75387542
}
75397543

7540-
pub fn parse_hive_formats(&mut self) -> Result<HiveFormat, ParserError> {
7541-
let mut hive_format = HiveFormat::default();
7544+
pub fn parse_hive_formats(&mut self) -> Result<Option<HiveFormat>, ParserError> {
7545+
let mut hive_format: Option<HiveFormat> = None;
75427546
loop {
75437547
match self.parse_one_of_keywords(&[
75447548
Keyword::ROW,
@@ -7547,32 +7551,39 @@ impl<'a> Parser<'a> {
75477551
Keyword::WITH,
75487552
]) {
75497553
Some(Keyword::ROW) => {
7550-
hive_format.row_format = Some(self.parse_row_format()?);
7554+
hive_format
7555+
.get_or_insert_with(HiveFormat::default)
7556+
.row_format = Some(self.parse_row_format()?);
75517557
}
75527558
Some(Keyword::STORED) => {
75537559
self.expect_keyword_is(Keyword::AS)?;
75547560
if self.parse_keyword(Keyword::INPUTFORMAT) {
75557561
let input_format = self.parse_expr()?;
75567562
self.expect_keyword_is(Keyword::OUTPUTFORMAT)?;
75577563
let output_format = self.parse_expr()?;
7558-
hive_format.storage = Some(HiveIOFormat::IOF {
7559-
input_format,
7560-
output_format,
7561-
});
7564+
hive_format.get_or_insert_with(HiveFormat::default).storage =
7565+
Some(HiveIOFormat::IOF {
7566+
input_format,
7567+
output_format,
7568+
});
75627569
} else {
75637570
let format = self.parse_file_format()?;
7564-
hive_format.storage = Some(HiveIOFormat::FileFormat { format });
7571+
hive_format.get_or_insert_with(HiveFormat::default).storage =
7572+
Some(HiveIOFormat::FileFormat { format });
75657573
}
75667574
}
75677575
Some(Keyword::LOCATION) => {
7568-
hive_format.location = Some(self.parse_literal_string()?);
7576+
hive_format.get_or_insert_with(HiveFormat::default).location =
7577+
Some(self.parse_literal_string()?);
75697578
}
75707579
Some(Keyword::WITH) => {
75717580
self.prev_token();
75727581
let properties = self
75737582
.parse_options_with_keywords(&[Keyword::WITH, Keyword::SERDEPROPERTIES])?;
75747583
if !properties.is_empty() {
7575-
hive_format.serde_properties = Some(properties);
7584+
hive_format
7585+
.get_or_insert_with(HiveFormat::default)
7586+
.serde_properties = Some(properties);
75767587
} else {
75777588
break;
75787589
}
@@ -7787,7 +7798,7 @@ impl<'a> Parser<'a> {
77877798
.if_not_exists(if_not_exists)
77887799
.transient(transient)
77897800
.hive_distribution(hive_distribution)
7790-
.hive_formats(Some(hive_formats))
7801+
.hive_formats(hive_formats)
77917802
.global(global)
77927803
.query(query)
77937804
.without_rowid(without_rowid)

tests/sqlparser_common.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4724,6 +4724,21 @@ fn parse_create_external_table_lowercase() {
47244724
assert_matches!(ast, Statement::CreateTable(CreateTable { .. }));
47254725
}
47264726

4727+
#[test]
4728+
fn parse_create_table_hive_formats_none_when_no_options() {
4729+
// Test that hive_formats is None when no Hive format options are specified
4730+
let sql = "CREATE TABLE simple_table (id INT, name VARCHAR(100))";
4731+
match verified_stmt(sql) {
4732+
Statement::CreateTable(CreateTable { hive_formats, .. }) => {
4733+
assert_eq!(
4734+
hive_formats, None,
4735+
"hive_formats should be None when no Hive format options are specified"
4736+
);
4737+
}
4738+
_ => unreachable!(),
4739+
}
4740+
}
4741+
47274742
#[test]
47284743
fn parse_alter_table() {
47294744
let add_column = "ALTER TABLE tab ADD COLUMN foo TEXT;";

tests/sqlparser_duckdb.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -739,12 +739,7 @@ fn test_duckdb_union_datatype() {
739739
],
740740
constraints: Default::default(),
741741
hive_distribution: HiveDistributionStyle::NONE,
742-
hive_formats: Some(HiveFormat {
743-
row_format: Default::default(),
744-
serde_properties: Default::default(),
745-
storage: Default::default(),
746-
location: Default::default()
747-
}),
742+
hive_formats: None,
748743
file_format: Default::default(),
749744
location: Default::default(),
750745
query: Default::default(),

tests/sqlparser_mssql.rs

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1881,12 +1881,7 @@ fn parse_create_table_with_valid_options() {
18811881
],
18821882
constraints: vec![],
18831883
hive_distribution: HiveDistributionStyle::NONE,
1884-
hive_formats: Some(HiveFormat {
1885-
row_format: None,
1886-
serde_properties: None,
1887-
storage: None,
1888-
location: None,
1889-
},),
1884+
hive_formats: None,
18901885
file_format: None,
18911886
location: None,
18921887
query: None,
@@ -2053,12 +2048,7 @@ fn parse_create_table_with_identity_column() {
20532048
},],
20542049
constraints: vec![],
20552050
hive_distribution: HiveDistributionStyle::NONE,
2056-
hive_formats: Some(HiveFormat {
2057-
row_format: None,
2058-
serde_properties: None,
2059-
storage: None,
2060-
location: None,
2061-
},),
2051+
hive_formats: None,
20622052
file_format: None,
20632053
location: None,
20642054
query: None,

tests/sqlparser_postgres.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6015,12 +6015,7 @@ fn parse_trigger_related_functions() {
60156015
],
60166016
constraints: vec![],
60176017
hive_distribution: HiveDistributionStyle::NONE,
6018-
hive_formats: Some(HiveFormat {
6019-
row_format: None,
6020-
serde_properties: None,
6021-
storage: None,
6022-
location: None
6023-
}),
6018+
hive_formats: None,
60246019
file_format: None,
60256020
location: None,
60266021
query: None,

0 commit comments

Comments
 (0)