Skip to content

Commit 8ea5691

Browse files
committed
Fix not treating GO as a statement delimiter next to a query
1 parent ba0675d commit 8ea5691

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
@@ -2067,6 +2067,11 @@ fn parse_mssql_go_keyword() {
20672067
assert_eq!(stmts.len(), 2);
20682068
assert_eq!(stmts[1], Statement::Go(GoStatement { count: Some(5) }));
20692069

2070+
let go_statement_delimiter = "SELECT 1\nGO";
2071+
let stmts = ms().parse_sql_statements(go_statement_delimiter).unwrap();
2072+
assert_eq!(stmts.len(), 2);
2073+
assert_eq!(stmts[1], Statement::Go(GoStatement { count: None }));
2074+
20702075
let bare_go = "GO";
20712076
let stmts = ms().parse_sql_statements(bare_go).unwrap();
20722077
assert_eq!(stmts.len(), 1);
@@ -2100,15 +2105,22 @@ fn parse_mssql_go_keyword() {
21002105
assert_eq!(stmts.len(), 2);
21012106
assert_eq!(stmts[1], Statement::Go(GoStatement { count: None }));
21022107

2103-
let actually_column_alias = "SELECT NULL AS GO";
2104-
let stmt = ms().verified_only_select(actually_column_alias);
2105-
assert_eq!(
2106-
only(stmt.projection),
2107-
SelectItem::ExprWithAlias {
2108-
expr: Expr::Value(Value::Null.with_empty_span()),
2109-
alias: Ident::new("GO"),
2108+
let actually_column_alias = "SELECT NULL GO";
2109+
let stmts = ms().parse_sql_statements(actually_column_alias).unwrap();
2110+
assert_eq!(stmts.len(), 1);
2111+
match &stmts[0] {
2112+
Statement::Query(query) => {
2113+
let select = query.body.as_select().unwrap();
2114+
assert_eq!(
2115+
only(select.clone().projection),
2116+
SelectItem::ExprWithAlias {
2117+
expr: Expr::Value(Value::Null.with_empty_span()),
2118+
alias: Ident::new("GO"),
2119+
}
2120+
);
21102121
}
2111-
);
2122+
_ => panic!("Expected Query statement"),
2123+
}
21122124

21132125
let invalid_go_position = "SELECT 1; GO";
21142126
let err = ms().parse_sql_statements(invalid_go_position);
@@ -2121,7 +2133,7 @@ fn parse_mssql_go_keyword() {
21212133
let err = ms().parse_sql_statements(invalid_go_count);
21222134
assert_eq!(
21232135
err.unwrap_err().to_string(),
2124-
"sql parser error: Expected: end of statement, found: x"
2136+
"sql parser error: Expected: literal int or newline, found: x"
21252137
);
21262138
}
21272139

0 commit comments

Comments
 (0)