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