polyglot_sql/dialects/
datafusion.rs1use super::{DialectImpl, DialectType};
21use crate::error::Result;
22use crate::expressions::{Expression, Function};
23#[cfg(feature = "generate")]
24use crate::generator::GeneratorConfig;
25use crate::tokens::TokenizerConfig;
26
27pub struct DataFusionDialect;
29
30impl DialectImpl for DataFusionDialect {
31 fn dialect_type(&self) -> DialectType {
32 DialectType::DataFusion
33 }
34
35 fn tokenizer_config(&self) -> TokenizerConfig {
36 let mut config = TokenizerConfig::default();
37 config.identifiers.insert('"', '"');
39 config.nested_comments = true;
41 config
42 }
43
44 #[cfg(feature = "generate")]
45
46 fn generator_config(&self) -> GeneratorConfig {
47 use crate::generator::{IdentifierQuoteStyle, LimitFetchStyle, NormalizeFunctions};
48 GeneratorConfig {
49 identifier_quote: '"',
50 identifier_quote_style: IdentifierQuoteStyle::DOUBLE_QUOTE,
51 dialect: Some(DialectType::DataFusion),
52 normalize_functions: NormalizeFunctions::Lower,
54 try_supported: true,
56 star_except: "EXCEPT",
58 multi_arg_distinct: false,
60 supports_window_exclude: false,
62 interval_allows_plural_form: true,
64 normalize_extract_date_parts: true,
66 limit_fetch_style: LimitFetchStyle::Limit,
68 join_hints: false,
70 table_hints: false,
71 query_hints: false,
72 semi_anti_join_with_side: true,
74 copy_has_into_keyword: false,
76 nvl2_supported: true,
78 supports_median: true,
80 can_implement_array_any: true,
82 supports_like_quantifiers: false,
84 aggregate_filter_supported: true,
86 supports_between_flags: false,
88 ..Default::default()
89 }
90 }
91
92 #[cfg(feature = "transpile")]
93
94 fn transform_expr(&self, expr: Expression) -> Result<Expression> {
95 match expr {
96 Expression::Function(f) => self.transform_function(*f),
98
99 Expression::AggregateFunction(f) => self.transform_aggregate_function(f),
101
102 _ => Ok(expr),
104 }
105 }
106}
107
108#[cfg(feature = "transpile")]
109impl DataFusionDialect {
110 fn transform_function(&self, f: Function) -> Result<Expression> {
111 let name_upper = f.name.to_uppercase();
112 match name_upper.as_str() {
113 "IFNULL" => Ok(Expression::Function(Box::new(Function::new(
115 "coalesce".to_string(),
116 f.args,
117 )))),
118
119 "SQUARE" => {
121 let mut args = f.args;
122 args.push(Expression::Literal(Box::new(
123 crate::expressions::Literal::Number("2".to_string()),
124 )));
125 Ok(Expression::Function(Box::new(Function::new(
126 "power".to_string(),
127 args,
128 ))))
129 }
130
131 "REGEXP_MATCHES" => Ok(Expression::Function(Box::new(Function::new(
133 "regexp_match".to_string(),
134 f.args,
135 )))),
136
137 "DATE_FORMAT" | "TIME_TO_STR" => Ok(Expression::Function(Box::new(Function::new(
139 "to_char".to_string(),
140 f.args,
141 )))),
142
143 _ => Ok(Expression::Function(Box::new(f))),
145 }
146 }
147
148 fn transform_aggregate_function(
149 &self,
150 f: Box<crate::expressions::AggregateFunction>,
151 ) -> Result<Expression> {
152 let name_upper = f.name.to_uppercase();
153 match name_upper.as_str() {
154 "GROUP_CONCAT" => Ok(Expression::Function(Box::new(Function::new(
156 "string_agg".to_string(),
157 f.args,
158 )))),
159
160 "LISTAGG" => Ok(Expression::Function(Box::new(Function::new(
162 "string_agg".to_string(),
163 f.args,
164 )))),
165
166 _ => Ok(Expression::AggregateFunction(f)),
168 }
169 }
170}