Skip to content

Commit 373219f

Browse files
committed
rebase
1 parent c35dcc9 commit 373219f

File tree

4 files changed

+64
-0
lines changed

4 files changed

+64
-0
lines changed

src/ast/value.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ pub enum Value {
4141
/// See [Postgres docs](https://www.postgresql.org/docs/8.3/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS)
4242
/// for more details.
4343
EscapedStringLiteral(String),
44+
/// B'string value'
45+
SingleQuotedByteStringLiteral(String),
46+
/// B"string value"
47+
DoubleQuotedByteStringLiteral(String),
4448
/// N'string value'
4549
NationalStringLiteral(String),
4650
/// X'hex value'
@@ -68,6 +72,11 @@ impl fmt::Display for Value {
6872
Value::NationalStringLiteral(v) => write!(f, "N'{v}'"),
6973
Value::HexStringLiteral(v) => write!(f, "X'{v}'"),
7074
Value::Boolean(v) => write!(f, "{v}"),
75+
Value::SingleQuotedByteStringLiteral(v) => write!(f, "B'{}'", v),
76+
Value::DoubleQuotedByteStringLiteral(v) => write!(f, "B\"{}\"", v),
77+
Value::NationalStringLiteral(v) => write!(f, "N'{}'", v),
78+
Value::HexStringLiteral(v) => write!(f, "X'{}'", v),
79+
Value::Boolean(v) => write!(f, "{}", v),
7180
Value::Null => write!(f, "NULL"),
7281
Value::Placeholder(v) => write!(f, "{v}"),
7382
Value::UnQuotedString(v) => write!(f, "{v}"),

src/parser.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,8 @@ impl<'a> Parser<'a> {
790790
| Token::SingleQuotedString(_)
791791
| Token::DoubleQuotedString(_)
792792
| Token::DollarQuotedString(_)
793+
| Token::SingleQuotedByteStringLiteral(_)
794+
| Token::DoubleQuotedByteStringLiteral(_)
793795
| Token::NationalStringLiteral(_)
794796
| Token::HexStringLiteral(_) => {
795797
self.prev_token();
@@ -4125,6 +4127,12 @@ impl<'a> Parser<'a> {
41254127
Token::SingleQuotedString(ref s) => Ok(Value::SingleQuotedString(s.to_string())),
41264128
Token::DoubleQuotedString(ref s) => Ok(Value::DoubleQuotedString(s.to_string())),
41274129
Token::DollarQuotedString(ref s) => Ok(Value::DollarQuotedString(s.clone())),
4130+
Token::SingleQuotedByteStringLiteral(ref s) => {
4131+
Ok(Value::SingleQuotedByteStringLiteral(s.clone()))
4132+
}
4133+
Token::DoubleQuotedByteStringLiteral(ref s) => {
4134+
Ok(Value::DoubleQuotedByteStringLiteral(s.clone()))
4135+
}
41284136
Token::NationalStringLiteral(ref s) => Ok(Value::NationalStringLiteral(s.to_string())),
41294137
Token::EscapedStringLiteral(ref s) => Ok(Value::EscapedStringLiteral(s.to_string())),
41304138
Token::HexStringLiteral(ref s) => Ok(Value::HexStringLiteral(s.to_string())),

src/tokenizer.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ pub enum Token {
5858
DoubleQuotedString(String),
5959
/// Dollar quoted string: i.e: $$string$$ or $tag_name$string$tag_name$
6060
DollarQuotedString(DollarQuotedString),
61+
/// Byte string literal: i.e: b'string' or B'string'
62+
SingleQuotedByteStringLiteral(String),
63+
/// Byte string literal: i.e: b"string" or B"string"
64+
DoubleQuotedByteStringLiteral(String),
6165
/// "National" string literal: i.e: N'string'
6266
NationalStringLiteral(String),
6367
/// "escaped" string literal, which are an extension to the SQL standard: i.e: e'first \n second' or E 'first \n second'
@@ -189,6 +193,15 @@ impl fmt::Display for Token {
189193
Token::NationalStringLiteral(ref s) => write!(f, "N'{s}'"),
190194
Token::EscapedStringLiteral(ref s) => write!(f, "E'{s}'"),
191195
Token::HexStringLiteral(ref s) => write!(f, "X'{s}'"),
196+
Token::Char(ref c) => write!(f, "{}", c),
197+
Token::SingleQuotedString(ref s) => write!(f, "'{}'", s),
198+
Token::DoubleQuotedString(ref s) => write!(f, "\"{}\"", s),
199+
Token::DollarQuotedString(ref s) => write!(f, "{}", s),
200+
Token::SingleQuotedByteStringLiteral(ref s) => write!(f, "B'{}'", s),
201+
Token::DoubleQuotedByteStringLiteral(ref s) => write!(f, "B\"{}\"", s),
202+
Token::NationalStringLiteral(ref s) => write!(f, "N'{}'", s),
203+
Token::EscapedStringLiteral(ref s) => write!(f, "E'{}'", s),
204+
Token::HexStringLiteral(ref s) => write!(f, "X'{}'", s),
192205
Token::Comma => f.write_str(","),
193206
Token::Whitespace(ws) => write!(f, "{ws}"),
194207
Token::DoubleEq => f.write_str("=="),
@@ -493,6 +506,25 @@ impl<'a> Tokenizer<'a> {
493506
}
494507
Ok(Some(Token::Whitespace(Whitespace::Newline)))
495508
}
509+
// BigQuery uses b or B for byte string literal
510+
b @ 'B' | b @ 'b' => {
511+
chars.next(); // consume
512+
match chars.peek() {
513+
Some('\'') => {
514+
let s = self.tokenize_quoted_string(chars, '\'')?;
515+
Ok(Some(Token::SingleQuotedByteStringLiteral(s)))
516+
}
517+
Some('\"') => {
518+
let s = self.tokenize_quoted_string(chars, '\"')?;
519+
Ok(Some(Token::DoubleQuotedByteStringLiteral(s)))
520+
}
521+
_ => {
522+
// regular identifier starting with an "b" or "B"
523+
let s = self.tokenize_word(b, chars);
524+
Ok(Some(Token::make_word(&s, None)))
525+
}
526+
}
527+
}
496528
// Redshift uses lower case n for national string literal
497529
n @ 'N' | n @ 'n' => {
498530
chars.next(); // consume, to check the next char

tests/sqlparser_bigquery.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,21 @@ fn parse_literal_string() {
3232
);
3333
}
3434

35+
#[test]
36+
fn parse_byte_literal() {
37+
let sql = r#"SELECT B'abc', B"abc""#;
38+
let select = bigquery().verified_only_select(sql);
39+
assert_eq!(2, select.projection.len());
40+
assert_eq!(
41+
&Expr::Value(Value::SingleQuotedByteStringLiteral("abc".to_string())),
42+
expr_from_projection(&select.projection[0])
43+
);
44+
assert_eq!(
45+
&Expr::Value(Value::DoubleQuotedByteStringLiteral("abc".to_string())),
46+
expr_from_projection(&select.projection[1])
47+
);
48+
}
49+
3550
#[test]
3651
fn parse_table_identifiers() {
3752
fn test_table_ident(ident: &str, expected: Vec<Ident>) {

0 commit comments

Comments
 (0)