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
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,11 @@ create EXTERNAL TABLE t(c1 int, c2 int) STORED AS CSV PARTITIONED BY (c1) partit
# Duplicate `OPTIONS` clause
statement error DataFusion error: SQL error: ParserError\("OPTIONS specified more than once"\)
CREATE EXTERNAL TABLE t STORED AS CSV OPTIONS ('k1' 'v1', 'k2' 'v2') OPTIONS ('k3' 'v3') LOCATION 'foo.csv'

# With typo error
statement error DataFusion error: SQL error: ParserError\("Expected HEADER, found: HEAD"\)
CREATE EXTERNAL TABLE t(c1 int) STORED AS CSV WITH HEAD ROW LOCATION 'foo.csv';

# Missing `anything` in WITH clause
statement error DataFusion error: SQL error: ParserError\("Expected HEADER, found: LOCATION"\)
CREATE EXTERNAL TABLE t(c1 int) STORED AS CSV WITH LOCATION 'foo.csv';
20 changes: 10 additions & 10 deletions datafusion/sql/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,16 +434,16 @@ impl<'a> DFParser<'a> {
} else if self.parser.parse_keyword(Keyword::LOCATION) {
ensure_not_set(&builder.location, "LOCATION")?;
builder.location = Some(self.parser.parse_literal_string()?);
} else if self
.parser
.parse_keywords(&[Keyword::WITH, Keyword::HEADER])
{
self.parser.expect_keyword(Keyword::ROW)?;
ensure_not_set(&builder.has_header, "WITH HEADER ROW")?;
builder.has_header = Some(true);
} else if self.parser.parse_keywords(&[Keyword::WITH, Keyword::ORDER]) {
ensure_not_set(&builder.order_exprs, "WITH ORDER")?;
builder.order_exprs = Some(self.parse_order_by_exprs()?);
} else if self.parser.parse_keyword(Keyword::WITH) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about using @tz70s 's suggestion at #6257 (comment)

https://docs.rs/sqlparser/0.33.0/sqlparser/parser/struct.Parser.html#method.expect_one_of_keywords

Here is an example of how it could be used: https://github.com/sqlparser-rs/sqlparser-rs/blob/b29b551fa111bbd50c40568f6aea6c49eafc0b9c/src/parser.rs#L6559-L6562

That would also produce an error message that told the user what keywords were expected and what was actually received

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I will use it, Thanks

if self.parser.parse_keyword(Keyword::ORDER) {
ensure_not_set(&builder.order_exprs, "WITH ORDER")?;
builder.order_exprs = Some(self.parse_order_by_exprs()?);
} else {
self.parser.expect_keyword(Keyword::HEADER)?;
self.parser.expect_keyword(Keyword::ROW)?;
ensure_not_set(&builder.has_header, "WITH HEADER ROW")?;
builder.has_header = Some(true);
}
} else if self.parser.parse_keyword(Keyword::DELIMITER) {
ensure_not_set(&builder.delimiter, "DELIMITER")?;
builder.delimiter = Some(self.parse_delimiter()?);
Expand Down