Skip to content

Commit 3db7fba

Browse files
committed
Fix not treating GO as a statement delimiter next to a query
1 parent f4750f0 commit 3db7fba

File tree

3 files changed

+49
-11
lines changed

3 files changed

+49
-11
lines changed

src/dialect/mssql.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::ast::{
2222
use crate::dialect::Dialect;
2323
use crate::keywords::{self, Keyword};
2424
use crate::parser::{Parser, ParserError};
25-
use crate::tokenizer::Token;
25+
use crate::tokenizer::{Token, Whitespace};
2626
#[cfg(not(feature = "std"))]
2727
use alloc::{vec, vec::Vec};
2828

@@ -118,7 +118,29 @@ impl Dialect for MsSqlDialect {
118118
true
119119
}
120120

121-
fn is_column_alias(&self, kw: &Keyword, _parser: &mut Parser) -> bool {
121+
fn is_column_alias(&self, kw: &Keyword, parser: &mut Parser) -> bool {
122+
// if:
123+
// - keyword is `GO`, and
124+
// - looking backwards there's only (any) whitespace preceded by a newline
125+
// then: `GO` iSN'T a column alias
126+
if kw == &Keyword::GO {
127+
let mut look_back_count = 2;
128+
loop {
129+
let prev_index = parser.index().saturating_sub(look_back_count);
130+
if prev_index == 0 {
131+
break;
132+
}
133+
let prev_token = parser.token_at(prev_index);
134+
match prev_token.token {
135+
Token::Whitespace(ref w) => match w {
136+
Whitespace::Newline => return false,
137+
_ => look_back_count += 1,
138+
},
139+
_ => break,
140+
};
141+
}
142+
}
143+
122144
!keywords::RESERVED_FOR_COLUMN_ALIAS.contains(kw) && !RESERVED_FOR_COLUMN_ALIAS.contains(kw)
123145
}
124146

src/parser/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,10 @@ impl<'a> Parser<'a> {
475475
if expecting_statement_delimiter && word.keyword == Keyword::END {
476476
break;
477477
}
478+
479+
if expecting_statement_delimiter && word.keyword == Keyword::GO {
480+
expecting_statement_delimiter = false;
481+
}
478482
}
479483
_ => {}
480484
}

tests/sqlparser_mssql.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2170,6 +2170,11 @@ fn parse_mssql_go_keyword() {
21702170
assert_eq!(stmts.len(), 2);
21712171
assert_eq!(stmts[1], Statement::Go(GoStatement { count: Some(5) }));
21722172

2173+
let go_statement_delimiter = "SELECT 1\nGO";
2174+
let stmts = ms().parse_sql_statements(go_statement_delimiter).unwrap();
2175+
assert_eq!(stmts.len(), 2);
2176+
assert_eq!(stmts[1], Statement::Go(GoStatement { count: None }));
2177+
21732178
let bare_go = "GO";
21742179
let stmts = ms().parse_sql_statements(bare_go).unwrap();
21752180
assert_eq!(stmts.len(), 1);
@@ -2203,15 +2208,22 @@ fn parse_mssql_go_keyword() {
22032208
assert_eq!(stmts.len(), 2);
22042209
assert_eq!(stmts[1], Statement::Go(GoStatement { count: None }));
22052210

2206-
let actually_column_alias = "SELECT NULL AS GO";
2207-
let stmt = ms().verified_only_select(actually_column_alias);
2208-
assert_eq!(
2209-
only(stmt.projection),
2210-
SelectItem::ExprWithAlias {
2211-
expr: Expr::Value(Value::Null.with_empty_span()),
2212-
alias: Ident::new("GO"),
2211+
let actually_column_alias = "SELECT NULL GO";
2212+
let stmts = ms().parse_sql_statements(actually_column_alias).unwrap();
2213+
assert_eq!(stmts.len(), 1);
2214+
match &stmts[0] {
2215+
Statement::Query(query) => {
2216+
let select = query.body.as_select().unwrap();
2217+
assert_eq!(
2218+
only(select.clone().projection),
2219+
SelectItem::ExprWithAlias {
2220+
expr: Expr::Value(Value::Null.with_empty_span()),
2221+
alias: Ident::new("GO"),
2222+
}
2223+
);
22132224
}
2214-
);
2225+
_ => panic!("Expected Query statement"),
2226+
}
22152227

22162228
let invalid_go_position = "SELECT 1; GO";
22172229
let err = ms().parse_sql_statements(invalid_go_position);
@@ -2224,7 +2236,7 @@ fn parse_mssql_go_keyword() {
22242236
let err = ms().parse_sql_statements(invalid_go_count);
22252237
assert_eq!(
22262238
err.unwrap_err().to_string(),
2227-
"sql parser error: Expected: end of statement, found: x"
2239+
"sql parser error: Expected: literal int or newline, found: x"
22282240
);
22292241
}
22302242

0 commit comments

Comments
 (0)