Skip to content

Commit e2a3470

Browse files
committed
fix: change token consumption to pick to test on EOF in parser
If we use `next_token(...)` then in the case of multi-statement query it consumes a semicolon token which leads to the parse error on the correct queries like: ```sql CREATE EXTERNAL TABLE t1 ...; CREATE EXTERNAL TABLE t2 ...; ```
1 parent 0c82ade commit e2a3470

File tree

1 file changed

+44
-2
lines changed

1 file changed

+44
-2
lines changed

datafusion/sql/src/parser.rs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ impl<'a> DFParser<'a> {
658658
}
659659
}
660660
} else {
661-
let token = self.parser.next_token();
661+
let token = self.parser.peek_token();
662662
if token == Token::EOF || token == Token::SemiColon {
663663
break;
664664
} else {
@@ -1079,7 +1079,7 @@ impl<'a> DFParser<'a> {
10791079
}
10801080
}
10811081
} else {
1082-
let token = self.parser.next_token();
1082+
let token = self.parser.peek_token();
10831083
if token == Token::EOF || token == Token::SemiColon {
10841084
break;
10851085
} else {
@@ -2026,6 +2026,48 @@ mod tests {
20262026
);
20272027
}
20282028

2029+
#[test]
2030+
fn test_multistatement() {
2031+
let sql = "COPY foo TO bar STORED AS CSV; \
2032+
CREATE EXTERNAL TABLE t(c1 int) STORED AS CSV LOCATION 'foo.csv'; \
2033+
RESET var;";
2034+
let statements = DFParser::parse_sql(sql).unwrap();
2035+
assert_eq!(
2036+
statements,
2037+
vec![
2038+
Statement::CopyTo(CopyToStatement {
2039+
source: object_name("foo"),
2040+
target: "bar".to_string(),
2041+
partitioned_by: vec![],
2042+
stored_as: Some("CSV".to_owned()),
2043+
options: vec![],
2044+
}),
2045+
{
2046+
let name = ObjectName::from(vec![Ident::from("t")]);
2047+
let display = None;
2048+
Statement::CreateExternalTable(CreateExternalTable {
2049+
name: name.clone(),
2050+
columns: vec![make_column_def("c1", DataType::Int(display))],
2051+
file_type: "CSV".to_string(),
2052+
location: "foo.csv".into(),
2053+
table_partition_cols: vec![],
2054+
order_exprs: vec![],
2055+
if_not_exists: false,
2056+
or_replace: false,
2057+
temporary: false,
2058+
unbounded: false,
2059+
options: vec![],
2060+
constraints: vec![],
2061+
})
2062+
},
2063+
{
2064+
let name = ObjectName::from(vec![Ident::from("var")]);
2065+
Statement::Reset(ResetStatement::Variable(name))
2066+
}
2067+
]
2068+
);
2069+
}
2070+
20292071
fn expect_parse_expr_ok(sql: &str, expected: ExprWithAlias) {
20302072
let expr = DFParser::parse_sql_into_expr(sql).unwrap();
20312073
assert_eq!(expr, expected, "actual:\n{expr:#?}");

0 commit comments

Comments
 (0)