From 05f003eeaed990a1a1812e7d80281570eada97ad Mon Sep 17 00:00:00 2001 From: Michiel De Backker Date: Sun, 10 Mar 2024 13:24:18 +0100 Subject: [PATCH 1/2] feat: add identifier quote style to dialect relates to apache/arrow-datafusion#9517 --- src/dialect/mod.rs | 4 ++++ src/dialect/mysql.rs | 4 ++++ src/dialect/postgresql.rs | 4 ++++ src/dialect/sqlite.rs | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/src/dialect/mod.rs b/src/dialect/mod.rs index c53670263..5109982be 100644 --- a/src/dialect/mod.rs +++ b/src/dialect/mod.rs @@ -108,6 +108,10 @@ pub trait Dialect: Debug + Any { fn is_delimited_identifier_start(&self, ch: char) -> bool { ch == '"' || ch == '`' } + /// Return the character used to quote identifiers. + fn identifier_quote_style(&self, _identifier: &str) -> Option { + None + } /// Determine if quoted characters are proper for identifier fn is_proper_identifier_inside_quotes(&self, mut _chars: Peekable>) -> bool { true diff --git a/src/dialect/mysql.rs b/src/dialect/mysql.rs index 95b358a7e..d0dbe923c 100644 --- a/src/dialect/mysql.rs +++ b/src/dialect/mysql.rs @@ -44,6 +44,10 @@ impl Dialect for MySqlDialect { ch == '`' } + fn identifier_quote_style(&self, _identifier: &str) -> Option { + Some('`') + } + fn parse_infix( &self, parser: &mut crate::parser::Parser, diff --git a/src/dialect/postgresql.rs b/src/dialect/postgresql.rs index cbd150511..f179111e0 100644 --- a/src/dialect/postgresql.rs +++ b/src/dialect/postgresql.rs @@ -21,6 +21,10 @@ use crate::tokenizer::Token; pub struct PostgreSqlDialect {} impl Dialect for PostgreSqlDialect { + fn identifier_quote_style(&self, _identifier: &str) -> Option { + Some('"') + } + fn is_identifier_start(&self, ch: char) -> bool { // See https://www.postgresql.org/docs/11/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS // We don't yet support identifiers beginning with "letters with diff --git a/src/dialect/sqlite.rs b/src/dialect/sqlite.rs index 622fddee6..daad6a159 100644 --- a/src/dialect/sqlite.rs +++ b/src/dialect/sqlite.rs @@ -32,6 +32,10 @@ impl Dialect for SQLiteDialect { ch == '`' || ch == '"' || ch == '[' } + fn identifier_quote_style(&self, _identifier: &str) -> Option { + Some('`') + } + fn is_identifier_start(&self, ch: char) -> bool { // See https://www.sqlite.org/draft/tokenreq.html ch.is_ascii_lowercase() From 3762358f05ef46ee1fd7656efe86f242264e2037 Mon Sep 17 00:00:00 2001 From: Michiel De Backker Date: Mon, 11 Mar 2024 20:01:50 +0100 Subject: [PATCH 2/2] test: identifier quote style --- src/dialect/mod.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/dialect/mod.rs b/src/dialect/mod.rs index 5109982be..682e5924c 100644 --- a/src/dialect/mod.rs +++ b/src/dialect/mod.rs @@ -266,6 +266,21 @@ mod tests { dialect_from_str(v).unwrap() } + #[test] + fn identifier_quote_style() { + let tests: Vec<(&dyn Dialect, &str, Option)> = vec![ + (&GenericDialect {}, "id", None), + (&SQLiteDialect {}, "id", Some('`')), + (&PostgreSqlDialect {}, "id", Some('"')), + ]; + + for (dialect, ident, expected) in tests { + let actual = dialect.identifier_quote_style(ident); + + assert_eq!(actual, expected); + } + } + #[test] fn parse_with_wrapped_dialect() { /// Wrapper for a dialect. In a real-world example, this wrapper @@ -287,6 +302,10 @@ mod tests { self.0.is_delimited_identifier_start(ch) } + fn identifier_quote_style(&self, identifier: &str) -> Option { + self.0.identifier_quote_style(identifier) + } + fn is_proper_identifier_inside_quotes( &self, chars: std::iter::Peekable>,