From b36514da3aee9a39424fd60f64538c9870d943a4 Mon Sep 17 00:00:00 2001 From: lovasoa Date: Mon, 23 Oct 2023 15:33:00 +0200 Subject: [PATCH] add support for single-quoted identifiers This does not support single-quoted table names, but supports the most common case of select tablename.'column' from tablename --- src/parser/mod.rs | 38 ++++++++++++++++++++++++++------------ tests/sqlparser_sqlite.rs | 7 +++++++ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 95f1f8edc..523f7d21b 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -618,18 +618,29 @@ impl<'a> Parser<'a> { let next_token = self.next_token(); match next_token.token { - Token::Word(w) if self.peek_token().token == Token::Period => { - let mut id_parts: Vec = vec![w.to_ident()]; - - while self.consume_token(&Token::Period) { - let next_token = self.next_token(); - match next_token.token { - Token::Word(w) => id_parts.push(w.to_ident()), - Token::Mul => { - return Ok(WildcardExpr::QualifiedWildcard(ObjectName(id_parts))); - } - _ => { - return self.expected("an identifier or a '*' after '.'", next_token); + t @ (Token::Word(_) | Token::SingleQuotedString(_)) => { + if self.peek_token().token == Token::Period { + let mut id_parts: Vec = vec![match t { + Token::Word(w) => w.to_ident(), + Token::SingleQuotedString(s) => Ident::with_quote('\'', s), + Token::DoubleQuotedString(s) => Ident::with_quote('"', s), + _ => unreachable!(), // We matched above + }]; + + while self.consume_token(&Token::Period) { + let next_token = self.next_token(); + match next_token.token { + Token::Word(w) => id_parts.push(w.to_ident()), + Token::SingleQuotedString(s) => { // SQLite has single-quoted identifiers + id_parts.push(Ident::with_quote('\'', s)) + } + Token::Mul => { + return Ok(WildcardExpr::QualifiedWildcard(ObjectName(id_parts))); + } + _ => { + return self + .expected("an identifier or a '*' after '.'", next_token); + } } } } @@ -825,6 +836,9 @@ impl<'a> Parser<'a> { let next_token = self.next_token(); match next_token.token { Token::Word(w) => id_parts.push(w.to_ident()), + Token::SingleQuotedString(s) => { + id_parts.push(Ident::with_quote('\'', s)) + } _ => { return self .expected("an identifier or a '*' after '.'", next_token); diff --git a/tests/sqlparser_sqlite.rs b/tests/sqlparser_sqlite.rs index 39a82cc8b..5b0714959 100644 --- a/tests/sqlparser_sqlite.rs +++ b/tests/sqlparser_sqlite.rs @@ -290,6 +290,13 @@ fn parse_create_table_with_strict() { } } + +#[test] +fn parse_single_quoted_identified() { + sqlite().verified_only_select("SELECT 't'.*, t.'x' FROM 't'"); + // TODO: add support for select 't'.x +} + #[test] fn parse_attach_database() { let sql = "ATTACH DATABASE 'test.db' AS test";