Skip to content

Commit 54be3a0

Browse files
agscppAgaev Huseyn
authored andcommitted
Fix parsing of negative values (apache#1419)
Co-authored-by: Agaev Huseyn <[email protected]>
1 parent 11a6e6f commit 54be3a0

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
@@ -7197,6 +7197,7 @@ impl<'a> Parser<'a> {
71977197
}
71987198
}
71997199

7200+
/// Parse an unsigned numeric literal
72007201
pub fn parse_number_value(&mut self) -> Result<Value, ParserError> {
72017202
match self.parse_value()? {
72027203
v @ Value::Number(_, _) => Ok(v),
@@ -7208,6 +7209,26 @@ impl<'a> Parser<'a> {
72087209
}
72097210
}
72107211

7212+
/// Parse a numeric literal as an expression. Returns a [`Expr::UnaryOp`] if the number is signed,
7213+
/// otherwise returns a [`Expr::Value`]
7214+
pub fn parse_number(&mut self) -> Result<Expr, ParserError> {
7215+
let next_token = self.next_token();
7216+
match next_token.token {
7217+
Token::Plus => Ok(Expr::UnaryOp {
7218+
op: UnaryOperator::Plus,
7219+
expr: Box::new(Expr::Value(self.parse_number_value()?)),
7220+
}),
7221+
Token::Minus => Ok(Expr::UnaryOp {
7222+
op: UnaryOperator::Minus,
7223+
expr: Box::new(Expr::Value(self.parse_number_value()?)),
7224+
}),
7225+
_ => {
7226+
self.prev_token();
7227+
Ok(Expr::Value(self.parse_number_value()?))
7228+
}
7229+
}
7230+
}
7231+
72117232
fn parse_introduced_string_value(&mut self) -> Result<Value, ParserError> {
72127233
let next_token = self.next_token();
72137234
let location = next_token.location;
@@ -11487,53 +11508,35 @@ impl<'a> Parser<'a> {
1148711508
//[ INCREMENT [ BY ] increment ]
1148811509
if self.parse_keywords(&[Keyword::INCREMENT]) {
1148911510
if self.parse_keywords(&[Keyword::BY]) {
11490-
sequence_options.push(SequenceOptions::IncrementBy(
11491-
Expr::Value(self.parse_number_value()?),
11492-
true,
11493-
));
11511+
sequence_options.push(SequenceOptions::IncrementBy(self.parse_number()?, true));
1149411512
} else {
11495-
sequence_options.push(SequenceOptions::IncrementBy(
11496-
Expr::Value(self.parse_number_value()?),
11497-
false,
11498-
));
11513+
sequence_options.push(SequenceOptions::IncrementBy(self.parse_number()?, false));
1149911514
}
1150011515
}
1150111516
//[ MINVALUE minvalue | NO MINVALUE ]
1150211517
if self.parse_keyword(Keyword::MINVALUE) {
11503-
sequence_options.push(SequenceOptions::MinValue(Some(Expr::Value(
11504-
self.parse_number_value()?,
11505-
))));
11518+
sequence_options.push(SequenceOptions::MinValue(Some(self.parse_number()?)));
1150611519
} else if self.parse_keywords(&[Keyword::NO, Keyword::MINVALUE]) {
1150711520
sequence_options.push(SequenceOptions::MinValue(None));
1150811521
}
1150911522
//[ MAXVALUE maxvalue | NO MAXVALUE ]
1151011523
if self.parse_keywords(&[Keyword::MAXVALUE]) {
11511-
sequence_options.push(SequenceOptions::MaxValue(Some(Expr::Value(
11512-
self.parse_number_value()?,
11513-
))));
11524+
sequence_options.push(SequenceOptions::MaxValue(Some(self.parse_number()?)));
1151411525
} else if self.parse_keywords(&[Keyword::NO, Keyword::MAXVALUE]) {
1151511526
sequence_options.push(SequenceOptions::MaxValue(None));
1151611527
}
1151711528

1151811529
//[ START [ WITH ] start ]
1151911530
if self.parse_keywords(&[Keyword::START]) {
1152011531
if self.parse_keywords(&[Keyword::WITH]) {
11521-
sequence_options.push(SequenceOptions::StartWith(
11522-
Expr::Value(self.parse_number_value()?),
11523-
true,
11524-
));
11532+
sequence_options.push(SequenceOptions::StartWith(self.parse_number()?, true));
1152511533
} else {
11526-
sequence_options.push(SequenceOptions::StartWith(
11527-
Expr::Value(self.parse_number_value()?),
11528-
false,
11529-
));
11534+
sequence_options.push(SequenceOptions::StartWith(self.parse_number()?, false));
1153011535
}
1153111536
}
1153211537
//[ CACHE cache ]
1153311538
if self.parse_keywords(&[Keyword::CACHE]) {
11534-
sequence_options.push(SequenceOptions::Cache(Expr::Value(
11535-
self.parse_number_value()?,
11536-
)));
11539+
sequence_options.push(SequenceOptions::Cache(self.parse_number()?));
1153711540
}
1153811541
// [ [ NO ] CYCLE ]
1153911542
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)