Skip to content

Commit 246838a

Browse files
agscppAgaev Huseyn
and
Agaev Huseyn
authored
Fix parsing of negative values (#1419)
Co-authored-by: Agaev Huseyn <[email protected]>
1 parent b9f6784 commit 246838a

File tree

3 files changed

+60
-25
lines changed

3 files changed

+60
-25
lines changed

src/parser/mod.rs

+28-25
Original file line numberDiff line numberDiff line change
@@ -7411,6 +7411,7 @@ impl<'a> Parser<'a> {
74117411
}
74127412
}
74137413

7414+
/// Parse an unsigned numeric literal
74147415
pub fn parse_number_value(&mut self) -> Result<Value, ParserError> {
74157416
match self.parse_value()? {
74167417
v @ Value::Number(_, _) => Ok(v),
@@ -7422,6 +7423,26 @@ impl<'a> Parser<'a> {
74227423
}
74237424
}
74247425

7426+
/// Parse a numeric literal as an expression. Returns a [`Expr::UnaryOp`] if the number is signed,
7427+
/// otherwise returns a [`Expr::Value`]
7428+
pub fn parse_number(&mut self) -> Result<Expr, ParserError> {
7429+
let next_token = self.next_token();
7430+
match next_token.token {
7431+
Token::Plus => Ok(Expr::UnaryOp {
7432+
op: UnaryOperator::Plus,
7433+
expr: Box::new(Expr::Value(self.parse_number_value()?)),
7434+
}),
7435+
Token::Minus => Ok(Expr::UnaryOp {
7436+
op: UnaryOperator::Minus,
7437+
expr: Box::new(Expr::Value(self.parse_number_value()?)),
7438+
}),
7439+
_ => {
7440+
self.prev_token();
7441+
Ok(Expr::Value(self.parse_number_value()?))
7442+
}
7443+
}
7444+
}
7445+
74257446
fn parse_introduced_string_value(&mut self) -> Result<Value, ParserError> {
74267447
let next_token = self.next_token();
74277448
let location = next_token.location;
@@ -11741,53 +11762,35 @@ impl<'a> Parser<'a> {
1174111762
//[ INCREMENT [ BY ] increment ]
1174211763
if self.parse_keywords(&[Keyword::INCREMENT]) {
1174311764
if self.parse_keywords(&[Keyword::BY]) {
11744-
sequence_options.push(SequenceOptions::IncrementBy(
11745-
Expr::Value(self.parse_number_value()?),
11746-
true,
11747-
));
11765+
sequence_options.push(SequenceOptions::IncrementBy(self.parse_number()?, true));
1174811766
} else {
11749-
sequence_options.push(SequenceOptions::IncrementBy(
11750-
Expr::Value(self.parse_number_value()?),
11751-
false,
11752-
));
11767+
sequence_options.push(SequenceOptions::IncrementBy(self.parse_number()?, false));
1175311768
}
1175411769
}
1175511770
//[ MINVALUE minvalue | NO MINVALUE ]
1175611771
if self.parse_keyword(Keyword::MINVALUE) {
11757-
sequence_options.push(SequenceOptions::MinValue(Some(Expr::Value(
11758-
self.parse_number_value()?,
11759-
))));
11772+
sequence_options.push(SequenceOptions::MinValue(Some(self.parse_number()?)));
1176011773
} else if self.parse_keywords(&[Keyword::NO, Keyword::MINVALUE]) {
1176111774
sequence_options.push(SequenceOptions::MinValue(None));
1176211775
}
1176311776
//[ MAXVALUE maxvalue | NO MAXVALUE ]
1176411777
if self.parse_keywords(&[Keyword::MAXVALUE]) {
11765-
sequence_options.push(SequenceOptions::MaxValue(Some(Expr::Value(
11766-
self.parse_number_value()?,
11767-
))));
11778+
sequence_options.push(SequenceOptions::MaxValue(Some(self.parse_number()?)));
1176811779
} else if self.parse_keywords(&[Keyword::NO, Keyword::MAXVALUE]) {
1176911780
sequence_options.push(SequenceOptions::MaxValue(None));
1177011781
}
1177111782

1177211783
//[ START [ WITH ] start ]
1177311784
if self.parse_keywords(&[Keyword::START]) {
1177411785
if self.parse_keywords(&[Keyword::WITH]) {
11775-
sequence_options.push(SequenceOptions::StartWith(
11776-
Expr::Value(self.parse_number_value()?),
11777-
true,
11778-
));
11786+
sequence_options.push(SequenceOptions::StartWith(self.parse_number()?, true));
1177911787
} else {
11780-
sequence_options.push(SequenceOptions::StartWith(
11781-
Expr::Value(self.parse_number_value()?),
11782-
false,
11783-
));
11788+
sequence_options.push(SequenceOptions::StartWith(self.parse_number()?, false));
1178411789
}
1178511790
}
1178611791
//[ CACHE cache ]
1178711792
if self.parse_keywords(&[Keyword::CACHE]) {
11788-
sequence_options.push(SequenceOptions::Cache(Expr::Value(
11789-
self.parse_number_value()?,
11790-
)));
11793+
sequence_options.push(SequenceOptions::Cache(self.parse_number()?));
1179111794
}
1179211795
// [ [ NO ] CYCLE ]
1179311796
if self.parse_keywords(&[Keyword::NO, Keyword::CYCLE]) {

tests/sqlparser_common.rs

+12
Original file line numberDiff line numberDiff line change
@@ -2819,6 +2819,18 @@ fn parse_window_function_null_treatment_arg() {
28192819
);
28202820
}
28212821

2822+
#[test]
2823+
fn parse_negative_value() {
2824+
let sql1 = "SELECT -1";
2825+
one_statement_parses_to(sql1, "SELECT -1");
2826+
2827+
let sql2 = "CREATE SEQUENCE name INCREMENT -10 MINVALUE -1000 MAXVALUE 15 START -100;";
2828+
one_statement_parses_to(
2829+
sql2,
2830+
"CREATE SEQUENCE name INCREMENT -10 MINVALUE -1000 MAXVALUE 15 START -100",
2831+
);
2832+
}
2833+
28222834
#[test]
28232835
fn parse_create_table() {
28242836
let sql = "CREATE TABLE uk_cities (\

tests/sqlparser_postgres.rs

+20
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,26 @@ fn parse_create_sequence() {
277277
"CREATE TEMPORARY SEQUENCE IF NOT EXISTS name3 INCREMENT 1 NO MINVALUE MAXVALUE 20 OWNED BY NONE",
278278
);
279279

280+
let sql7 = "CREATE SEQUENCE name4
281+
AS BIGINT
282+
INCREMENT -15
283+
MINVALUE - 2000 MAXVALUE -50
284+
START WITH - 60";
285+
pg().one_statement_parses_to(
286+
sql7,
287+
"CREATE SEQUENCE name4 AS BIGINT INCREMENT -15 MINVALUE -2000 MAXVALUE -50 START WITH -60",
288+
);
289+
290+
let sql8 = "CREATE SEQUENCE name5
291+
AS BIGINT
292+
INCREMENT +10
293+
MINVALUE + 30 MAXVALUE +5000
294+
START WITH + 45";
295+
pg().one_statement_parses_to(
296+
sql8,
297+
"CREATE SEQUENCE name5 AS BIGINT INCREMENT +10 MINVALUE +30 MAXVALUE +5000 START WITH +45",
298+
);
299+
280300
assert!(matches!(
281301
pg().parse_sql_statements("CREATE SEQUENCE foo INCREMENT 1 NO MINVALUE NO"),
282302
Err(ParserError::ParserError(_))

0 commit comments

Comments
 (0)