1use std::{borrow::Cow, fmt, ops::Deref};
2
3use crate::*;
4
5const QUOTE: Quote = Quote(b'"', b'"');
6
7pub trait QueryBuilder:
8 QuotedBuilder + EscapeBuilder + TableRefBuilder + OperLeftAssocDecider + PrecedenceDecider + Sized
9{
10 fn placeholder(&self) -> (&'static str, bool) {
12 ("?", false)
13 }
14
15 fn values_list_tuple_prefix(&self) -> &str {
17 ""
18 }
19
20 fn prepare_insert_statement(&self, insert: &InsertStatement, sql: &mut impl SqlWriter) {
22 if let Some(with) = &insert.with {
23 self.prepare_with_clause(with, sql);
24 }
25
26 self.prepare_insert(insert.replace, sql);
27
28 if let Some(table) = &insert.table {
29 sql.write_str(" INTO ").unwrap();
30
31 self.prepare_table_ref(table, sql);
32 }
33
34 if insert.default_values.unwrap_or_default() != 0
35 && insert.columns.is_empty()
36 && insert.source.is_none()
37 {
38 self.prepare_output(&insert.returning, sql);
39 sql.write_str(" ").unwrap();
40 let num_rows = insert.default_values.unwrap();
41 self.insert_default_values(num_rows, sql);
42 } else {
43 sql.write_str(" (").unwrap();
44 let mut cols = insert.columns.iter();
45 join_io!(
46 cols,
47 col,
48 join {
49 sql.write_str(", ").unwrap();
50 },
51 do {
52 self.prepare_iden(col, sql);
53 }
54 );
55
56 sql.write_str(")").unwrap();
57
58 self.prepare_output(&insert.returning, sql);
59
60 if let Some(source) = &insert.source {
61 sql.write_str(" ").unwrap();
62 match source {
63 InsertValueSource::Values(values) => {
64 sql.write_str("VALUES ").unwrap();
65 let mut vals = values.iter();
66 join_io!(
67 vals,
68 row,
69 join {
70 sql.write_str(", ").unwrap();
71 },
72 do {
73 sql.write_str("(").unwrap();
74 let mut cols = row.iter();
75 join_io!(
76 cols,
77 col,
78 join {
79 sql.write_str(", ").unwrap();
80 },
81 do {
82 self.prepare_expr(col, sql);
83 }
84 );
85
86 sql.write_str(")").unwrap();
87 }
88 );
89 }
90 InsertValueSource::Select(select_query) => {
91 self.prepare_select_statement(select_query.deref(), sql);
92 }
93 }
94 }
95 }
96
97 self.prepare_on_conflict(&insert.on_conflict, sql);
98
99 self.prepare_returning(&insert.returning, sql);
100 }
101
102 fn prepare_union_statement(
103 &self,
104 union_type: UnionType,
105 select_statement: &SelectStatement,
106 sql: &mut impl SqlWriter,
107 ) {
108 match union_type {
109 UnionType::Intersect => sql.write_str(" INTERSECT (").unwrap(),
110 UnionType::Distinct => sql.write_str(" UNION (").unwrap(),
111 UnionType::Except => sql.write_str(" EXCEPT (").unwrap(),
112 UnionType::All => sql.write_str(" UNION ALL (").unwrap(),
113 }
114 self.prepare_select_statement(select_statement, sql);
115 sql.write_str(")").unwrap();
116 }
117
118 fn prepare_select_statement(&self, select: &SelectStatement, sql: &mut impl SqlWriter) {
120 if let Some(with) = &select.with {
121 self.prepare_with_clause(with, sql);
122 }
123
124 sql.write_str("SELECT ").unwrap();
125
126 if let Some(distinct) = &select.distinct {
127 self.prepare_select_distinct(distinct, sql);
128 sql.write_str(" ").unwrap();
129 }
130
131 let mut selects = select.selects.iter();
132 join_io!(
133 selects,
134 expr,
135 join {
136 sql.write_str(", ").unwrap();
137 },
138 do {
139 self.prepare_select_expr(expr, sql);
140 }
141 );
142
143 if let Some(into_table) = &select.into {
144 self.prepare_select_into(into_table, sql);
145 }
146
147 let mut from_tables = select.from.iter();
148 join_io!(
149 from_tables,
150 table_ref,
151 first {
152 sql.write_str(" FROM ").unwrap();
153 },
154 join {
155 sql.write_str(", ").unwrap();
156 },
157 do {
158 self.prepare_table_ref(table_ref, sql);
159 self.prepare_index_hints(table_ref,select, sql);
160 },
161 last {
162 self.prepare_table_sample(select, sql);
163 }
164 );
165
166 for expr in &select.join {
167 sql.write_str(" ").unwrap();
168 self.prepare_join_expr(expr, sql);
169 }
170
171 self.prepare_condition(&select.r#where, "WHERE", sql);
172
173 let mut groups = select.groups.iter();
174 join_io!(
175 groups,
176 expr,
177 first {
178 sql.write_str(" GROUP BY ").unwrap();
179 },
180 join {
181 sql.write_str(", ").unwrap();
182 },
183 do {
184 self.prepare_expr(expr, sql);
185 }
186 );
187
188 self.prepare_condition(&select.having, "HAVING", sql);
189
190 if !select.unions.is_empty() {
191 select.unions.iter().for_each(|(union_type, query)| {
192 self.prepare_union_statement(*union_type, query, sql);
193 });
194 }
195
196 let mut orders = select.orders.iter();
197 join_io!(
198 orders,
199 expr,
200 first {
201 sql.write_str(" ORDER BY ").unwrap();
202 },
203 join {
204 sql.write_str(", ").unwrap();
205 },
206 do {
207 self.prepare_order_expr(expr, sql);
208 }
209 );
210
211 self.prepare_select_limit_offset(select, sql);
212
213 if let Some(lock) = &select.lock {
214 sql.write_str(" ").unwrap();
215 self.prepare_select_lock(lock, sql);
216 }
217
218 if let Some((name, query)) = &select.window {
219 sql.write_str(" WINDOW ").unwrap();
220 self.prepare_iden(name, sql);
221 sql.write_str(" AS (").unwrap();
222 self.prepare_window_statement(query, sql);
223 sql.write_str(")").unwrap();
224 }
225 }
226
227 fn prepare_select_limit_offset(&self, select: &SelectStatement, sql: &mut impl SqlWriter) {
229 if let Some(limit) = &select.limit {
230 sql.write_str(" LIMIT ").unwrap();
231 self.prepare_value(limit.clone(), sql);
232 }
233
234 if let Some(offset) = &select.offset {
235 sql.write_str(" OFFSET ").unwrap();
236 self.prepare_value(offset.clone(), sql);
237 }
238 }
239
240 fn prepare_update_statement(&self, update: &UpdateStatement, sql: &mut impl SqlWriter) {
242 if let Some(with) = &update.with {
243 self.prepare_with_clause(with, sql);
244 }
245
246 sql.write_str("UPDATE ").unwrap();
247
248 if let Some(table) = &update.table {
249 self.prepare_table_ref(table, sql);
250 }
251
252 self.prepare_update_join(&update.from, &update.r#where, sql);
253
254 sql.write_str(" SET ").unwrap();
255
256 let mut values = update.values.iter();
257 join_io!(
258 values,
259 row,
260 join {
261 sql.write_str(", ").unwrap();
262 },
263 do {
264 let (col, v) = row;
265 self.prepare_update_column(&update.table, &update.from, col, sql);
266 sql.write_str(" = ").unwrap();
267 self.prepare_expr(v, sql);
268 }
269 );
270
271 self.prepare_update_from(&update.from, sql);
272
273 self.prepare_output(&update.returning, sql);
274
275 self.prepare_update_condition(&update.from, &update.r#where, sql);
276
277 self.prepare_update_order_by(update, sql);
278
279 self.prepare_update_limit(update, sql);
280
281 self.prepare_returning(&update.returning, sql);
282 }
283
284 fn prepare_update_join(&self, _: &[TableRef], _: &ConditionHolder, _: &mut impl SqlWriter) {
285 }
287
288 fn prepare_update_from(&self, from: &[TableRef], sql: &mut impl SqlWriter) {
289 let mut from_iter = from.iter();
290 join_io!(
291 from_iter,
292 table_ref,
293 first {
294 sql.write_str(" FROM ").unwrap();
295 },
296 join {
297 sql.write_str(", ").unwrap();
298 },
299 do {
300 self.prepare_table_ref(table_ref, sql);
301 }
302 );
303 }
304
305 fn prepare_update_column(
306 &self,
307 _: &Option<Box<TableRef>>,
308 _: &[TableRef],
309 column: &DynIden,
310 sql: &mut impl SqlWriter,
311 ) {
312 self.prepare_iden(column, sql);
313 }
314
315 fn prepare_update_condition(
316 &self,
317 _: &[TableRef],
318 condition: &ConditionHolder,
319 sql: &mut impl SqlWriter,
320 ) {
321 self.prepare_condition(condition, "WHERE", sql);
322 }
323
324 fn prepare_update_order_by(&self, update: &UpdateStatement, sql: &mut impl SqlWriter) {
326 let mut orders = update.orders.iter();
327 join_io!(
328 orders,
329 expr,
330 first {
331 sql.write_str(" ORDER BY ").unwrap();
332 },
333 join {
334 sql.write_str(", ").unwrap();
335 },
336 do {
337 self.prepare_order_expr(expr, sql);
338 }
339 );
340 }
341
342 fn prepare_update_limit(&self, update: &UpdateStatement, sql: &mut impl SqlWriter) {
344 if let Some(limit) = &update.limit {
345 sql.write_str(" LIMIT ").unwrap();
346 self.prepare_value(limit.clone(), sql);
347 }
348 }
349
350 fn prepare_delete_statement(&self, delete: &DeleteStatement, sql: &mut impl SqlWriter) {
352 if let Some(with) = &delete.with {
353 self.prepare_with_clause(with, sql);
354 }
355
356 sql.write_str("DELETE ").unwrap();
357
358 if let Some(table) = &delete.table {
359 sql.write_str("FROM ").unwrap();
360 self.prepare_table_ref(table, sql);
361 }
362
363 self.prepare_output(&delete.returning, sql);
364
365 self.prepare_condition(&delete.r#where, "WHERE", sql);
366
367 self.prepare_delete_order_by(delete, sql);
368
369 self.prepare_delete_limit(delete, sql);
370
371 self.prepare_returning(&delete.returning, sql);
372 }
373
374 fn prepare_delete_order_by(&self, delete: &DeleteStatement, sql: &mut impl SqlWriter) {
376 let mut orders = delete.orders.iter();
377 join_io!(
378 orders,
379 expr,
380 first {
381 sql.write_str(" ORDER BY ").unwrap();
382 },
383 join {
384 sql.write_str(", ").unwrap();
385 },
386 do {
387 self.prepare_order_expr(expr, sql);
388 }
389 );
390 }
391
392 fn prepare_delete_limit(&self, delete: &DeleteStatement, sql: &mut impl SqlWriter) {
394 if let Some(limit) = &delete.limit {
395 sql.write_str(" LIMIT ").unwrap();
396 self.prepare_value(limit.clone(), sql);
397 }
398 }
399
400 fn prepare_expr(&self, simple_expr: &Expr, sql: &mut impl SqlWriter) {
402 self.prepare_expr_common(simple_expr, sql);
403 }
404
405 fn prepare_expr_common(&self, simple_expr: &Expr, sql: &mut impl SqlWriter) {
406 match simple_expr {
407 Expr::Column(column_ref) => {
408 self.prepare_column_ref(column_ref, sql);
409 }
410 Expr::Tuple(exprs) => {
411 self.prepare_tuple(exprs, sql);
412 }
413 Expr::Unary(op, expr) => {
414 self.prepare_un_oper(op, sql);
415 sql.write_str(" ").unwrap();
416 let drop_expr_paren =
417 self.inner_expr_well_known_greater_precedence(expr, &(*op).into());
418 if !drop_expr_paren {
419 sql.write_str("(").unwrap();
420 }
421 self.prepare_expr(expr, sql);
422 if !drop_expr_paren {
423 sql.write_str(")").unwrap();
424 }
425 }
426 Expr::FunctionCall(func) => {
427 self.prepare_function_name(&func.func, sql);
428 self.prepare_function_arguments(func, sql);
429 }
430 Expr::Binary(left, op, right) => match (op, right.as_ref()) {
431 (BinOper::In, Expr::Tuple(t)) if t.is_empty() => {
432 self.binary_expr(&1i32.into(), &BinOper::Equal, &2i32.into(), sql)
433 }
434 (BinOper::NotIn, Expr::Tuple(t)) if t.is_empty() => {
435 self.binary_expr(&1i32.into(), &BinOper::Equal, &1i32.into(), sql)
436 }
437 _ => self.binary_expr(left, op, right, sql),
438 },
439 Expr::SubQuery(oper, sel) => {
440 if let Some(oper) = oper {
441 self.prepare_sub_query_oper(oper, sql);
442 }
443 sql.write_str("(").unwrap();
444 self.prepare_query_statement(sel.deref(), sql);
445 sql.write_str(")").unwrap();
446 }
447 Expr::Value(val) => {
448 self.prepare_value(val.clone(), sql);
449 }
450 Expr::Values(list) => {
451 sql.write_str("(").unwrap();
452 let mut iter = list.iter();
453 join_io!(
454 iter,
455 val,
456 join {
457 sql.write_str(", ").unwrap();
458 },
459 do {
460 self.prepare_value(val.clone(), sql);
461 }
462 );
463 sql.write_str(")").unwrap();
464 }
465 Expr::Custom(s) => {
466 sql.write_str(s).unwrap();
467 }
468 Expr::CustomWithExpr(expr, values) => {
469 let (placeholder, numbered) = self.placeholder();
470 let mut tokenizer = Tokenizer::new(expr).iter().peekable();
471 let mut count = 0;
472 while let Some(token) = tokenizer.next() {
473 match token {
474 Token::Punctuation(mark) if mark == placeholder => match tokenizer.peek() {
475 Some(Token::Punctuation(next_mark)) if next_mark == &placeholder => {
476 sql.write_str(next_mark).unwrap();
477 tokenizer.next();
478 }
479 Some(Token::Unquoted(tok)) if numbered => {
480 if let Ok(num) = tok.parse::<usize>() {
481 self.prepare_expr(&values[num - 1], sql);
482 }
483 tokenizer.next();
484 }
485 _ => {
486 self.prepare_expr(&values[count], sql);
487 count += 1;
488 }
489 },
490 _ => sql.write_str(token.as_str()).unwrap(),
491 };
492 }
493 }
494 Expr::Keyword(keyword) => {
495 self.prepare_keyword(keyword, sql);
496 }
497 Expr::AsEnum(_, expr) => {
498 self.prepare_expr(expr, sql);
499 }
500 Expr::Case(case_stmt) => {
501 self.prepare_case_statement(case_stmt, sql);
502 }
503 Expr::Constant(val) => {
504 self.prepare_constant(val, sql);
505 }
506 Expr::TypeName(type_name) => {
507 self.prepare_type_ref(type_name, sql);
508 }
509 }
510 }
511
512 fn prepare_case_statement(&self, stmts: &CaseStatement, sql: &mut impl SqlWriter) {
514 sql.write_str("(CASE").unwrap();
515
516 let CaseStatement { when, r#else } = stmts;
517
518 for case in when.iter() {
519 sql.write_str(" WHEN (").unwrap();
520 self.prepare_condition_where(&case.condition, sql);
521 sql.write_str(") THEN ").unwrap();
522
523 self.prepare_expr(&case.result, sql);
524 }
525 if let Some(r#else) = r#else {
526 sql.write_str(" ELSE ").unwrap();
527 self.prepare_expr(r#else, sql);
528 }
529
530 sql.write_str(" END)").unwrap();
531 }
532
533 fn prepare_select_distinct(&self, select_distinct: &SelectDistinct, sql: &mut impl SqlWriter) {
535 match select_distinct {
536 SelectDistinct::All => sql.write_str("ALL").unwrap(),
537 SelectDistinct::Distinct => sql.write_str("DISTINCT").unwrap(),
538 _ => {}
539 }
540 }
541
542 fn prepare_index_hints(
544 &self,
545 _table_ref: &TableRef,
546 _select: &SelectStatement,
547 _sql: &mut impl SqlWriter,
548 ) {
549 }
550
551 fn prepare_table_sample(&self, _select: &SelectStatement, _sql: &mut impl SqlWriter) {}
553
554 fn prepare_select_lock(&self, lock: &LockClause, sql: &mut impl SqlWriter) {
556 sql.write_str(self.lock_phrase(lock.r#type)).unwrap();
557 let mut tables = lock.tables.iter();
558 join_io!(
559 tables,
560 table_ref,
561 first {
562 sql.write_str(" OF ").unwrap();
563 },
564 join {
565 sql.write_str(", ").unwrap();
566 },
567 do {
568 self.prepare_table_ref(table_ref, sql);
569 }
570 );
571
572 if let Some(behavior) = lock.behavior {
573 match behavior {
574 LockBehavior::Nowait => sql.write_str(" NOWAIT").unwrap(),
575 LockBehavior::SkipLocked => sql.write_str(" SKIP LOCKED").unwrap(),
576 }
577 }
578 }
579
580 fn prepare_select_expr(&self, select_expr: &SelectExpr, sql: &mut impl SqlWriter) {
582 self.prepare_expr(&select_expr.expr, sql);
583 match &select_expr.window {
584 Some(WindowSelectType::Name(name)) => {
585 sql.write_str(" OVER ").unwrap();
586 self.prepare_iden(name, sql);
587 }
588 Some(WindowSelectType::Query(window)) => {
589 sql.write_str(" OVER ").unwrap();
590 sql.write_str("( ").unwrap();
591 self.prepare_window_statement(window, sql);
592 sql.write_str(" )").unwrap();
593 }
594 None => {}
595 };
596
597 if let Some(alias) = &select_expr.alias {
598 sql.write_str(" AS ").unwrap();
599 self.prepare_iden(alias, sql);
600 };
601 }
602
603 fn prepare_join_expr(&self, join_expr: &JoinExpr, sql: &mut impl SqlWriter) {
605 self.prepare_join_type(&join_expr.join, sql);
606 sql.write_str(" ").unwrap();
607 self.prepare_join_table_ref(join_expr, sql);
608 if let Some(on) = &join_expr.on {
609 self.prepare_join_on(on, sql);
610 }
611 }
612
613 fn prepare_join_table_ref(&self, join_expr: &JoinExpr, sql: &mut impl SqlWriter) {
614 if join_expr.lateral {
615 sql.write_str("LATERAL ").unwrap();
616 }
617 self.prepare_table_ref(&join_expr.table, sql);
618 }
619
620 fn prepare_table_ref(&self, table_ref: &TableRef, sql: &mut impl SqlWriter) {
622 match table_ref {
623 TableRef::SubQuery(query, alias) => {
624 sql.write_str("(").unwrap();
625 self.prepare_select_statement(query, sql);
626 sql.write_str(")").unwrap();
627 sql.write_str(" AS ").unwrap();
628 self.prepare_iden(alias, sql);
629 }
630 TableRef::ValuesList(values, alias) => {
631 sql.write_str("(").unwrap();
632 self.prepare_values_list(values, sql);
633 sql.write_str(")").unwrap();
634 sql.write_str(" AS ").unwrap();
635 self.prepare_iden(alias, sql);
636 }
637 TableRef::FunctionCall(func, alias) => {
638 self.prepare_function_name(&func.func, sql);
639 self.prepare_function_arguments(func, sql);
640 sql.write_str(" AS ").unwrap();
641 self.prepare_iden(alias, sql);
642 }
643 _ => self.prepare_table_ref_iden(table_ref, sql),
644 }
645 }
646
647 fn prepare_column_ref(&self, column_ref: &ColumnRef, sql: &mut impl SqlWriter) {
648 match column_ref {
649 ColumnRef::Column(ColumnName(table_name, column)) => {
650 if let Some(table_name) = table_name {
651 self.prepare_table_name(table_name, sql);
652 sql.write_str(".").unwrap();
653 }
654 self.prepare_iden(column, sql);
655 }
656 ColumnRef::Asterisk(table_name) => {
657 if let Some(table_name) = table_name {
658 self.prepare_table_name(table_name, sql);
659 sql.write_str(".").unwrap();
660 }
661 sql.write_str("*").unwrap();
662 }
663 }
664 }
665
666 fn prepare_un_oper(&self, un_oper: &UnOper, sql: &mut impl SqlWriter) {
668 sql.write_str(match un_oper {
669 UnOper::Not => "NOT",
670 })
671 .unwrap();
672 }
673
674 fn prepare_bin_oper_common(&self, bin_oper: &BinOper, sql: &mut impl SqlWriter) {
675 sql.write_str(match bin_oper {
676 BinOper::And => "AND",
677 BinOper::Or => "OR",
678 BinOper::Like => "LIKE",
679 BinOper::NotLike => "NOT LIKE",
680 BinOper::Is => "IS",
681 BinOper::IsNot => "IS NOT",
682 BinOper::In => "IN",
683 BinOper::NotIn => "NOT IN",
684 BinOper::Between => "BETWEEN",
685 BinOper::NotBetween => "NOT BETWEEN",
686 BinOper::Equal => "=",
687 BinOper::NotEqual => "<>",
688 BinOper::SmallerThan => "<",
689 BinOper::GreaterThan => ">",
690 BinOper::SmallerThanOrEqual => "<=",
691 BinOper::GreaterThanOrEqual => ">=",
692 BinOper::Add => "+",
693 BinOper::Sub => "-",
694 BinOper::Mul => "*",
695 BinOper::Div => "/",
696 BinOper::Mod => "%",
697 BinOper::LShift => "<<",
698 BinOper::RShift => ">>",
699 BinOper::As => "AS",
700 BinOper::Escape => "ESCAPE",
701 BinOper::Custom(raw) => raw,
702 BinOper::BitAnd => "&",
703 BinOper::BitOr => "|",
704 #[allow(unreachable_patterns)]
705 _ => unimplemented!(),
706 })
707 .unwrap();
708 }
709
710 fn prepare_bin_oper(&self, bin_oper: &BinOper, sql: &mut impl SqlWriter) {
712 self.prepare_bin_oper_common(bin_oper, sql);
713 }
714
715 fn prepare_sub_query_oper(&self, oper: &SubQueryOper, sql: &mut impl SqlWriter) {
717 sql.write_str(match oper {
718 SubQueryOper::Exists => "EXISTS",
719 SubQueryOper::Any => "ANY",
720 SubQueryOper::Some => "SOME",
721 SubQueryOper::All => "ALL",
722 })
723 .unwrap();
724 }
725
726 fn prepare_logical_chain_oper(
728 &self,
729 log_chain_oper: &LogicalChainOper,
730 i: usize,
731 length: usize,
732 sql: &mut impl SqlWriter,
733 ) {
734 let (simple_expr, oper) = match log_chain_oper {
735 LogicalChainOper::And(simple_expr) => (simple_expr, "AND"),
736 LogicalChainOper::Or(simple_expr) => (simple_expr, "OR"),
737 };
738 if i > 0 {
739 sql.write_str(" ").unwrap();
740 sql.write_str(oper).unwrap();
741 sql.write_str(" ").unwrap();
742 }
743 let both_binary = match simple_expr {
744 Expr::Binary(_, _, right) => {
745 matches!(right.as_ref(), Expr::Binary(_, _, _))
746 }
747 _ => false,
748 };
749 let need_parentheses = length > 1 && both_binary;
750 if need_parentheses {
751 sql.write_str("(").unwrap();
752 }
753 self.prepare_expr(simple_expr, sql);
754 if need_parentheses {
755 sql.write_str(")").unwrap();
756 }
757 }
758
759 fn prepare_function_name_common(&self, function: &Func, sql: &mut impl SqlWriter) {
761 if let Func::Custom(iden) = function {
762 sql.write_str(&iden.0)
763 } else {
764 sql.write_str(match function {
765 Func::Max => "MAX",
766 Func::Min => "MIN",
767 Func::Sum => "SUM",
768 Func::Avg => "AVG",
769 Func::Abs => "ABS",
770 Func::Coalesce => "COALESCE",
771 Func::Count => "COUNT",
772 Func::IfNull => self.if_null_function(),
773 Func::Greatest => self.greatest_function(),
774 Func::Least => self.least_function(),
775 Func::CharLength => self.char_length_function(),
776 Func::Cast => "CAST",
777 Func::Lower => "LOWER",
778 Func::Upper => "UPPER",
779 Func::BitAnd => "BIT_AND",
780 Func::BitOr => "BIT_OR",
781 Func::Custom(_) => "",
782 Func::Random => self.random_function(),
783 Func::Round => "ROUND",
784 Func::Md5 => "MD5",
785 #[cfg(feature = "backend-postgres")]
786 Func::PgFunction(_) => unimplemented!(),
787 })
788 }
789 .unwrap();
790 }
791
792 fn prepare_function_arguments(&self, func: &FunctionCall, sql: &mut impl SqlWriter) {
793 sql.write_str("(").unwrap();
794 let mut args = func.args.iter().zip(func.mods.iter());
795
796 if let Some((arg, modifier)) = args.next() {
797 if modifier.distinct {
798 sql.write_str("DISTINCT ").unwrap();
799 }
800 self.prepare_expr(arg, sql);
801 }
802
803 for (arg, modifier) in args {
804 sql.write_str(", ").unwrap();
805 if modifier.distinct {
806 sql.write_str("DISTINCT ").unwrap();
807 }
808 self.prepare_expr(arg, sql);
809 }
810
811 sql.write_str(")").unwrap();
812 }
813
814 fn prepare_query_statement(&self, query: &SubQueryStatement, sql: &mut impl SqlWriter);
816
817 fn prepare_select_into(&self, into_table: &SelectInto, sql: &mut impl SqlWriter);
818
819 fn prepare_with_query(&self, query: &WithQuery, sql: &mut impl SqlWriter) {
820 self.prepare_with_clause(&query.with_clause, sql);
821 self.prepare_query_statement(query.query.as_ref().unwrap().deref(), sql);
822 }
823
824 fn prepare_with_clause(&self, with_clause: &WithClause, sql: &mut impl SqlWriter) {
825 self.prepare_with_clause_start(with_clause, sql);
826 self.prepare_with_clause_common_tables(with_clause, sql);
827 if with_clause.recursive {
828 self.prepare_with_clause_recursive_options(with_clause, sql);
829 }
830 }
831
832 fn prepare_with_clause_recursive_options(
833 &self,
834 with_clause: &WithClause,
835 sql: &mut impl SqlWriter,
836 ) {
837 if with_clause.recursive {
838 if let Some(search) = &with_clause.search {
839 sql.write_str("SEARCH ").unwrap();
840 sql.write_str(match &search.order.as_ref().unwrap() {
841 SearchOrder::BREADTH => "BREADTH",
842 SearchOrder::DEPTH => "DEPTH",
843 })
844 .unwrap();
845 sql.write_str(" FIRST BY ").unwrap();
846
847 self.prepare_expr(&search.expr.as_ref().unwrap().expr, sql);
848
849 sql.write_str(" SET ").unwrap();
850
851 self.prepare_iden(search.expr.as_ref().unwrap().alias.as_ref().unwrap(), sql);
852 sql.write_str(" ").unwrap();
853 }
854 if let Some(cycle) = &with_clause.cycle {
855 sql.write_str("CYCLE ").unwrap();
856
857 self.prepare_expr(cycle.expr.as_ref().unwrap(), sql);
858
859 sql.write_str(" SET ").unwrap();
860
861 self.prepare_iden(cycle.set_as.as_ref().unwrap(), sql);
862 sql.write_str(" USING ").unwrap();
863 self.prepare_iden(cycle.using.as_ref().unwrap(), sql);
864 sql.write_str(" ").unwrap();
865 }
866 }
867 }
868
869 fn prepare_with_clause_common_tables(
870 &self,
871 with_clause: &WithClause,
872 sql: &mut impl SqlWriter,
873 ) {
874 let mut cte_first = true;
875 assert_ne!(
876 with_clause.cte_expressions.len(),
877 0,
878 "Cannot build a with query that has no common table expression!"
879 );
880
881 for cte in &with_clause.cte_expressions {
882 if !cte_first {
883 sql.write_str(", ").unwrap();
884 }
885 cte_first = false;
886
887 self.prepare_with_query_clause_common_table(cte, sql);
888 }
889 }
890
891 fn prepare_with_query_clause_common_table(
892 &self,
893 cte: &CommonTableExpression,
894 sql: &mut impl SqlWriter,
895 ) {
896 self.prepare_iden(cte.table_name.as_ref().unwrap(), sql);
897
898 if cte.cols.is_empty() {
899 sql.write_str(" ").unwrap();
900 } else {
901 sql.write_str(" (").unwrap();
902
903 let mut col_first = true;
904 for col in &cte.cols {
905 if !col_first {
906 sql.write_str(", ").unwrap();
907 }
908 col_first = false;
909 self.prepare_iden(col, sql);
910 }
911
912 sql.write_str(") ").unwrap();
913 }
914
915 sql.write_str("AS ").unwrap();
916
917 self.prepare_with_query_clause_materialization(cte, sql);
918
919 sql.write_str("(").unwrap();
920
921 match &cte.query {
922 CteQuery::SubQuery(sub_query) => self.prepare_query_statement(sub_query, sql),
923 CteQuery::Values(items) => self.prepare_values_rows(items, sql),
924 }
925
926 sql.write_str(") ").unwrap();
927 }
928
929 fn prepare_with_query_clause_materialization(
930 &self,
931 cte: &CommonTableExpression,
932 sql: &mut impl SqlWriter,
933 ) {
934 if let Some(materialized) = cte.materialized {
935 if !materialized {
936 sql.write_str("NOT MATERIALIZED ")
937 } else {
938 sql.write_str(" MATERIALIZED ")
939 }
940 .unwrap()
941 }
942 }
943
944 fn prepare_with_clause_start(&self, with_clause: &WithClause, sql: &mut impl SqlWriter) {
945 sql.write_str("WITH ").unwrap();
946
947 if with_clause.recursive {
948 sql.write_str("RECURSIVE ").unwrap();
949 }
950 }
951
952 fn prepare_insert(&self, replace: bool, sql: &mut impl SqlWriter) {
953 if replace {
954 sql.write_str("REPLACE").unwrap();
955 } else {
956 sql.write_str("INSERT").unwrap();
957 }
958 }
959
960 fn prepare_function_name(&self, function: &Func, sql: &mut impl SqlWriter) {
961 self.prepare_function_name_common(function, sql)
962 }
963
964 fn prepare_type_ref(&self, type_name: &TypeRef, sql: &mut impl SqlWriter) {
966 let TypeRef(schema_name, r#type) = type_name;
967 if let Some(schema_name) = schema_name {
968 self.prepare_schema_name(schema_name, sql);
969 write!(sql, ".").unwrap();
970 }
971 let mut base = r#type.0.as_ref();
972 let mut array_dims = 0;
973 while let Some(stripped) = base.strip_suffix("[]") {
974 base = stripped;
975 array_dims += 1;
976 }
977 if array_dims == 0 {
978 self.prepare_iden(r#type, sql);
979 } else {
980 let base_iden = DynIden(Cow::Owned(base.to_string()));
981 self.prepare_iden(&base_iden, sql);
982 for _ in 0..array_dims {
983 sql.write_str("[]").unwrap();
984 }
985 }
986 }
987
988 fn prepare_join_type(&self, join_type: &JoinType, sql: &mut impl SqlWriter) {
990 self.prepare_join_type_common(join_type, sql)
991 }
992
993 fn prepare_join_type_common(&self, join_type: &JoinType, sql: &mut impl SqlWriter) {
994 sql.write_str(match join_type {
995 JoinType::Join => "JOIN",
996 JoinType::CrossJoin => "CROSS JOIN",
997 JoinType::InnerJoin => "INNER JOIN",
998 JoinType::LeftJoin => "LEFT JOIN",
999 JoinType::RightJoin => "RIGHT JOIN",
1000 JoinType::FullOuterJoin => "FULL OUTER JOIN",
1001 JoinType::StraightJoin => "STRAIGHT_JOIN",
1002 })
1003 .unwrap()
1004 }
1005
1006 fn prepare_order_expr(&self, order_expr: &OrderExpr, sql: &mut impl SqlWriter) {
1008 if !matches!(order_expr.order, Order::Field(_)) {
1009 self.prepare_expr(&order_expr.expr, sql);
1010 }
1011 self.prepare_order(order_expr, sql);
1012 }
1013
1014 fn prepare_join_on(&self, join_on: &JoinOn, sql: &mut impl SqlWriter) {
1016 match join_on {
1017 JoinOn::Condition(c) => self.prepare_condition(c, "ON", sql),
1018 JoinOn::Columns(_c) => unimplemented!(),
1019 }
1020 }
1021
1022 fn prepare_order(&self, order_expr: &OrderExpr, sql: &mut impl SqlWriter) {
1024 match &order_expr.order {
1025 Order::Asc => sql.write_str(" ASC").unwrap(),
1026 Order::Desc => sql.write_str(" DESC").unwrap(),
1027 Order::Field(values) => self.prepare_field_order(order_expr, values, sql),
1028 }
1029 }
1030
1031 fn prepare_field_order(
1033 &self,
1034 order_expr: &OrderExpr,
1035 values: &Values,
1036 sql: &mut impl SqlWriter,
1037 ) {
1038 sql.write_str("CASE ").unwrap();
1039 let mut i = 0;
1040 for value in &values.0 {
1041 sql.write_str("WHEN ").unwrap();
1042 self.prepare_expr(&order_expr.expr, sql);
1043 sql.write_str("=").unwrap();
1044 self.write_value(sql, value).unwrap();
1045 sql.write_str(" THEN ").unwrap();
1046 write_int(sql, i);
1047 sql.write_str(" ").unwrap();
1048 i += 1;
1049 }
1050
1051 sql.write_str("ELSE ").unwrap();
1052 write_int(sql, i);
1053 sql.write_str(" END").unwrap();
1054 }
1055
1056 fn prepare_value(&self, value: Value, sql: &mut impl SqlWriter);
1058
1059 fn prepare_constant(&self, value: &Value, sql: &mut impl SqlWriter) {
1061 self.write_value(sql, value).unwrap();
1062 }
1063
1064 fn prepare_values_list(&self, value_tuples: &[ValueTuple], sql: &mut impl SqlWriter) {
1066 sql.write_str("VALUES ").unwrap();
1067 let mut tuples = value_tuples.iter();
1068 join_io!(
1069 tuples,
1070 value_tuple,
1071 join {
1072 sql.write_str(", ").unwrap();
1073 },
1074 do {
1075 sql.write_str(self.values_list_tuple_prefix()).unwrap();
1076 sql.write_str("(").unwrap();
1077
1078 let mut values = value_tuple.clone().into_iter();
1079 join_io!(
1080 values,
1081 value,
1082 join {
1083 sql.write_str(", ").unwrap();
1084 },
1085 do {
1086 self.prepare_value(value, sql);
1087 }
1088 );
1089
1090 sql.write_str(")").unwrap();
1091 }
1092 );
1093 }
1094
1095 fn prepare_values_rows(&self, values: &[Values], sql: &mut impl SqlWriter) {
1096 sql.write_str("VALUES ").unwrap();
1097 let mut rows = values.iter();
1098 join_io!(
1099 rows,
1100 row,
1101 join {
1102 sql.write_str(", ").unwrap();
1103 },
1104 do {
1105 sql.write_str("(").unwrap();
1106
1107 let mut vals = row.clone().into_iter();
1108 join_io!(
1109 vals,
1110 val,
1111 join {
1112 sql.write_str(", ").unwrap();
1113 },
1114 do {
1115 self.prepare_value(val, sql);
1116 }
1117 );
1118
1119 sql.write_str(")").unwrap();
1120 }
1121 );
1122 }
1123
1124 fn prepare_tuple(&self, exprs: &[Expr], sql: &mut impl SqlWriter) {
1126 sql.write_str("(").unwrap();
1127 for (i, expr) in exprs.iter().enumerate() {
1128 if i != 0 {
1129 sql.write_str(", ").unwrap();
1130 }
1131 self.prepare_expr(expr, sql);
1132 }
1133 sql.write_str(")").unwrap();
1134 }
1135
1136 fn prepare_keyword(&self, keyword: &Keyword, sql: &mut impl SqlWriter) {
1138 match keyword {
1139 Keyword::Null => sql.write_str("NULL").unwrap(),
1140 Keyword::CurrentDate => sql.write_str("CURRENT_DATE").unwrap(),
1141 Keyword::CurrentTime => sql.write_str("CURRENT_TIME").unwrap(),
1142 Keyword::CurrentTimestamp => sql.write_str("CURRENT_TIMESTAMP").unwrap(),
1143 Keyword::Default => sql.write_str("DEFAULT").unwrap(),
1144 Keyword::Custom(iden) => sql.write_str(&iden.0).unwrap(),
1145 }
1146 }
1147
1148 fn value_to_string(&self, v: &Value) -> String {
1150 self.value_to_string_common(v)
1151 }
1152
1153 fn value_to_string_common(&self, v: &Value) -> String {
1154 let mut s = String::new();
1155 self.write_value(&mut s, v).unwrap();
1156 s
1157 }
1158
1159 #[doc(hidden)]
1160 fn write_value(&self, buf: &mut impl Write, value: &Value) -> fmt::Result {
1161 self.write_value_common(buf, value)
1162 }
1163
1164 #[doc(hidden)]
1165 fn write_value_common(&self, buf: &mut impl Write, value: &Value) -> fmt::Result {
1166 match value {
1167 Value::Bool(None)
1168 | Value::TinyInt(None)
1169 | Value::SmallInt(None)
1170 | Value::Int(None)
1171 | Value::BigInt(None)
1172 | Value::TinyUnsigned(None)
1173 | Value::SmallUnsigned(None)
1174 | Value::Unsigned(None)
1175 | Value::BigUnsigned(None)
1176 | Value::Float(None)
1177 | Value::Double(None)
1178 | Value::String(None)
1179 | Value::Char(None)
1180 | Value::Bytes(None) => buf.write_str("NULL")?,
1181 #[cfg(feature = "with-json")]
1182 Value::Json(None) => buf.write_str("NULL")?,
1183 #[cfg(feature = "with-chrono")]
1184 Value::ChronoDate(None) => buf.write_str("NULL")?,
1185 #[cfg(feature = "with-chrono")]
1186 Value::ChronoTime(None) => buf.write_str("NULL")?,
1187 #[cfg(feature = "with-chrono")]
1188 Value::ChronoDateTime(None) => buf.write_str("NULL")?,
1189 #[cfg(feature = "with-chrono")]
1190 Value::ChronoDateTimeUtc(None) => buf.write_str("NULL")?,
1191 #[cfg(feature = "with-chrono")]
1192 Value::ChronoDateTimeLocal(None) => buf.write_str("NULL")?,
1193 #[cfg(feature = "with-chrono")]
1194 Value::ChronoDateTimeWithTimeZone(None) => buf.write_str("NULL")?,
1195 #[cfg(feature = "with-time")]
1196 Value::TimeDate(None) => buf.write_str("NULL")?,
1197 #[cfg(feature = "with-time")]
1198 Value::TimeTime(None) => buf.write_str("NULL")?,
1199 #[cfg(feature = "with-time")]
1200 Value::TimeDateTime(None) => buf.write_str("NULL")?,
1201 #[cfg(feature = "with-time")]
1202 Value::TimeDateTimeWithTimeZone(None) => buf.write_str("NULL")?,
1203 #[cfg(feature = "with-jiff")]
1204 Value::JiffDate(None) => buf.write_str("NULL")?,
1205 #[cfg(feature = "with-jiff")]
1206 Value::JiffTime(None) => buf.write_str("NULL")?,
1207 #[cfg(feature = "with-jiff")]
1208 Value::JiffDateTime(None) => buf.write_str("NULL")?,
1209 #[cfg(feature = "with-jiff")]
1210 Value::JiffTimestamp(None) => buf.write_str("NULL")?,
1211 #[cfg(feature = "with-jiff")]
1212 Value::JiffZoned(None) => buf.write_str("NULL")?,
1213 #[cfg(feature = "with-rust_decimal")]
1214 Value::Decimal(None) => buf.write_str("NULL")?,
1215 #[cfg(feature = "with-bigdecimal")]
1216 Value::BigDecimal(None) => buf.write_str("NULL")?,
1217 #[cfg(feature = "with-uuid")]
1218 Value::Uuid(None) => buf.write_str("NULL")?,
1219 #[cfg(feature = "with-ipnetwork")]
1220 Value::IpNetwork(None) => buf.write_str("NULL")?,
1221 #[cfg(feature = "with-mac_address")]
1222 Value::MacAddress(None) => buf.write_str("NULL")?,
1223 #[cfg(feature = "postgres-array")]
1224 Value::Array(_, None) => buf.write_str("NULL")?,
1225 #[cfg(feature = "postgres-vector")]
1226 Value::Vector(None) => buf.write_str("NULL")?,
1227 #[cfg(feature = "postgres-range")]
1228 Value::Range(None) => buf.write_str("NULL")?,
1229 Value::Bool(Some(b)) => buf.write_str(if *b { "TRUE" } else { "FALSE" })?,
1230 Value::TinyInt(Some(v)) => {
1231 write_int(buf, *v);
1232 }
1233 Value::SmallInt(Some(v)) => {
1234 write_int(buf, *v);
1235 }
1236 Value::Int(Some(v)) => {
1237 write_int(buf, *v);
1238 }
1239 Value::BigInt(Some(v)) => {
1240 write_int(buf, *v);
1241 }
1242 Value::TinyUnsigned(Some(v)) => {
1243 write_int(buf, *v);
1244 }
1245 Value::SmallUnsigned(Some(v)) => {
1246 write_int(buf, *v);
1247 }
1248 Value::Unsigned(Some(v)) => {
1249 write_int(buf, *v);
1250 }
1251 Value::BigUnsigned(Some(v)) => {
1252 write_int(buf, *v);
1253 }
1254 Value::Float(Some(v)) => write!(buf, "{v}")?,
1255 Value::Double(Some(v)) => write!(buf, "{v}")?,
1256 Value::String(Some(v)) => self.write_string_quoted(v, buf),
1257 Value::Char(Some(v)) => {
1258 self.write_string_quoted(std::str::from_utf8(&[*v as u8]).unwrap(), buf)
1259 }
1260 Value::Bytes(Some(v)) => self.write_bytes(v, buf),
1261 #[cfg(feature = "with-json")]
1262 Value::Json(Some(v)) => self.write_string_quoted(&v.to_string(), buf),
1263 #[cfg(feature = "with-chrono")]
1264 Value::ChronoDate(Some(v)) => {
1265 buf.write_str("'")?;
1266 write!(buf, "{}", v.format("%Y-%m-%d"))?;
1267 buf.write_str("'")?;
1268 }
1269 #[cfg(feature = "with-chrono")]
1270 Value::ChronoTime(Some(v)) => {
1271 buf.write_str("'")?;
1272 write!(buf, "{}", v.format("%H:%M:%S%.6f"))?;
1273 buf.write_str("'")?;
1274 }
1275 #[cfg(feature = "with-chrono")]
1276 Value::ChronoDateTime(Some(v)) => {
1277 buf.write_str("'")?;
1278 write!(buf, "{}", v.format("%Y-%m-%d %H:%M:%S%.6f"))?;
1279 buf.write_str("'")?;
1280 }
1281 #[cfg(feature = "with-chrono")]
1282 Value::ChronoDateTimeUtc(Some(v)) => {
1283 buf.write_str("'")?;
1284 write!(buf, "{}", v.format("%Y-%m-%d %H:%M:%S%.6f %:z"))?;
1285 buf.write_str("'")?;
1286 }
1287 #[cfg(feature = "with-chrono")]
1288 Value::ChronoDateTimeLocal(Some(v)) => {
1289 buf.write_str("'")?;
1290 write!(buf, "{}", v.format("%Y-%m-%d %H:%M:%S%.6f %:z"))?;
1291 buf.write_str("'")?;
1292 }
1293 #[cfg(feature = "with-chrono")]
1294 Value::ChronoDateTimeWithTimeZone(Some(v)) => {
1295 buf.write_str("'")?;
1296 write!(buf, "{}", v.format("%Y-%m-%d %H:%M:%S%.6f %:z"))?;
1297 buf.write_str("'")?;
1298 }
1299 #[cfg(feature = "with-time")]
1300 Value::TimeDate(Some(v)) => {
1301 buf.write_str("'")?;
1302 buf.write_str(&v.format(time_format::FORMAT_DATE).unwrap())?;
1303 buf.write_str("'")?;
1304 }
1305 #[cfg(feature = "with-time")]
1306 Value::TimeTime(Some(v)) => {
1307 buf.write_str("'")?;
1308 buf.write_str(&v.format(time_format::FORMAT_TIME).unwrap())?;
1309 buf.write_str("'")?;
1310 }
1311 #[cfg(feature = "with-time")]
1312 Value::TimeDateTime(Some(v)) => {
1313 buf.write_str("'")?;
1314 buf.write_str(&v.format(time_format::FORMAT_DATETIME).unwrap())?;
1315 buf.write_str("'")?;
1316 }
1317 #[cfg(feature = "with-time")]
1318 Value::TimeDateTimeWithTimeZone(Some(v)) => {
1319 buf.write_str("'")?;
1320 buf.write_str(&v.format(time_format::FORMAT_DATETIME_TZ).unwrap())?;
1321 buf.write_str("'")?;
1322 }
1323 #[cfg(feature = "with-jiff")]
1326 Value::JiffDate(Some(v)) => {
1327 buf.write_str("'")?;
1328 write!(buf, "{v}")?;
1329 buf.write_str("'")?;
1330 }
1331 #[cfg(feature = "with-jiff")]
1332 Value::JiffTime(Some(v)) => {
1333 buf.write_str("'")?;
1334 write!(buf, "{v}")?;
1335 buf.write_str("'")?;
1336 }
1337 #[cfg(feature = "with-jiff")]
1339 Value::JiffDateTime(Some(v)) => {
1340 use crate::with_jiff::JIFF_DATE_TIME_FMT_STR;
1341 buf.write_str("'")?;
1342 write!(buf, "{}", v.strftime(JIFF_DATE_TIME_FMT_STR))?;
1343 buf.write_str("'")?;
1344 }
1345 #[cfg(feature = "with-jiff")]
1346 Value::JiffTimestamp(Some(v)) => {
1347 use crate::with_jiff::JIFF_TIMESTAMP_FMT_STR;
1348 buf.write_str("'")?;
1349 write!(buf, "{}", v.strftime(JIFF_TIMESTAMP_FMT_STR))?;
1350 buf.write_str("'")?;
1351 }
1352 #[cfg(feature = "with-jiff")]
1353 Value::JiffZoned(Some(v)) => {
1355 use crate::with_jiff::JIFF_ZONE_FMT_STR;
1356 buf.write_str("'")?;
1357 write!(buf, "{}", v.strftime(JIFF_ZONE_FMT_STR))?;
1358 buf.write_str("'")?;
1359 }
1360 #[cfg(feature = "with-rust_decimal")]
1361 Value::Decimal(Some(v)) => write!(buf, "{v}")?,
1362 #[cfg(feature = "with-bigdecimal")]
1363 Value::BigDecimal(Some(v)) => write!(buf, "{v}")?,
1364 #[cfg(feature = "with-uuid")]
1365 Value::Uuid(Some(v)) => {
1366 buf.write_str("'")?;
1367 write!(buf, "{v}")?;
1368 buf.write_str("'")?;
1369 }
1370 #[cfg(feature = "postgres-array")]
1371 Value::Array(_, Some(v)) => {
1372 if v.is_empty() {
1373 buf.write_str("'{}'")?;
1374 } else {
1375 buf.write_str("ARRAY [")?;
1376
1377 let mut viter = v.iter();
1378
1379 if let Some(element) = viter.next() {
1380 self.write_value(buf, element)?;
1381 }
1382
1383 for element in viter {
1384 buf.write_str(",")?;
1385 self.write_value(buf, element)?;
1386 }
1387 buf.write_str("]")?;
1388 }
1389 }
1390 #[cfg(feature = "postgres-vector")]
1391 Value::Vector(Some(v)) => {
1392 buf.write_str("'[")?;
1393 let mut viter = v.as_slice().iter();
1394
1395 if let Some(element) = viter.next() {
1396 write!(buf, "{element}")?;
1397 }
1398
1399 for element in viter {
1400 buf.write_str(",")?;
1401 write!(buf, "{element}")?;
1402 }
1403 buf.write_str("]'")?;
1404 }
1405 #[cfg(feature = "with-ipnetwork")]
1406 Value::IpNetwork(Some(v)) => {
1407 buf.write_str("'")?;
1408 write!(buf, "{v}")?;
1409 buf.write_str("'")?;
1410 }
1411 #[cfg(feature = "with-mac_address")]
1412 Value::MacAddress(Some(v)) => {
1413 buf.write_str("'")?;
1414 write!(buf, "{v}")?;
1415 buf.write_str("'")?;
1416 }
1417 #[cfg(feature = "postgres-range")]
1418 Value::Range(Some(v)) => {
1419 buf.write_str("'")?;
1420 write!(buf, "{v}")?;
1421 buf.write_str("'")?;
1422 }
1423 };
1424
1425 Ok(())
1426 }
1427
1428 #[doc(hidden)]
1429 fn prepare_on_conflict(&self, on_conflict: &Option<OnConflict>, sql: &mut impl SqlWriter) {
1431 if let Some(on_conflict) = on_conflict {
1432 self.prepare_on_conflict_keywords(sql);
1433 self.prepare_on_conflict_target(&on_conflict.targets, sql);
1434 self.prepare_on_conflict_condition(&on_conflict.target_where, sql);
1435 self.prepare_on_conflict_action(&on_conflict.action, sql);
1436 self.prepare_on_conflict_condition(&on_conflict.action_where, sql);
1437 }
1438 }
1439
1440 #[doc(hidden)]
1441 fn prepare_on_conflict_target(
1443 &self,
1444 on_conflict_targets: &OnConflictTarget,
1445 sql: &mut impl SqlWriter,
1446 ) {
1447 match on_conflict_targets {
1448 OnConflictTarget::Identifiers(identifiers) => {
1449 self.prepare_on_conflict_target_identifiers(identifiers, sql)
1450 }
1451 OnConflictTarget::Constraint(constraint) => {
1452 self.prepare_on_conflict_target_constraint(constraint, sql)
1453 }
1454 }
1455 }
1456
1457 #[doc(hidden)]
1458 fn prepare_on_conflict_target_identifiers(
1460 &self,
1461 identifiers: &[OnConflictIdentifier],
1462 sql: &mut impl SqlWriter,
1463 ) {
1464 let mut targets = identifiers.iter();
1465 join_io!(
1466 targets,
1467 target,
1468 first {
1469 sql.write_str("(").unwrap();
1470 },
1471 join {
1472 sql.write_str(", ").unwrap();
1473 },
1474 do {
1475 match target {
1476 OnConflictIdentifier::Column(col) => {
1477 self.prepare_iden(col, sql);
1478 }
1479 OnConflictIdentifier::Expr(expr) => {
1480 self.prepare_expr(expr, sql);
1481 }
1482 }
1483 },
1484 last {
1485 sql.write_str(")").unwrap();
1486 }
1487 );
1488 }
1489
1490 #[doc(hidden)]
1491 fn prepare_on_conflict_target_constraint(&self, constraint: &str, sql: &mut impl SqlWriter) {
1492 sql.write_fmt(format_args!("ON CONSTRAINT \"{}\"", constraint))
1493 .unwrap();
1494 }
1495
1496 #[doc(hidden)]
1497 fn prepare_on_conflict_action(
1499 &self,
1500 on_conflict_action: &Option<OnConflictAction>,
1501 sql: &mut impl SqlWriter,
1502 ) {
1503 self.prepare_on_conflict_action_common(on_conflict_action, sql);
1504 }
1505
1506 fn prepare_on_conflict_action_common(
1507 &self,
1508 on_conflict_action: &Option<OnConflictAction>,
1509 sql: &mut impl SqlWriter,
1510 ) {
1511 if let Some(action) = on_conflict_action {
1512 match action {
1513 OnConflictAction::DoNothing(_) => {
1514 sql.write_str(" DO NOTHING").unwrap();
1515 }
1516 OnConflictAction::Update(update_strats) => {
1517 self.prepare_on_conflict_do_update_keywords(sql);
1518 let mut update_strats_iter = update_strats.iter();
1519 join_io!(
1520 update_strats_iter,
1521 update_strat,
1522 join {
1523 sql.write_str(", ").unwrap();
1524 },
1525 do {
1526 match update_strat {
1527 OnConflictUpdate::Column(col) => {
1528 self.prepare_iden(col, sql);
1529 sql.write_str(" = ").unwrap();
1530 self.prepare_on_conflict_excluded_table(col, sql);
1531 }
1532 OnConflictUpdate::Expr(col, expr) => {
1533 self.prepare_iden(col, sql);
1534 sql.write_str(" = ").unwrap();
1535 self.prepare_expr(expr, sql);
1536 }
1537 }
1538 }
1539 );
1540 }
1541 }
1542 }
1543 }
1544
1545 #[doc(hidden)]
1546 fn prepare_on_conflict_keywords(&self, sql: &mut impl SqlWriter) {
1548 sql.write_str(" ON CONFLICT ").unwrap();
1549 }
1550
1551 #[doc(hidden)]
1552 fn prepare_on_conflict_do_update_keywords(&self, sql: &mut impl SqlWriter) {
1554 sql.write_str(" DO UPDATE SET ").unwrap();
1555 }
1556
1557 #[doc(hidden)]
1558 fn prepare_on_conflict_excluded_table(&self, col: &DynIden, sql: &mut impl SqlWriter) {
1560 sql.write_char(self.quote().left()).unwrap();
1561 sql.write_str("excluded").unwrap();
1562 sql.write_char(self.quote().right()).unwrap();
1563 sql.write_str(".").unwrap();
1564 self.prepare_iden(col, sql);
1565 }
1566
1567 #[doc(hidden)]
1568 fn prepare_on_conflict_condition(
1570 &self,
1571 on_conflict_condition: &ConditionHolder,
1572 sql: &mut impl SqlWriter,
1573 ) {
1574 self.prepare_condition(on_conflict_condition, "WHERE", sql)
1575 }
1576
1577 #[doc(hidden)]
1578 fn prepare_output(&self, _returning: &Option<ReturningClause>, _sql: &mut impl SqlWriter) {}
1580
1581 #[doc(hidden)]
1582 fn prepare_returning(&self, returning: &Option<ReturningClause>, sql: &mut impl SqlWriter) {
1584 if let Some(returning) = returning {
1585 sql.write_str(" RETURNING ").unwrap();
1586 match &returning {
1587 ReturningClause::All => sql.write_str("*").unwrap(),
1588 ReturningClause::Columns(cols) => {
1589 let mut cols_iter = cols.iter();
1590 join_io!(
1591 cols_iter,
1592 column_ref,
1593 join {
1594 sql.write_str(", ").unwrap();
1595 },
1596 do {
1597 self.prepare_column_ref(column_ref, sql);
1598 }
1599 );
1600 }
1601 ReturningClause::Exprs(exprs) => {
1602 let mut exprs_iter = exprs.iter();
1603 join_io!(
1604 exprs_iter,
1605 expr,
1606 join {
1607 sql.write_str(", ").unwrap();
1608 },
1609 do {
1610 self.prepare_expr(expr, sql);
1611 }
1612 );
1613 }
1614 }
1615 }
1616 }
1617
1618 #[doc(hidden)]
1619 fn prepare_condition(
1621 &self,
1622 condition: &ConditionHolder,
1623 keyword: &str,
1624 sql: &mut impl SqlWriter,
1625 ) {
1626 match &condition.contents {
1627 ConditionHolderContents::Empty => (),
1628 ConditionHolderContents::Chain(conditions) => {
1629 sql.write_str(" ").unwrap();
1630 sql.write_str(keyword).unwrap();
1631 sql.write_str(" ").unwrap();
1632 for (i, log_chain_oper) in conditions.iter().enumerate() {
1633 self.prepare_logical_chain_oper(log_chain_oper, i, conditions.len(), sql);
1634 }
1635 }
1636 ConditionHolderContents::Condition(c) => {
1637 sql.write_str(" ").unwrap();
1638 sql.write_str(keyword).unwrap();
1639 sql.write_str(" ").unwrap();
1640 self.prepare_condition_where(c, sql);
1641 }
1642 }
1643 }
1644
1645 #[doc(hidden)]
1646 fn prepare_condition_where(&self, condition: &Condition, sql: &mut impl SqlWriter) {
1648 let simple_expr = condition.clone().into();
1649 self.prepare_expr(&simple_expr, sql);
1650 }
1651
1652 #[doc(hidden)]
1653 fn prepare_frame(&self, frame: &Frame, sql: &mut impl SqlWriter) {
1655 match *frame {
1656 Frame::UnboundedPreceding => sql.write_str("UNBOUNDED PRECEDING").unwrap(),
1657 Frame::Preceding(v) => {
1658 self.prepare_value(v.into(), sql);
1659 sql.write_str("PRECEDING").unwrap();
1660 }
1661 Frame::CurrentRow => sql.write_str("CURRENT ROW").unwrap(),
1662 Frame::Following(v) => {
1663 self.prepare_value(v.into(), sql);
1664 sql.write_str("FOLLOWING").unwrap();
1665 }
1666 Frame::UnboundedFollowing => sql.write_str("UNBOUNDED FOLLOWING").unwrap(),
1667 }
1668 }
1669
1670 #[doc(hidden)]
1671 fn prepare_window_statement(&self, window: &WindowStatement, sql: &mut impl SqlWriter) {
1673 let mut partition_iter = window.partition_by.iter();
1674 join_io!(
1675 partition_iter,
1676 expr,
1677 first {
1678 sql.write_str("PARTITION BY ").unwrap();
1679 },
1680 join {
1681 sql.write_str(", ").unwrap();
1682 },
1683 do {
1684 self.prepare_expr(expr, sql);
1685 }
1686 );
1687
1688 let mut order_iter = window.order_by.iter();
1689 join_io!(
1690 order_iter,
1691 expr,
1692 first {
1693 sql.write_str(" ORDER BY ").unwrap();
1694 },
1695 join {
1696 sql.write_str(", ").unwrap();
1697 },
1698 do {
1699 self.prepare_order_expr(expr, sql);
1700 }
1701 );
1702
1703 if let Some(frame) = &window.frame {
1704 match frame.r#type {
1705 FrameType::Range => sql.write_str(" RANGE ").unwrap(),
1706 FrameType::Rows => sql.write_str(" ROWS ").unwrap(),
1707 };
1708 if let Some(end) = &frame.end {
1709 sql.write_str("BETWEEN ").unwrap();
1710 self.prepare_frame(&frame.start, sql);
1711 sql.write_str(" AND ").unwrap();
1712 self.prepare_frame(end, sql);
1713 } else {
1714 self.prepare_frame(&frame.start, sql);
1715 }
1716 }
1717 }
1718
1719 #[doc(hidden)]
1720 fn binary_expr(&self, left: &Expr, op: &BinOper, right: &Expr, sql: &mut impl SqlWriter) {
1722 let drop_left_higher_precedence =
1724 self.inner_expr_well_known_greater_precedence(left, &(*op).into());
1725
1726 let drop_left_assoc = left.is_binary()
1728 && op == left.get_bin_oper().unwrap()
1729 && self.well_known_left_associative(op);
1730
1731 let left_paren = !drop_left_higher_precedence && !drop_left_assoc;
1732 if left_paren {
1733 sql.write_str("(").unwrap();
1734 }
1735 self.prepare_expr(left, sql);
1736 if left_paren {
1737 sql.write_str(")").unwrap();
1738 }
1739
1740 sql.write_str(" ").unwrap();
1741 self.prepare_bin_oper(op, sql);
1742 sql.write_str(" ").unwrap();
1743
1744 let drop_right_higher_precedence =
1746 self.inner_expr_well_known_greater_precedence(right, &(*op).into());
1747
1748 let op_as_oper = Oper::BinOper(*op);
1749 let drop_right_between_hack = op_as_oper.is_between()
1751 && right.is_binary()
1752 && matches!(right.get_bin_oper(), Some(&BinOper::And));
1753
1754 let drop_right_escape_hack = op_as_oper.is_like()
1756 && right.is_binary()
1757 && matches!(right.get_bin_oper(), Some(&BinOper::Escape));
1758
1759 let drop_right_as_hack = (op == &BinOper::As) && matches!(right, Expr::Custom(_));
1761
1762 let right_paren = !drop_right_higher_precedence
1763 && !drop_right_escape_hack
1764 && !drop_right_between_hack
1765 && !drop_right_as_hack;
1766 if right_paren {
1767 sql.write_str("(").unwrap();
1768 }
1769 self.prepare_expr(right, sql);
1770 if right_paren {
1771 sql.write_str(")").unwrap();
1772 }
1773 }
1774
1775 fn write_string_quoted(&self, string: &str, buffer: &mut impl Write) {
1776 buffer.write_str("'").unwrap();
1777 self.write_escaped(buffer, string);
1778 buffer.write_str("'").unwrap();
1779 }
1780
1781 #[doc(hidden)]
1782 fn write_bytes(&self, bytes: &[u8], buffer: &mut impl Write) {
1784 buffer.write_str("x'").unwrap();
1785 for b in bytes {
1786 write!(buffer, "{b:02X}").unwrap()
1787 }
1788 buffer.write_str("'").unwrap();
1789 }
1790
1791 #[doc(hidden)]
1792 fn if_null_function(&self) -> &str {
1794 "IFNULL"
1795 }
1796
1797 #[doc(hidden)]
1798 fn greatest_function(&self) -> &str {
1800 "GREATEST"
1801 }
1802
1803 #[doc(hidden)]
1804 fn least_function(&self) -> &str {
1806 "LEAST"
1807 }
1808
1809 #[doc(hidden)]
1810 fn char_length_function(&self) -> &str {
1812 "CHAR_LENGTH"
1813 }
1814
1815 #[doc(hidden)]
1816 fn random_function(&self) -> &str {
1818 "RANDOM"
1820 }
1821
1822 #[doc(hidden)]
1823 fn lock_phrase(&self, lock_type: LockType) -> &'static str {
1825 match lock_type {
1826 LockType::Update => "FOR UPDATE",
1827 LockType::NoKeyUpdate => "FOR NO KEY UPDATE",
1828 LockType::Share => "FOR SHARE",
1829 LockType::KeyShare => "FOR KEY SHARE",
1830 }
1831 }
1832
1833 fn insert_default_keyword(&self) -> &str {
1835 "(DEFAULT)"
1836 }
1837
1838 fn insert_default_values(&self, num_rows: u32, sql: &mut impl SqlWriter) {
1840 sql.write_str("VALUES ").unwrap();
1841 if num_rows > 0 {
1842 sql.write_str(self.insert_default_keyword()).unwrap();
1843
1844 for _ in 1..num_rows {
1845 sql.write_str(", ").unwrap();
1846 sql.write_str(self.insert_default_keyword()).unwrap();
1847 }
1848 }
1849 }
1850
1851 fn prepare_constant_true(&self, sql: &mut impl SqlWriter) {
1853 self.prepare_constant(&true.into(), sql);
1854 }
1855
1856 fn prepare_constant_false(&self, sql: &mut impl SqlWriter) {
1858 self.prepare_constant(&false.into(), sql);
1859 }
1860}
1861
1862impl SubQueryStatement {
1863 pub(crate) fn prepare_statement(
1864 &self,
1865 query_builder: &impl QueryBuilder,
1866 sql: &mut impl SqlWriter,
1867 ) {
1868 use SubQueryStatement::*;
1869 match self {
1870 SelectStatement(stmt) => query_builder.prepare_select_statement(stmt, sql),
1871 InsertStatement(stmt) => query_builder.prepare_insert_statement(stmt, sql),
1872 UpdateStatement(stmt) => query_builder.prepare_update_statement(stmt, sql),
1873 DeleteStatement(stmt) => query_builder.prepare_delete_statement(stmt, sql),
1874 WithStatement(stmt) => query_builder.prepare_with_query(stmt, sql),
1875 }
1876 }
1877}
1878
1879pub(crate) struct CommonSqlQueryBuilder;
1880
1881impl OperLeftAssocDecider for CommonSqlQueryBuilder {
1882 fn well_known_left_associative(&self, op: &BinOper) -> bool {
1883 common_well_known_left_associative(op)
1884 }
1885}
1886
1887impl PrecedenceDecider for CommonSqlQueryBuilder {
1888 fn inner_expr_well_known_greater_precedence(&self, inner: &Expr, outer_oper: &Oper) -> bool {
1889 common_inner_expr_well_known_greater_precedence(inner, outer_oper)
1890 }
1891}
1892
1893impl QueryBuilder for CommonSqlQueryBuilder {
1894 fn prepare_query_statement(&self, query: &SubQueryStatement, sql: &mut impl SqlWriter) {
1895 query.prepare_statement(self, sql);
1896 }
1897
1898 fn prepare_select_into(&self, _: &SelectInto, _: &mut impl SqlWriter) {}
1899
1900 fn prepare_value(&self, value: Value, sql: &mut impl SqlWriter) {
1901 sql.push_param(value, self as _);
1902 }
1903}
1904
1905impl QuotedBuilder for CommonSqlQueryBuilder {
1906 fn quote(&self) -> Quote {
1907 QUOTE
1908 }
1909}
1910
1911impl EscapeBuilder for CommonSqlQueryBuilder {}
1912
1913impl TableRefBuilder for CommonSqlQueryBuilder {}
1914
1915#[cfg_attr(
1916 feature = "option-more-parentheses",
1917 allow(unreachable_code, unused_variables)
1918)]
1919pub(crate) fn common_inner_expr_well_known_greater_precedence(
1920 inner: &Expr,
1921 outer_oper: &Oper,
1922) -> bool {
1923 match inner {
1924 Expr::Column(_)
1930 | Expr::Tuple(_)
1931 | Expr::Constant(_)
1932 | Expr::FunctionCall(_)
1933 | Expr::Value(_)
1934 | Expr::Keyword(_)
1935 | Expr::Case(_)
1936 | Expr::SubQuery(_, _)
1937 | Expr::TypeName(_) => true,
1938 Expr::Binary(_, inner_oper, _) => {
1939 #[cfg(feature = "option-more-parentheses")]
1940 {
1941 return false;
1942 }
1943 let inner_oper: Oper = (*inner_oper).into();
1944 if inner_oper.is_arithmetic() || inner_oper.is_shift() {
1945 outer_oper.is_comparison()
1946 || outer_oper.is_between()
1947 || outer_oper.is_in()
1948 || outer_oper.is_like()
1949 || outer_oper.is_logical()
1950 } else if inner_oper.is_comparison()
1951 || inner_oper.is_in()
1952 || inner_oper.is_like()
1953 || inner_oper.is_is()
1954 {
1955 outer_oper.is_logical()
1956 } else {
1957 false
1958 }
1959 }
1960 _ => false,
1961 }
1962}
1963
1964pub(crate) fn common_well_known_left_associative(op: &BinOper) -> bool {
1965 matches!(
1966 op,
1967 BinOper::And | BinOper::Or | BinOper::Add | BinOper::Sub | BinOper::Mul | BinOper::Mod
1968 )
1969}
1970
1971macro_rules! join_io {
1972 ($iter:ident, $item:ident $(, first $first:expr)?, join $join:expr, do $do:expr $(, last $last:expr)?) => {
1973 if let Some($item) = $iter.next() {
1974 $($first)?
1975 $do
1976
1977 for $item in $iter {
1978 $join
1979 $do
1980 }
1981
1982 $($last)?
1983 }
1984 };
1985}
1986
1987pub(crate) use join_io;
1988
1989#[cfg(test)]
1990mod tests {
1991 #[cfg(feature = "with-chrono")]
1992 use chrono::{DateTime, FixedOffset, NaiveDate, NaiveDateTime, NaiveTime, Utc};
1993
1994 use crate::QueryBuilder;
1995
1996 #[test]
2002 #[cfg(feature = "with-chrono")]
2003 fn format_time_constant() {
2004 use crate::{MysqlQueryBuilder, PostgresQueryBuilder, QueryBuilder, SqliteQueryBuilder};
2005
2006 let time = NaiveTime::from_hms_micro_opt(1, 2, 3, 123456)
2007 .unwrap()
2008 .into();
2009
2010 let mut string = String::new();
2011 macro_rules! compare {
2012 ($a:ident, $b:literal) => {
2013 PostgresQueryBuilder.prepare_constant(&$a, &mut string);
2014 assert_eq!(string, $b);
2015
2016 string.clear();
2017
2018 MysqlQueryBuilder.prepare_constant(&$a, &mut string);
2019 assert_eq!(string, $b);
2020
2021 string.clear();
2022
2023 SqliteQueryBuilder.prepare_constant(&$a, &mut string);
2024 assert_eq!(string, $b);
2025
2026 string.clear();
2027 };
2028 }
2029
2030 compare!(time, "'01:02:03.123456'");
2031
2032 let d = NaiveDate::from_ymd_opt(2015, 6, 3).unwrap();
2033 let t = NaiveTime::from_hms_micro_opt(12, 34, 56, 123456).unwrap();
2034
2035 let dt = NaiveDateTime::new(d, t);
2036
2037 let date_time = dt.into();
2038
2039 compare!(date_time, "'2015-06-03 12:34:56.123456'");
2040
2041 let date_time_utc = DateTime::<Utc>::from_naive_utc_and_offset(dt, Utc).into();
2042
2043 compare!(date_time_utc, "'2015-06-03 12:34:56.123456 +00:00'");
2044
2045 let date_time_tz = DateTime::<FixedOffset>::from_naive_utc_and_offset(
2046 dt,
2047 FixedOffset::east_opt(8 * 3600).unwrap(),
2048 )
2049 .into();
2050
2051 compare!(date_time_tz, "'2015-06-03 20:34:56.123456 +08:00'");
2052 }
2053
2054 #[test]
2055 fn prepare_type_ref_escape_array() {
2056 use crate::{PostgresQueryBuilder, TypeRef};
2057
2058 let mut buf = String::new();
2059 let test_cases = [
2060 ("text", r#""text""#),
2061 ("text[]", r#""text"[]"#),
2062 ("text[][]", r#""text"[][]"#),
2063 ("text[][][]", r#""text"[][][]"#),
2064 ("text[][][][]", r#""text"[][][][]"#),
2065 ("text[][][][][]", r#""text"[][][][][]"#),
2066 ];
2067 for (ty, expect) in test_cases {
2068 PostgresQueryBuilder.prepare_type_ref(&TypeRef::from(ty), &mut buf);
2069 assert_eq!(buf, expect);
2070 buf.clear();
2071 }
2072 }
2073}