Skip to content

Commit d5651fd

Browse files
committed
fix parsing <-
1 parent fdd7a07 commit d5651fd

File tree

1 file changed

+43
-7
lines changed

1 file changed

+43
-7
lines changed

src/tokenizer.rs

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1530,12 +1530,13 @@ impl<'a> Tokenizer<'a> {
15301530
}
15311531
Some('<') => self.consume_for_binop(chars, "<<", Token::ShiftLeft),
15321532
Some('-') if self.dialect.supports_geometric_types() => {
1533-
chars.next(); // consume
1534-
match chars.peek() {
1535-
Some('>') => {
1536-
self.consume_for_binop(chars, "<->", Token::TwoWayArrow)
1537-
}
1538-
_ => self.start_binop_opt(chars, "<-", None),
1533+
// `<->` is a geometric operator, but `<-123` means `< -123`.
1534+
// If the sequence is not `<->`, keep `-` unconsumed so it can be tokenized as a unary minus.
1535+
if chars.peekable.clone().nth(1) == Some('>') {
1536+
chars.next(); // consume '-'
1537+
self.consume_for_binop(chars, "<->", Token::TwoWayArrow)
1538+
} else {
1539+
self.start_binop(chars, "<", Token::Lt)
15391540
}
15401541
}
15411542
Some('^') if self.dialect.supports_geometric_types() => {
@@ -2495,7 +2496,8 @@ fn take_char_from_hex_digits(
24952496
mod tests {
24962497
use super::*;
24972498
use crate::dialect::{
2498-
BigQueryDialect, ClickHouseDialect, HiveDialect, MsSqlDialect, MySqlDialect, SQLiteDialect,
2499+
BigQueryDialect, ClickHouseDialect, HiveDialect, MsSqlDialect, MySqlDialect,
2500+
RedshiftSqlDialect, SQLiteDialect,
24992501
};
25002502
use crate::test_utils::{all_dialects_except, all_dialects_where};
25012503
use core::fmt::Debug;
@@ -4152,4 +4154,38 @@ mod tests {
41524154
],
41534155
);
41544156
}
4157+
4158+
#[test]
4159+
fn tokenize_lt_followed_by_negative_number() {
4160+
let sql = "SELECT a <-4000";
4161+
let dialect = RedshiftSqlDialect {};
4162+
let tokens = Tokenizer::new(&dialect, sql).tokenize().unwrap();
4163+
compare(
4164+
vec![
4165+
Token::make_keyword("SELECT"),
4166+
Token::Whitespace(Whitespace::Space),
4167+
Token::make_word("a", None),
4168+
Token::Whitespace(Whitespace::Space),
4169+
Token::Lt,
4170+
Token::Minus,
4171+
Token::Number("4000".to_string(), false),
4172+
],
4173+
tokens,
4174+
);
4175+
4176+
// Ensure geometric `<->` is still recognized.
4177+
let tokens = Tokenizer::new(&dialect, "SELECT a <-> b").tokenize().unwrap();
4178+
compare(
4179+
vec![
4180+
Token::make_keyword("SELECT"),
4181+
Token::Whitespace(Whitespace::Space),
4182+
Token::make_word("a", None),
4183+
Token::Whitespace(Whitespace::Space),
4184+
Token::TwoWayArrow,
4185+
Token::Whitespace(Whitespace::Space),
4186+
Token::make_word("b", None),
4187+
],
4188+
tokens,
4189+
);
4190+
}
41554191
}

0 commit comments

Comments
 (0)