mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-31 11:17:23 +00:00
Add dialect_from_str
and improve Dialect
documentation (#848)
* Add `dialect_from_str` and improve `Dialect` documentation * cleanup * fix compilation with nostd
This commit is contained in:
parent
d8af92536c
commit
5ecf633e31
4 changed files with 99 additions and 8 deletions
|
@ -42,14 +42,47 @@ pub use self::sqlite::SQLiteDialect;
|
|||
pub use crate::keywords;
|
||||
use crate::parser::{Parser, ParserError};
|
||||
|
||||
/// `dialect_of!(parser is SQLiteDialect | GenericDialect)` evaluates
|
||||
/// to `true` if `parser.dialect` is one of the `Dialect`s specified.
|
||||
#[cfg(not(feature = "std"))]
|
||||
use alloc::boxed::Box;
|
||||
|
||||
/// Convenience check if a [`Parser`] uses a certain dialect.
|
||||
///
|
||||
/// `dialect_of!(parser Is SQLiteDialect | GenericDialect)` evaluates
|
||||
/// to `true` if `parser.dialect` is one of the [`Dialect`]s specified.
|
||||
macro_rules! dialect_of {
|
||||
( $parsed_dialect: ident is $($dialect_type: ty)|+ ) => {
|
||||
($($parsed_dialect.dialect.is::<$dialect_type>())||+)
|
||||
};
|
||||
}
|
||||
|
||||
/// Encapsulates the differences between SQL implementations.
|
||||
///
|
||||
/// # SQL Dialects
|
||||
/// SQL implementations deviatiate from one another, either due to
|
||||
/// custom extensions or various historical reasons. This trait
|
||||
/// encapsulates the parsing differences between dialects.
|
||||
///
|
||||
/// # Examples
|
||||
/// Most users create a [`Dialect`] directly, as shown on the [module
|
||||
/// level documentation]:
|
||||
///
|
||||
/// ```
|
||||
/// # use sqlparser::dialect::AnsiDialect;
|
||||
/// let dialect = AnsiDialect {};
|
||||
/// ```
|
||||
///
|
||||
/// It is also possible to dynamically create a [`Dialect`] from its
|
||||
/// name. For example:
|
||||
///
|
||||
/// ```
|
||||
/// # use sqlparser::dialect::{AnsiDialect, dialect_from_str};
|
||||
/// let dialect = dialect_from_str("ansi").unwrap();
|
||||
///
|
||||
/// // Parsed dialect is an instance of `AnsiDialect`:
|
||||
/// assert!(dialect.is::<AnsiDialect>());
|
||||
/// ```
|
||||
///
|
||||
/// [module level documentation]: crate
|
||||
pub trait Dialect: Debug + Any {
|
||||
/// Determine if a character starts a quoted identifier. The default
|
||||
/// implementation, accepting "double quoted" ids is both ANSI-compliant
|
||||
|
@ -113,6 +146,27 @@ impl dyn Dialect {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the built in [`Dialect`] corresponding to `dialect_name`.
|
||||
///
|
||||
/// See [`Dialect`] documentation for an example.
|
||||
pub fn dialect_from_str(dialect_name: impl AsRef<str>) -> Option<Box<dyn Dialect>> {
|
||||
let dialect_name = dialect_name.as_ref();
|
||||
match dialect_name.to_lowercase().as_str() {
|
||||
"generic" => Some(Box::new(GenericDialect)),
|
||||
"mysql" => Some(Box::new(MySqlDialect {})),
|
||||
"postgresql" | "postgres" => Some(Box::new(PostgreSqlDialect {})),
|
||||
"hive" => Some(Box::new(HiveDialect {})),
|
||||
"sqlite" => Some(Box::new(SQLiteDialect {})),
|
||||
"snowflake" => Some(Box::new(SnowflakeDialect)),
|
||||
"redshift" => Some(Box::new(RedshiftSqlDialect {})),
|
||||
"mssql" => Some(Box::new(MsSqlDialect {})),
|
||||
"clickhouse" => Some(Box::new(ClickHouseDialect {})),
|
||||
"bigquery" => Some(Box::new(BigQueryDialect)),
|
||||
"ansi" => Some(Box::new(AnsiDialect {})),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::ansi::AnsiDialect;
|
||||
|
@ -141,4 +195,32 @@ mod tests {
|
|||
assert!(dialect_of!(ansi_holder is GenericDialect | AnsiDialect));
|
||||
assert!(!dialect_of!(ansi_holder is GenericDialect | MsSqlDialect));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dialect_from_str() {
|
||||
assert!(parse_dialect("generic").is::<GenericDialect>());
|
||||
assert!(parse_dialect("mysql").is::<MySqlDialect>());
|
||||
assert!(parse_dialect("MySql").is::<MySqlDialect>());
|
||||
assert!(parse_dialect("postgresql").is::<PostgreSqlDialect>());
|
||||
assert!(parse_dialect("postgres").is::<PostgreSqlDialect>());
|
||||
assert!(parse_dialect("hive").is::<HiveDialect>());
|
||||
assert!(parse_dialect("sqlite").is::<SQLiteDialect>());
|
||||
assert!(parse_dialect("snowflake").is::<SnowflakeDialect>());
|
||||
assert!(parse_dialect("SnowFlake").is::<SnowflakeDialect>());
|
||||
assert!(parse_dialect("MsSql").is::<MsSqlDialect>());
|
||||
assert!(parse_dialect("clickhouse").is::<ClickHouseDialect>());
|
||||
assert!(parse_dialect("ClickHouse").is::<ClickHouseDialect>());
|
||||
assert!(parse_dialect("bigquery").is::<BigQueryDialect>());
|
||||
assert!(parse_dialect("BigQuery").is::<BigQueryDialect>());
|
||||
assert!(parse_dialect("ansi").is::<AnsiDialect>());
|
||||
assert!(parse_dialect("ANSI").is::<AnsiDialect>());
|
||||
|
||||
// error cases
|
||||
assert!(dialect_from_str("Unknown").is_none());
|
||||
assert!(dialect_from_str("").is_none());
|
||||
}
|
||||
|
||||
fn parse_dialect(v: &str) -> Box<dyn Dialect> {
|
||||
dialect_from_str(v).unwrap()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
use crate::dialect::Dialect;
|
||||
|
||||
// [Microsoft SQL Server](https://www.microsoft.com/en-us/sql-server/) dialect
|
||||
#[derive(Debug)]
|
||||
pub struct MsSqlDialect {}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
use crate::dialect::Dialect;
|
||||
|
||||
/// [MySQL](https://www.mysql.com/)
|
||||
#[derive(Debug)]
|
||||
pub struct MySqlDialect {}
|
||||
|
||||
|
|
19
src/lib.rs
19
src/lib.rs
|
@ -10,17 +10,18 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! SQL Parser for Rust
|
||||
//! # SQL Parser for Rust
|
||||
//!
|
||||
//! This crate provides an ANSI:SQL 2011 lexer and parser that can parse SQL
|
||||
//! into an Abstract Syntax Tree (AST). See the [sqlparser crates.io page]
|
||||
//! into an Abstract Syntax Tree ([`AST`]). See the [sqlparser crates.io page]
|
||||
//! for more information.
|
||||
//!
|
||||
//! See [`Parser::parse_sql`](crate::parser::Parser::parse_sql) and
|
||||
//! [`Parser::new`](crate::parser::Parser::new) for the Parsing API
|
||||
//! and the [`ast`](crate::ast) crate for the AST structure.
|
||||
//! For more information:
|
||||
//! 1. [`Parser::parse_sql`] and [`Parser::new`] for the Parsing API
|
||||
//! 2. [`ast`] for the AST structure
|
||||
//! 3. [`Dialect`] for supported SQL dialects
|
||||
//!
|
||||
//! Example:
|
||||
//! # Example
|
||||
//!
|
||||
//! ```
|
||||
//! use sqlparser::dialect::GenericDialect;
|
||||
|
@ -37,7 +38,13 @@
|
|||
//!
|
||||
//! println!("AST: {:?}", ast);
|
||||
//! ```
|
||||
//!
|
||||
//! [sqlparser crates.io page]: https://crates.io/crates/sqlparser
|
||||
//! [`Parser::parse_sql`]: crate::parser::Parser::parse_sql
|
||||
//! [`Parser::new`]: crate::parser::Parser::new
|
||||
//! [`AST`]: crate::ast
|
||||
//! [`ast`]: crate::ast
|
||||
//! [`Dialect`]: crate::dialect::Dialect
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![allow(clippy::upper_case_acronyms)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue