polyglot_sql/dialects/
tableau.rs1use super::{DialectImpl, DialectType};
14use crate::error::Result;
15use crate::expressions::{Expression, Function};
16#[cfg(feature = "generate")]
17use crate::generator::GeneratorConfig;
18use crate::tokens::TokenizerConfig;
19
20pub struct TableauDialect;
22
23impl DialectImpl for TableauDialect {
24 fn dialect_type(&self) -> DialectType {
25 DialectType::Tableau
26 }
27
28 fn tokenizer_config(&self) -> TokenizerConfig {
29 let mut config = TokenizerConfig::default();
30 config.identifiers.insert('[', ']');
32 config
33 }
34
35 #[cfg(feature = "generate")]
36
37 fn generator_config(&self) -> GeneratorConfig {
38 use crate::generator::IdentifierQuoteStyle;
39 GeneratorConfig {
40 identifier_quote: '[',
41 identifier_quote_style: IdentifierQuoteStyle::BRACKET,
42 dialect: Some(DialectType::Tableau),
43 ..Default::default()
44 }
45 }
46
47 #[cfg(feature = "transpile")]
48
49 fn transform_expr(&self, expr: Expression) -> Result<Expression> {
50 match expr {
51 Expression::Coalesce(f) => {
53 if f.expressions.len() == 2 {
54 Ok(Expression::Function(Box::new(Function::new(
55 "IFNULL".to_string(),
56 f.expressions,
57 ))))
58 } else {
59 Ok(Expression::Coalesce(f))
61 }
62 }
63
64 Expression::Nvl(f) => Ok(Expression::Function(Box::new(Function::new(
66 "IFNULL".to_string(),
67 vec![f.this, f.expression],
68 )))),
69
70 Expression::IfNull(f) => Ok(Expression::Function(Box::new(Function::new(
72 "IFNULL".to_string(),
73 vec![f.this, f.expression],
74 )))),
75
76 Expression::Function(f) => self.transform_function(*f),
78
79 Expression::AggregateFunction(f) => self.transform_aggregate_function(f),
81
82 _ => Ok(expr),
84 }
85 }
86}
87
88#[cfg(feature = "transpile")]
89impl TableauDialect {
90 fn transform_function(&self, f: Function) -> Result<Expression> {
91 let name_upper = f.name.to_uppercase();
92 match name_upper.as_str() {
93 "COALESCE" if f.args.len() == 2 => Ok(Expression::Function(Box::new(Function::new(
95 "IFNULL".to_string(),
96 f.args,
97 )))),
98
99 "NVL" if f.args.len() == 2 => Ok(Expression::Function(Box::new(Function::new(
101 "IFNULL".to_string(),
102 f.args,
103 )))),
104
105 "ISNULL" if f.args.len() == 2 => Ok(Expression::Function(Box::new(Function::new(
107 "IFNULL".to_string(),
108 f.args,
109 )))),
110
111 "STRPOS" | "POSITION" | "INSTR" if f.args.len() >= 2 => Ok(Expression::Function(
113 Box::new(Function::new("FIND".to_string(), f.args)),
114 )),
115
116 "CHARINDEX" if f.args.len() >= 2 => Ok(Expression::Function(Box::new(Function::new(
118 "FIND".to_string(),
119 f.args,
120 )))),
121
122 _ => Ok(Expression::Function(Box::new(f))),
124 }
125 }
126
127 fn transform_aggregate_function(
128 &self,
129 f: Box<crate::expressions::AggregateFunction>,
130 ) -> Result<Expression> {
131 let name_upper = f.name.to_uppercase();
132 match name_upper.as_str() {
133 "COUNT" if f.distinct => Ok(Expression::Function(Box::new(Function::new(
135 "COUNTD".to_string(),
136 f.args,
137 )))),
138
139 _ => Ok(Expression::AggregateFunction(f)),
141 }
142 }
143}