use super::{DialectImpl, DialectType};
use crate::error::Result;
use crate::expressions::{Expression, Function};
use crate::generator::GeneratorConfig;
use crate::tokens::TokenizerConfig;
pub struct TableauDialect;
impl DialectImpl for TableauDialect {
fn dialect_type(&self) -> DialectType {
DialectType::Tableau
}
fn tokenizer_config(&self) -> TokenizerConfig {
let mut config = TokenizerConfig::default();
config.identifiers.insert('[', ']');
config
}
fn generator_config(&self) -> GeneratorConfig {
use crate::generator::IdentifierQuoteStyle;
GeneratorConfig {
identifier_quote: '[',
identifier_quote_style: IdentifierQuoteStyle::BRACKET,
dialect: Some(DialectType::Tableau),
..Default::default()
}
}
fn transform_expr(&self, expr: Expression) -> Result<Expression> {
match expr {
Expression::Coalesce(f) => {
if f.expressions.len() == 2 {
Ok(Expression::Function(Box::new(Function::new(
"IFNULL".to_string(),
f.expressions,
))))
} else {
Ok(Expression::Coalesce(f))
}
}
Expression::Nvl(f) => Ok(Expression::Function(Box::new(Function::new(
"IFNULL".to_string(),
vec![f.this, f.expression],
)))),
Expression::IfNull(f) => Ok(Expression::Function(Box::new(Function::new(
"IFNULL".to_string(),
vec![f.this, f.expression],
)))),
Expression::Function(f) => self.transform_function(*f),
Expression::AggregateFunction(f) => self.transform_aggregate_function(f),
_ => Ok(expr),
}
}
}
impl TableauDialect {
fn transform_function(&self, f: Function) -> Result<Expression> {
let name_upper = f.name.to_uppercase();
match name_upper.as_str() {
"COALESCE" if f.args.len() == 2 => Ok(Expression::Function(Box::new(Function::new(
"IFNULL".to_string(),
f.args,
)))),
"NVL" if f.args.len() == 2 => Ok(Expression::Function(Box::new(Function::new(
"IFNULL".to_string(),
f.args,
)))),
"ISNULL" if f.args.len() == 2 => Ok(Expression::Function(Box::new(Function::new(
"IFNULL".to_string(),
f.args,
)))),
"STRPOS" | "POSITION" | "INSTR" if f.args.len() >= 2 => Ok(Expression::Function(
Box::new(Function::new("FIND".to_string(), f.args)),
)),
"CHARINDEX" if f.args.len() >= 2 => Ok(Expression::Function(Box::new(Function::new(
"FIND".to_string(),
f.args,
)))),
_ => Ok(Expression::Function(Box::new(f))),
}
}
fn transform_aggregate_function(
&self,
f: Box<crate::expressions::AggregateFunction>,
) -> Result<Expression> {
let name_upper = f.name.to_uppercase();
match name_upper.as_str() {
"COUNT" if f.distinct => Ok(Expression::Function(Box::new(Function::new(
"COUNTD".to_string(),
f.args,
)))),
_ => Ok(Expression::AggregateFunction(f)),
}
}
}