Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 60 additions & 36 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17019,44 +17019,68 @@ impl<'a> Parser<'a> {

fn parse_create_sequence_options(&mut self) -> Result<Vec<SequenceOptions>, ParserError> {
let mut sequence_options = vec![];
//[ INCREMENT [ BY ] increment ]
if self.parse_keywords(&[Keyword::INCREMENT]) {
if self.parse_keywords(&[Keyword::BY]) {
sequence_options.push(SequenceOptions::IncrementBy(self.parse_number()?, true));
} else {
sequence_options.push(SequenceOptions::IncrementBy(self.parse_number()?, false));
}
}
//[ MINVALUE minvalue | NO MINVALUE ]
if self.parse_keyword(Keyword::MINVALUE) {
sequence_options.push(SequenceOptions::MinValue(Some(self.parse_number()?)));
} else if self.parse_keywords(&[Keyword::NO, Keyword::MINVALUE]) {
sequence_options.push(SequenceOptions::MinValue(None));
}
//[ MAXVALUE maxvalue | NO MAXVALUE ]
if self.parse_keywords(&[Keyword::MAXVALUE]) {
sequence_options.push(SequenceOptions::MaxValue(Some(self.parse_number()?)));
} else if self.parse_keywords(&[Keyword::NO, Keyword::MAXVALUE]) {
sequence_options.push(SequenceOptions::MaxValue(None));
}

//[ START [ WITH ] start ]
if self.parse_keywords(&[Keyword::START]) {
if self.parse_keywords(&[Keyword::WITH]) {
sequence_options.push(SequenceOptions::StartWith(self.parse_number()?, true));
} else {
sequence_options.push(SequenceOptions::StartWith(self.parse_number()?, false));
// To disallow duplicate options
let has_increment = false;
let has_minvalue = false;
let has_maxvalue = false;
let has_start = false;
let has_cache = false;
let has_cycle = false;

let mut should_continue_loop = true;
while should_continue_loop {
Comment on lines +17031 to +17032
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let mut should_continue_loop = true;
while should_continue_loop {
loop {

It looks like we can skip the bool var and instead use a combination of continue and break to manage the loop?

should_continue_loop = false;

//[ INCREMENT [ BY ] increment ]
if !has_increment && self.parse_keywords(&[Keyword::INCREMENT]) {
should_continue_loop = true;
if self.parse_keywords(&[Keyword::BY]) {
sequence_options.push(SequenceOptions::IncrementBy(self.parse_number()?, true));
} else {
sequence_options
.push(SequenceOptions::IncrementBy(self.parse_number()?, false));
}
}
//[ MINVALUE minvalue | NO MINVALUE ]
if !has_minvalue && self.parse_keyword(Keyword::MINVALUE) {
should_continue_loop = true;
sequence_options.push(SequenceOptions::MinValue(Some(self.parse_number()?)));
} else if !has_minvalue && self.parse_keywords(&[Keyword::NO, Keyword::MINVALUE]) {
should_continue_loop = true;
sequence_options.push(SequenceOptions::MinValue(None));
}
//[ MAXVALUE maxvalue | NO MAXVALUE ]
if !has_maxvalue && self.parse_keywords(&[Keyword::MAXVALUE]) {
should_continue_loop = true;
sequence_options.push(SequenceOptions::MaxValue(Some(self.parse_number()?)));
} else if !has_maxvalue && self.parse_keywords(&[Keyword::NO, Keyword::MAXVALUE]) {
should_continue_loop = true;
sequence_options.push(SequenceOptions::MaxValue(None));
}

//[ START [ WITH ] start ]
if !has_start && self.parse_keywords(&[Keyword::START]) {
should_continue_loop = true;
if self.parse_keywords(&[Keyword::WITH]) {
sequence_options.push(SequenceOptions::StartWith(self.parse_number()?, true));
} else {
sequence_options.push(SequenceOptions::StartWith(self.parse_number()?, false));
}
}
//[ CACHE cache ]
if !has_cache && self.parse_keywords(&[Keyword::CACHE]) {
should_continue_loop = true;
sequence_options.push(SequenceOptions::Cache(self.parse_number()?));
}
// [ [ NO ] CYCLE ]
if !has_cycle && self.parse_keywords(&[Keyword::NO, Keyword::CYCLE]) {
should_continue_loop = true;
sequence_options.push(SequenceOptions::Cycle(true));
} else if !has_cycle && self.parse_keywords(&[Keyword::CYCLE]) {
should_continue_loop = true;
sequence_options.push(SequenceOptions::Cycle(false));
}
}
//[ CACHE cache ]
if self.parse_keywords(&[Keyword::CACHE]) {
sequence_options.push(SequenceOptions::Cache(self.parse_number()?));
}
// [ [ NO ] CYCLE ]
if self.parse_keywords(&[Keyword::NO, Keyword::CYCLE]) {
sequence_options.push(SequenceOptions::Cycle(true));
} else if self.parse_keywords(&[Keyword::CYCLE]) {
sequence_options.push(SequenceOptions::Cycle(false));
}

Ok(sequence_options)
Expand Down
9 changes: 9 additions & 0 deletions tests/sqlparser_postgres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,15 @@ fn parse_create_sequence() {
pg().parse_sql_statements("CREATE SEQUENCE foo INCREMENT 1 NO MINVALUE NO"),
Err(ParserError::ParserError(_))
));

let sql9 = "CREATE SEQUENCE name6
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a test case with duplicate options?

AS INTEGER
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1";
pg().one_statement_parses_to(sql9, "CREATE SEQUENCE name6 AS INTEGER START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1");
Comment on lines +313 to +320
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let sql9 = "CREATE SEQUENCE name6
AS INTEGER
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1";
pg().one_statement_parses_to(sql9, "CREATE SEQUENCE name6 AS INTEGER START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1");
pg().verified_stmt("CREATE SEQUENCE name6 AS INTEGER START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1");

it looks like this should be equivalent?

}

#[test]
Expand Down