Skip to content

Commit 4015ada

Browse files
agscppAgaev Huseyn
and
Agaev Huseyn
committed
Fix parsing of negative values (apache#1419)
Co-authored-by: Agaev Huseyn <h.agaev@vkteam.ru>
1 parent f3f5de5 commit 4015ada

File tree

3 files changed

+60
-25
lines changed

3 files changed

+60
-25
lines changed

src/parser/mod.rs

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6717,6 +6717,7 @@ impl<'a> Parser<'a> {
67176717
}
67186718
}
67196719

6720+
/// Parse an unsigned numeric literal
67206721
pub fn parse_number_value(&mut self) -> Result<Value, ParserError> {
67216722
match self.parse_value()? {
67226723
v @ Value::Number(_, _) => Ok(v),
@@ -6728,6 +6729,26 @@ impl<'a> Parser<'a> {
67286729
}
67296730
}
67306731

6732+
/// Parse a numeric literal as an expression. Returns a [`Expr::UnaryOp`] if the number is signed,
6733+
/// otherwise returns a [`Expr::Value`]
6734+
pub fn parse_number(&mut self) -> Result<Expr, ParserError> {
6735+
let next_token = self.next_token();
6736+
match next_token.token {
6737+
Token::Plus => Ok(Expr::UnaryOp {
6738+
op: UnaryOperator::Plus,
6739+
expr: Box::new(Expr::Value(self.parse_number_value()?)),
6740+
}),
6741+
Token::Minus => Ok(Expr::UnaryOp {
6742+
op: UnaryOperator::Minus,
6743+
expr: Box::new(Expr::Value(self.parse_number_value()?)),
6744+
}),
6745+
_ => {
6746+
self.prev_token();
6747+
Ok(Expr::Value(self.parse_number_value()?))
6748+
}
6749+
}
6750+
}
6751+
67316752
fn parse_introduced_string_value(&mut self) -> Result<Value, ParserError> {
67326753
let next_token = self.next_token();
67336754
let location = next_token.location;
@@ -10660,53 +10681,35 @@ impl<'a> Parser<'a> {
1066010681
//[ INCREMENT [ BY ] increment ]
1066110682
if self.parse_keywords(&[Keyword::INCREMENT]) {
1066210683
if self.parse_keywords(&[Keyword::BY]) {
10663-
sequence_options.push(SequenceOptions::IncrementBy(
10664-
Expr::Value(self.parse_number_value()?),
10665-
true,
10666-
));
10684+
sequence_options.push(SequenceOptions::IncrementBy(self.parse_number()?, true));
1066710685
} else {
10668-
sequence_options.push(SequenceOptions::IncrementBy(
10669-
Expr::Value(self.parse_number_value()?),
10670-
false,
10671-
));
10686+
sequence_options.push(SequenceOptions::IncrementBy(self.parse_number()?, false));
1067210687
}
1067310688
}
1067410689
//[ MINVALUE minvalue | NO MINVALUE ]
1067510690
if self.parse_keyword(Keyword::MINVALUE) {
10676-
sequence_options.push(SequenceOptions::MinValue(Some(Expr::Value(
10677-
self.parse_number_value()?,
10678-
))));
10691+
sequence_options.push(SequenceOptions::MinValue(Some(self.parse_number()?)));
1067910692
} else if self.parse_keywords(&[Keyword::NO, Keyword::MINVALUE]) {
1068010693
sequence_options.push(SequenceOptions::MinValue(None));
1068110694
}
1068210695
//[ MAXVALUE maxvalue | NO MAXVALUE ]
1068310696
if self.parse_keywords(&[Keyword::MAXVALUE]) {
10684-
sequence_options.push(SequenceOptions::MaxValue(Some(Expr::Value(
10685-
self.parse_number_value()?,
10686-
))));
10697+
sequence_options.push(SequenceOptions::MaxValue(Some(self.parse_number()?)));
1068710698
} else if self.parse_keywords(&[Keyword::NO, Keyword::MAXVALUE]) {
1068810699
sequence_options.push(SequenceOptions::MaxValue(None));
1068910700
}
1069010701

1069110702
//[ START [ WITH ] start ]
1069210703
if self.parse_keywords(&[Keyword::START]) {
1069310704
if self.parse_keywords(&[Keyword::WITH]) {
10694-
sequence_options.push(SequenceOptions::StartWith(
10695-
Expr::Value(self.parse_number_value()?),
10696-
true,
10697-
));
10705+
sequence_options.push(SequenceOptions::StartWith(self.parse_number()?, true));
1069810706
} else {
10699-
sequence_options.push(SequenceOptions::StartWith(
10700-
Expr::Value(self.parse_number_value()?),
10701-
false,
10702-
));
10707+
sequence_options.push(SequenceOptions::StartWith(self.parse_number()?, false));
1070310708
}
1070410709
}
1070510710
//[ CACHE cache ]
1070610711
if self.parse_keywords(&[Keyword::CACHE]) {
10707-
sequence_options.push(SequenceOptions::Cache(Expr::Value(
10708-
self.parse_number_value()?,
10709-
)));
10712+
sequence_options.push(SequenceOptions::Cache(self.parse_number()?));
1071010713
}
1071110714
// [ [ NO ] CYCLE ]
1071210715
if self.parse_keywords(&[Keyword::NO, Keyword::CYCLE]) {

tests/sqlparser_common.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2718,6 +2718,18 @@ fn parse_window_function_null_treatment_arg() {
27182718
);
27192719
}
27202720

2721+
#[test]
2722+
fn parse_negative_value() {
2723+
let sql1 = "SELECT -1";
2724+
one_statement_parses_to(sql1, "SELECT -1");
2725+
2726+
let sql2 = "CREATE SEQUENCE name INCREMENT -10 MINVALUE -1000 MAXVALUE 15 START -100;";
2727+
one_statement_parses_to(
2728+
sql2,
2729+
"CREATE SEQUENCE name INCREMENT -10 MINVALUE -1000 MAXVALUE 15 START -100",
2730+
);
2731+
}
2732+
27212733
#[test]
27222734
fn parse_create_table() {
27232735
let sql = "CREATE TABLE uk_cities (\

tests/sqlparser_postgres.rs

Lines changed: 20 additions & 0 deletions
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)