1use super::{DialectImpl, DialectType};
17use crate::error::Result;
18use crate::expressions::{BinaryFunc, CeilFunc, Expression, Function, LikeOp, UnaryFunc};
19use crate::generator::GeneratorConfig;
20use crate::tokens::TokenizerConfig;
21
22pub struct OracleDialect;
24
25impl DialectImpl for OracleDialect {
26 fn dialect_type(&self) -> DialectType {
27 DialectType::Oracle
28 }
29
30 fn tokenizer_config(&self) -> TokenizerConfig {
31 let mut config = TokenizerConfig::default();
32 config.identifiers.insert('"', '"');
34 config.nested_comments = false;
36 config
37 }
38
39 fn generator_config(&self) -> GeneratorConfig {
40 use crate::generator::IdentifierQuoteStyle;
41 GeneratorConfig {
42 identifier_quote: '"',
43 identifier_quote_style: IdentifierQuoteStyle::DOUBLE_QUOTE,
44 dialect: Some(DialectType::Oracle),
45 supports_column_join_marks: true,
46 alter_table_include_column_keyword: false,
48 tablesample_keywords: "SAMPLE",
50 alias_post_tablesample: true,
52 tz_to_with_time_zone: true,
54 ..Default::default()
55 }
56 }
57
58 fn transform_expr(&self, expr: Expression) -> Result<Expression> {
59 match expr {
60 Expression::IfNull(f) => Ok(Expression::Nvl(f)),
62
63 Expression::Coalesce(f) if f.expressions.len() == 2 => {
65 let mut exprs = f.expressions;
66 let second = exprs.pop().unwrap();
67 let first = exprs.pop().unwrap();
68 Ok(Expression::Nvl(Box::new(BinaryFunc {
69 original_name: None,
70 this: first,
71 expression: second,
72 inferred_type: None,
73 })))
74 }
75
76 Expression::Nvl(f) => Ok(Expression::Nvl(f)),
78
79 Expression::TryCast(c) => Ok(Expression::Cast(c)),
81
82 Expression::SafeCast(c) => Ok(Expression::Cast(c)),
84
85 Expression::ILike(op) => {
87 let lower_left = Expression::Lower(Box::new(UnaryFunc::new(op.left)));
88 let lower_right = Expression::Lower(Box::new(UnaryFunc::new(op.right)));
89 Ok(Expression::Like(Box::new(LikeOp {
90 left: lower_left,
91 right: lower_right,
92 escape: op.escape,
93 quantifier: op.quantifier,
94 inferred_type: None,
95 })))
96 }
97
98 Expression::Random(_) => Ok(Expression::Function(Box::new(Function::new(
100 "DBMS_RANDOM.VALUE".to_string(),
101 vec![],
102 )))),
103
104 Expression::Rand(_) => Ok(Expression::Function(Box::new(Function::new(
106 "DBMS_RANDOM.VALUE".to_string(),
107 vec![],
108 )))),
109
110 Expression::Concat(op) => Ok(Expression::Concat(op)),
112
113 Expression::Unnest(f) => Ok(Expression::Function(Box::new(Function::new(
116 "TABLE".to_string(),
117 vec![f.this],
118 )))),
119
120 Expression::Explode(f) => Ok(Expression::Function(Box::new(Function::new(
122 "TABLE".to_string(),
123 vec![f.this],
124 )))),
125
126 Expression::Function(f) => self.transform_function(*f),
128
129 Expression::AggregateFunction(f) => self.transform_aggregate_function(f),
131
132 _ => Ok(expr),
134 }
135 }
136}
137
138impl OracleDialect {
139 fn transform_function(&self, f: Function) -> Result<Expression> {
140 let name_upper = f.name.to_uppercase();
141 match name_upper.as_str() {
142 "IFNULL" if f.args.len() == 2 => {
144 let mut args = f.args;
145 let second = args.pop().unwrap();
146 let first = args.pop().unwrap();
147 Ok(Expression::Nvl(Box::new(BinaryFunc {
148 original_name: None,
149 this: first,
150 expression: second,
151 inferred_type: None,
152 })))
153 }
154
155 "ISNULL" if f.args.len() == 2 => {
157 let mut args = f.args;
158 let second = args.pop().unwrap();
159 let first = args.pop().unwrap();
160 Ok(Expression::Nvl(Box::new(BinaryFunc {
161 original_name: None,
162 this: first,
163 expression: second,
164 inferred_type: None,
165 })))
166 }
167
168 "NVL" if f.args.len() == 2 => {
170 let mut args = f.args;
171 let second = args.pop().unwrap();
172 let first = args.pop().unwrap();
173 Ok(Expression::Nvl(Box::new(BinaryFunc {
174 original_name: None,
175 this: first,
176 expression: second,
177 inferred_type: None,
178 })))
179 }
180
181 "NVL2" => Ok(Expression::Function(Box::new(f))),
183
184 "GROUP_CONCAT" if !f.args.is_empty() => Ok(Expression::Function(Box::new(
186 Function::new("LISTAGG".to_string(), f.args),
187 ))),
188
189 "STRING_AGG" if !f.args.is_empty() => Ok(Expression::Function(Box::new(
191 Function::new("LISTAGG".to_string(), f.args),
192 ))),
193
194 "LISTAGG" => Ok(Expression::Function(Box::new(f))),
196
197 "SUBSTRING" => Ok(Expression::Function(Box::new(Function::new(
199 "SUBSTR".to_string(),
200 f.args,
201 )))),
202
203 "SUBSTR" => Ok(Expression::Function(Box::new(f))),
205
206 "LENGTH" => Ok(Expression::Function(Box::new(f))),
208
209 "LEN" if f.args.len() == 1 => Ok(Expression::Length(Box::new(UnaryFunc::new(
211 f.args.into_iter().next().unwrap(),
212 )))),
213
214 "RANDOM" | "RAND" => Ok(Expression::Function(Box::new(Function::new(
216 "DBMS_RANDOM.VALUE".to_string(),
217 vec![],
218 )))),
219
220 "NOW" => Ok(Expression::CurrentTimestamp(
222 crate::expressions::CurrentTimestamp {
223 precision: None,
224 sysdate: false,
225 },
226 )),
227
228 "GETDATE" => Ok(Expression::Function(Box::new(Function::new(
230 "SYSDATE".to_string(),
231 vec![],
232 )))),
233
234 "CURRENT_TIMESTAMP" => {
237 if f.args.is_empty() {
238 Ok(Expression::CurrentTimestamp(
239 crate::expressions::CurrentTimestamp {
240 precision: None,
241 sysdate: false,
242 },
243 ))
244 } else if f.args.len() == 1 {
245 if let Expression::Literal(crate::expressions::Literal::Number(n)) = &f.args[0]
247 {
248 if let Ok(precision) = n.parse::<u32>() {
249 return Ok(Expression::CurrentTimestamp(
250 crate::expressions::CurrentTimestamp {
251 precision: Some(precision),
252 sysdate: false,
253 },
254 ));
255 }
256 }
257 Ok(Expression::Function(Box::new(f)))
259 } else {
260 Ok(Expression::Function(Box::new(f)))
262 }
263 }
264
265 "CURRENT_DATE" => Ok(Expression::CurrentDate(crate::expressions::CurrentDate)),
267
268 "TO_DATE" => Ok(Expression::Function(Box::new(f))),
270
271 "TO_TIMESTAMP" => Ok(Expression::Function(Box::new(f))),
273
274 "TO_CHAR" => Ok(Expression::Function(Box::new(f))),
276
277 "DATE_FORMAT" => Ok(Expression::Function(Box::new(Function::new(
279 "TO_CHAR".to_string(),
280 f.args,
281 )))),
282
283 "STRFTIME" => Ok(Expression::Function(Box::new(Function::new(
285 "TO_CHAR".to_string(),
286 f.args,
287 )))),
288
289 "DATE_TRUNC" => Ok(Expression::Function(Box::new(Function::new(
291 "TRUNC".to_string(),
292 f.args,
293 )))),
294
295 "TRUNC" if f.args.len() == 1 => {
299 let mut args = f.args;
300 args.push(Expression::Literal(crate::expressions::Literal::String(
301 "DD".to_string(),
302 )));
303 Ok(Expression::Function(Box::new(Function::new(
304 "TRUNC".to_string(),
305 args,
306 ))))
307 }
308
309 "EXTRACT" => Ok(Expression::Function(Box::new(f))),
311
312 "POSITION" if f.args.len() == 2 => {
315 let mut args = f.args;
316 let first = args.remove(0);
317 let second = args.remove(0);
318 Ok(Expression::Function(Box::new(Function::new(
320 "INSTR".to_string(),
321 vec![second, first],
322 ))))
323 }
324
325 "STRPOS" if f.args.len() == 2 => Ok(Expression::Function(Box::new(Function::new(
327 "INSTR".to_string(),
328 f.args,
329 )))),
330
331 "CHARINDEX" if f.args.len() >= 2 => {
333 let mut args = f.args;
334 let substring = args.remove(0);
335 let string = args.remove(0);
336 let mut instr_args = vec![string, substring];
338 if !args.is_empty() {
339 instr_args.push(args.remove(0));
340 }
341 Ok(Expression::Function(Box::new(Function::new(
342 "INSTR".to_string(),
343 instr_args,
344 ))))
345 }
346
347 "INSTR" => Ok(Expression::Function(Box::new(f))),
349
350 "CEILING" if f.args.len() == 1 => Ok(Expression::Ceil(Box::new(CeilFunc {
352 this: f.args.into_iter().next().unwrap(),
353 decimals: None,
354 to: None,
355 }))),
356
357 "CEIL" if f.args.len() == 1 => Ok(Expression::Ceil(Box::new(CeilFunc {
359 this: f.args.into_iter().next().unwrap(),
360 decimals: None,
361 to: None,
362 }))),
363
364 "LOG" if f.args.len() == 1 => Ok(Expression::Function(Box::new(Function::new(
367 "LN".to_string(),
368 f.args,
369 )))),
370
371 "LN" => Ok(Expression::Function(Box::new(f))),
373
374 "POWER" | "POW" => Ok(Expression::Function(Box::new(Function::new(
376 "POWER".to_string(),
377 f.args,
378 )))),
379
380 "REGEXP_LIKE" => Ok(Expression::Function(Box::new(f))),
382
383 "JSON_VALUE" => Ok(Expression::Function(Box::new(f))),
385
386 "JSON_QUERY" => Ok(Expression::Function(Box::new(f))),
388
389 "JSON_EXTRACT" => Ok(Expression::Function(Box::new(Function::new(
391 "JSON_VALUE".to_string(),
392 f.args,
393 )))),
394
395 "JSON_EXTRACT_SCALAR" => Ok(Expression::Function(Box::new(Function::new(
397 "JSON_VALUE".to_string(),
398 f.args,
399 )))),
400
401 "SPLIT" => {
404 Ok(Expression::Function(Box::new(Function::new(
406 "REGEXP_SUBSTR".to_string(),
407 f.args,
408 ))))
409 }
410
411 "ADD_MONTHS" => Ok(Expression::Function(Box::new(f))),
413
414 "MONTHS_BETWEEN" => Ok(Expression::Function(Box::new(f))),
416
417 "DATEADD" => {
419 Ok(Expression::Function(Box::new(f)))
421 }
422
423 "DATEDIFF" => Ok(Expression::Function(Box::new(f))),
425
426 "DECODE" => Ok(Expression::Function(Box::new(f))),
428
429 _ => Ok(Expression::Function(Box::new(f))),
431 }
432 }
433
434 fn transform_aggregate_function(
435 &self,
436 f: Box<crate::expressions::AggregateFunction>,
437 ) -> Result<Expression> {
438 let name_upper = f.name.to_uppercase();
439 match name_upper.as_str() {
440 "GROUP_CONCAT" if !f.args.is_empty() => Ok(Expression::Function(Box::new(
442 Function::new("LISTAGG".to_string(), f.args),
443 ))),
444
445 "STRING_AGG" if !f.args.is_empty() => Ok(Expression::Function(Box::new(
447 Function::new("LISTAGG".to_string(), f.args),
448 ))),
449
450 "ARRAY_AGG" if !f.args.is_empty() => Ok(Expression::Function(Box::new(Function::new(
453 "COLLECT".to_string(),
454 f.args,
455 )))),
456
457 _ => Ok(Expression::AggregateFunction(f)),
459 }
460 }
461}