From 1d047d5f7d016264bf9727e97aabf89bfe710d03 Mon Sep 17 00:00:00 2001 From: Michael Victor Zink Date: Mon, 18 Nov 2024 14:23:35 -0800 Subject: [PATCH 1/2] Parse byte/bit string literals in MySQL and Postgres --- src/tokenizer.rs | 5 +++-- tests/sqlparser_mysql.rs | 31 +++++++++++++++++++++++++++++++ tests/sqlparser_postgres.rs | 31 +++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/src/tokenizer.rs b/src/tokenizer.rs index 4186ec824..05aaf1e28 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -704,8 +704,9 @@ impl<'a> Tokenizer<'a> { } Ok(Some(Token::Whitespace(Whitespace::Newline))) } - // BigQuery uses b or B for byte string literal - b @ 'B' | b @ 'b' if dialect_of!(self is BigQueryDialect | GenericDialect) => { + // BigQuery and MySQL use b or B for byte string literal, Postgres for bit strings + b @ 'B' | b @ 'b' if dialect_of!(self is BigQueryDialect | PostgreSqlDialect | MySqlDialect | GenericDialect) => + { chars.next(); // consume match chars.peek() { Some('\'') => { diff --git a/tests/sqlparser_mysql.rs b/tests/sqlparser_mysql.rs index 2a876cff2..438c14730 100644 --- a/tests/sqlparser_mysql.rs +++ b/tests/sqlparser_mysql.rs @@ -2960,3 +2960,34 @@ fn parse_logical_xor() { select.projection[3] ); } + +#[test] +fn parse_bitstring_literal_in_projection_is_not_alias() { + let select = mysql_and_generic().verified_only_select("SELECT B'111'"); + assert_eq!( + select.projection, + vec![SelectItem::UnnamedExpr(Expr::Value( + Value::SingleQuotedByteStringLiteral("111".to_string()) + ))] + ); +} + +#[test] +fn parse_bitstring_literal_in_insert_value_succeeds() { + let stmt = mysql_and_generic().verified_stmt("INSERT INTO foo VALUES (B'111')"); + match &stmt { + Statement::Insert(Insert { + source: Some(query), + .. + }) => assert_eq!( + *query.body, + SetExpr::Values(Values { + explicit_row: false, + rows: vec![vec![Expr::Value(Value::SingleQuotedByteStringLiteral( + "111".to_string() + ))]] + }) + ), + _ => unreachable!(), + } +} diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs index a6c480cd7..f798d1535 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -5098,3 +5098,34 @@ fn parse_create_type_as_enum() { _ => unreachable!(), } } + +#[test] +fn parse_bitstring_literal_in_projection_is_not_alias() { + let select = pg_and_generic().verified_only_select("SELECT B'111'"); + assert_eq!( + select.projection, + vec![SelectItem::UnnamedExpr(Expr::Value( + Value::SingleQuotedByteStringLiteral("111".to_string()) + ))] + ); +} + +#[test] +fn parse_bitstring_literal_in_insert_value_succeeds() { + let stmt = pg_and_generic().verified_stmt("INSERT INTO foo VALUES (B'111')"); + match &stmt { + Statement::Insert(Insert { + source: Some(query), + .. + }) => assert_eq!( + *query.body, + SetExpr::Values(Values { + explicit_row: false, + rows: vec![vec![Expr::Value(Value::SingleQuotedByteStringLiteral( + "111".to_string() + ))]] + }) + ), + _ => unreachable!(), + } +} From ade6883cd9a4ca2eb69418029fec104cd556b828 Mon Sep 17 00:00:00 2001 From: Michael Victor Zink Date: Tue, 19 Nov 2024 10:02:35 -0800 Subject: [PATCH 2/2] Simplify bitstring tests --- tests/sqlparser_mysql.rs | 22 +--------------------- tests/sqlparser_postgres.rs | 22 +--------------------- 2 files changed, 2 insertions(+), 42 deletions(-) diff --git a/tests/sqlparser_mysql.rs b/tests/sqlparser_mysql.rs index 438c14730..ce3296737 100644 --- a/tests/sqlparser_mysql.rs +++ b/tests/sqlparser_mysql.rs @@ -2962,7 +2962,7 @@ fn parse_logical_xor() { } #[test] -fn parse_bitstring_literal_in_projection_is_not_alias() { +fn parse_bitstring_literal() { let select = mysql_and_generic().verified_only_select("SELECT B'111'"); assert_eq!( select.projection, @@ -2971,23 +2971,3 @@ fn parse_bitstring_literal_in_projection_is_not_alias() { ))] ); } - -#[test] -fn parse_bitstring_literal_in_insert_value_succeeds() { - let stmt = mysql_and_generic().verified_stmt("INSERT INTO foo VALUES (B'111')"); - match &stmt { - Statement::Insert(Insert { - source: Some(query), - .. - }) => assert_eq!( - *query.body, - SetExpr::Values(Values { - explicit_row: false, - rows: vec![vec![Expr::Value(Value::SingleQuotedByteStringLiteral( - "111".to_string() - ))]] - }) - ), - _ => unreachable!(), - } -} diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs index f798d1535..2e2c4403c 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -5100,7 +5100,7 @@ fn parse_create_type_as_enum() { } #[test] -fn parse_bitstring_literal_in_projection_is_not_alias() { +fn parse_bitstring_literal() { let select = pg_and_generic().verified_only_select("SELECT B'111'"); assert_eq!( select.projection, @@ -5109,23 +5109,3 @@ fn parse_bitstring_literal_in_projection_is_not_alias() { ))] ); } - -#[test] -fn parse_bitstring_literal_in_insert_value_succeeds() { - let stmt = pg_and_generic().verified_stmt("INSERT INTO foo VALUES (B'111')"); - match &stmt { - Statement::Insert(Insert { - source: Some(query), - .. - }) => assert_eq!( - *query.body, - SetExpr::Values(Values { - explicit_row: false, - rows: vec![vec![Expr::Value(Value::SingleQuotedByteStringLiteral( - "111".to_string() - ))]] - }) - ), - _ => unreachable!(), - } -}