Skip to content

Commit db157eb

Browse files
committed
Fix not treating GO as a statement delimiter next to a query
1 parent 0fc73a6 commit db157eb

File tree

3 files changed

+49
-11
lines changed

3 files changed

+49
-11
lines changed

src/dialect/mssql.rs

+24-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::ast::{ConditionalStatementBlock, ConditionalStatements, IfStatement,
2020
use crate::dialect::Dialect;
2121
use crate::keywords::{self, Keyword};
2222
use crate::parser::{Parser, ParserError};
23-
use crate::tokenizer::Token;
23+
use crate::tokenizer::{Token, Whitespace};
2424
#[cfg(not(feature = "std"))]
2525
use alloc::{vec, vec::Vec};
2626

@@ -116,7 +116,29 @@ impl Dialect for MsSqlDialect {
116116
true
117117
}
118118

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

src/parser/mod.rs

+4
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

+21-9
Original file line numberDiff line numberDiff line change
@@ -2084,6 +2084,11 @@ fn parse_mssql_go_keyword() {
20842084
assert_eq!(stmts.len(), 2);
20852085
assert_eq!(stmts[1], Statement::Go(GoStatement { count: Some(5) }));
20862086

2087+
let go_statement_delimiter = "SELECT 1\nGO";
2088+
let stmts = ms().parse_sql_statements(go_statement_delimiter).unwrap();
2089+
assert_eq!(stmts.len(), 2);
2090+
assert_eq!(stmts[1], Statement::Go(GoStatement { count: None }));
2091+
20872092
let bare_go = "GO";
20882093
let stmts = ms().parse_sql_statements(bare_go).unwrap();
20892094
assert_eq!(stmts.len(), 1);
@@ -2117,15 +2122,22 @@ fn parse_mssql_go_keyword() {
21172122
assert_eq!(stmts.len(), 2);
21182123
assert_eq!(stmts[1], Statement::Go(GoStatement { count: None }));
21192124

2120-
let actually_column_alias = "SELECT NULL AS GO";
2121-
let stmt = ms().verified_only_select(actually_column_alias);
2122-
assert_eq!(
2123-
only(stmt.projection),
2124-
SelectItem::ExprWithAlias {
2125-
expr: Expr::Value(Value::Null.with_empty_span()),
2126-
alias: Ident::new("GO"),
2125+
let actually_column_alias = "SELECT NULL GO";
2126+
let stmts = ms().parse_sql_statements(actually_column_alias).unwrap();
2127+
assert_eq!(stmts.len(), 1);
2128+
match &stmts[0] {
2129+
Statement::Query(query) => {
2130+
let select = query.body.as_select().unwrap();
2131+
assert_eq!(
2132+
only(select.clone().projection),
2133+
SelectItem::ExprWithAlias {
2134+
expr: Expr::Value(Value::Null.with_empty_span()),
2135+
alias: Ident::new("GO"),
2136+
}
2137+
);
21272138
}
2128-
);
2139+
_ => panic!("Expected Query statement"),
2140+
}
21292141

21302142
let invalid_go_position = "SELECT 1; GO";
21312143
let err = ms().parse_sql_statements(invalid_go_position);
@@ -2138,7 +2150,7 @@ fn parse_mssql_go_keyword() {
21382150
let err = ms().parse_sql_statements(invalid_go_count);
21392151
assert_eq!(
21402152
err.unwrap_err().to_string(),
2141-
"sql parser error: Expected: end of statement, found: x"
2153+
"sql parser error: Expected: literal int or newline, found: x"
21422154
);
21432155
}
21442156

0 commit comments

Comments
 (0)