mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-10-12 23:12:01 +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;
|
pub use crate::keywords;
|
||||||
use crate::parser::{Parser, ParserError};
|
use crate::parser::{Parser, ParserError};
|
||||||
|
|
||||||
/// `dialect_of!(parser is SQLiteDialect | GenericDialect)` evaluates
|
#[cfg(not(feature = "std"))]
|
||||||
/// to `true` if `parser.dialect` is one of the `Dialect`s specified.
|
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 {
|
macro_rules! dialect_of {
|
||||||
( $parsed_dialect: ident is $($dialect_type: ty)|+ ) => {
|
( $parsed_dialect: ident is $($dialect_type: ty)|+ ) => {
|
||||||
($($parsed_dialect.dialect.is::<$dialect_type>())||+)
|
($($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 {
|
pub trait Dialect: Debug + Any {
|
||||||
/// Determine if a character starts a quoted identifier. The default
|
/// Determine if a character starts a quoted identifier. The default
|
||||||
/// implementation, accepting "double quoted" ids is both ANSI-compliant
|
/// 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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::ansi::AnsiDialect;
|
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 | AnsiDialect));
|
||||||
assert!(!dialect_of!(ansi_holder is GenericDialect | MsSqlDialect));
|
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;
|
use crate::dialect::Dialect;
|
||||||
|
|
||||||
|
// [Microsoft SQL Server](https://www.microsoft.com/en-us/sql-server/) dialect
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MsSqlDialect {}
|
pub struct MsSqlDialect {}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
use crate::dialect::Dialect;
|
use crate::dialect::Dialect;
|
||||||
|
|
||||||
|
/// [MySQL](https://www.mysql.com/)
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MySqlDialect {}
|
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
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// 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
|
//! 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.
|
//! for more information.
|
||||||
//!
|
//!
|
||||||
//! See [`Parser::parse_sql`](crate::parser::Parser::parse_sql) and
|
//! For more information:
|
||||||
//! [`Parser::new`](crate::parser::Parser::new) for the Parsing API
|
//! 1. [`Parser::parse_sql`] and [`Parser::new`] for the Parsing API
|
||||||
//! and the [`ast`](crate::ast) crate for the AST structure.
|
//! 2. [`ast`] for the AST structure
|
||||||
|
//! 3. [`Dialect`] for supported SQL dialects
|
||||||
//!
|
//!
|
||||||
//! Example:
|
//! # Example
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! use sqlparser::dialect::GenericDialect;
|
//! use sqlparser::dialect::GenericDialect;
|
||||||
|
@ -37,7 +38,13 @@
|
||||||
//!
|
//!
|
||||||
//! println!("AST: {:?}", ast);
|
//! println!("AST: {:?}", ast);
|
||||||
//! ```
|
//! ```
|
||||||
|
//!
|
||||||
//! [sqlparser crates.io page]: https://crates.io/crates/sqlparser
|
//! [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)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
#![allow(clippy::upper_case_acronyms)]
|
#![allow(clippy::upper_case_acronyms)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue