Skip to content

Commit 9b7ea9d

Browse files
committed
Move parse_mssql_create_trigger into MsSqlDialect
- this requires being able to start parsing `CREATE` statements; but if it isn't a trigger, we need to rewind - therefore, a new `set_index` method is added to manually update the parser index
1 parent d042e88 commit 9b7ea9d

File tree

2 files changed

+80
-58
lines changed

2 files changed

+80
-58
lines changed

src/dialect/mssql.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use crate::ast::helpers::attached_token::AttachedToken;
1919
use crate::ast::{
2020
BeginEndStatements, ConditionalStatementBlock, ConditionalStatements, IfStatement, Statement,
21+
TriggerObject,
2122
};
2223
use crate::dialect::Dialect;
2324
use crate::keywords::{self, Keyword};
@@ -125,6 +126,8 @@ impl Dialect for MsSqlDialect {
125126
fn parse_statement(&self, parser: &mut Parser) -> Option<Result<Statement, ParserError>> {
126127
if parser.peek_keyword(Keyword::IF) {
127128
Some(self.parse_if_stmt(parser))
129+
} else if parser.peek_keyword(Keyword::CREATE) {
130+
self.parse_create(parser)
128131
} else {
129132
None
130133
}
@@ -215,6 +218,78 @@ impl MsSqlDialect {
215218
}))
216219
}
217220

221+
/// Parse a SQL CREATE statement
222+
fn parse_create(&self, parser: &mut Parser) -> Option<Result<Statement, ParserError>> {
223+
let original_index = parser.index();
224+
225+
if !parser.parse_keyword(Keyword::CREATE) {
226+
parser.set_index(original_index);
227+
return None;
228+
}
229+
230+
let or_alter = parser.parse_keywords(&[Keyword::OR, Keyword::ALTER]);
231+
232+
if parser.parse_keyword(Keyword::TRIGGER) {
233+
return Some(self.parse_create_trigger(parser, or_alter));
234+
}
235+
236+
parser.set_index(original_index);
237+
None
238+
}
239+
240+
/// Parse `CREATE TRIGGER` for [MsSql]
241+
///
242+
/// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql
243+
fn parse_create_trigger(
244+
&self,
245+
parser: &mut Parser,
246+
or_alter: bool,
247+
) -> Result<Statement, ParserError> {
248+
let name = parser.parse_object_name(false)?;
249+
parser.expect_keyword_is(Keyword::ON)?;
250+
let table_name = parser.parse_object_name(false)?;
251+
let period = parser.parse_trigger_period()?;
252+
let events = parser.parse_comma_separated(Parser::parse_trigger_event)?;
253+
254+
parser.expect_keyword_is(Keyword::AS)?;
255+
256+
let trigger_statements_body = if parser.peek_keyword(Keyword::BEGIN) {
257+
let begin_token = parser.expect_keyword(Keyword::BEGIN)?;
258+
let statements = parser.parse_statement_list(&[Keyword::END])?;
259+
let end_token = parser.expect_keyword(Keyword::END)?;
260+
261+
BeginEndStatements {
262+
begin_token: AttachedToken(begin_token),
263+
statements,
264+
end_token: AttachedToken(end_token),
265+
}
266+
} else {
267+
BeginEndStatements {
268+
begin_token: AttachedToken::empty(),
269+
statements: vec![parser.parse_statement()?],
270+
end_token: AttachedToken::empty(),
271+
}
272+
};
273+
274+
Ok(Statement::CreateTrigger {
275+
or_alter,
276+
or_replace: false,
277+
is_constraint: false,
278+
name,
279+
period,
280+
events,
281+
table_name,
282+
referenced_table_name: None,
283+
referencing: Vec::new(),
284+
trigger_object: TriggerObject::Statement,
285+
include_each: false,
286+
condition: None,
287+
exec_body: None,
288+
statements: Some(trigger_statements_body),
289+
characteristics: None,
290+
})
291+
}
292+
218293
/// Parse a sequence of statements, optionally separated by semicolon.
219294
///
220295
/// Stops parsing when reaching EOF or the given keyword.

src/parser/mod.rs

Lines changed: 5 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -5265,10 +5265,6 @@ impl<'a> Parser<'a> {
52655265
return self.expected("an object type after CREATE", self.peek_token());
52665266
}
52675267

5268-
if dialect_of!(self is MsSqlDialect) {
5269-
return self.parse_mssql_create_trigger(or_alter, or_replace, is_constraint);
5270-
}
5271-
52725268
let name = self.parse_object_name(false)?;
52735269
let period = self.parse_trigger_period()?;
52745270

@@ -5328,60 +5324,6 @@ impl<'a> Parser<'a> {
53285324
})
53295325
}
53305326

5331-
/// Parse `CREATE TRIGGER` for [MsSql]
5332-
///
5333-
/// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql
5334-
pub fn parse_mssql_create_trigger(
5335-
&mut self,
5336-
or_alter: bool,
5337-
or_replace: bool,
5338-
is_constraint: bool,
5339-
) -> Result<Statement, ParserError> {
5340-
let name = self.parse_object_name(false)?;
5341-
self.expect_keyword_is(Keyword::ON)?;
5342-
let table_name = self.parse_object_name(false)?;
5343-
let period = self.parse_trigger_period()?;
5344-
let events = self.parse_comma_separated(Parser::parse_trigger_event)?;
5345-
5346-
self.expect_keyword_is(Keyword::AS)?;
5347-
5348-
let trigger_statements_body = if self.peek_keyword(Keyword::BEGIN) {
5349-
let begin_token = self.expect_keyword(Keyword::BEGIN)?;
5350-
let statements = self.parse_statement_list(&[Keyword::END])?;
5351-
let end_token = self.expect_keyword(Keyword::END)?;
5352-
5353-
BeginEndStatements {
5354-
begin_token: AttachedToken(begin_token),
5355-
statements,
5356-
end_token: AttachedToken(end_token),
5357-
}
5358-
} else {
5359-
BeginEndStatements {
5360-
begin_token: AttachedToken::empty(),
5361-
statements: vec![self.parse_statement()?],
5362-
end_token: AttachedToken::empty(),
5363-
}
5364-
};
5365-
5366-
Ok(Statement::CreateTrigger {
5367-
or_alter,
5368-
or_replace,
5369-
is_constraint,
5370-
name,
5371-
period,
5372-
events,
5373-
table_name,
5374-
referenced_table_name: None,
5375-
referencing: Vec::new(),
5376-
trigger_object: TriggerObject::Statement,
5377-
include_each: false,
5378-
condition: None,
5379-
exec_body: None,
5380-
statements: Some(trigger_statements_body),
5381-
characteristics: None,
5382-
})
5383-
}
5384-
53855327
pub fn parse_trigger_period(&mut self) -> Result<TriggerPeriod, ParserError> {
53865328
Ok(
53875329
match self.expect_one_of_keywords(&[
@@ -15139,6 +15081,11 @@ impl<'a> Parser<'a> {
1513915081
self.index
1514015082
}
1514115083

15084+
/// Manually change the parser index.
15085+
pub(crate) fn set_index(&mut self, index: usize) {
15086+
self.index = index;
15087+
}
15088+
1514215089
pub fn parse_named_window(&mut self) -> Result<NamedWindowDefinition, ParserError> {
1514315090
let ident = self.parse_identifier()?;
1514415091
self.expect_keyword_is(Keyword::AS)?;

0 commit comments

Comments
 (0)