diesel/query_builder/upsert/
on_conflict_target.rs
1use crate::backend::sql_dialect;
2use crate::expression::SqlLiteral;
3use crate::query_builder::*;
4use crate::query_source::Column;
5
6#[doc(hidden)]
7pub trait OnConflictTarget<Table> {}
8
9#[doc(hidden)]
10#[derive(Debug, Clone, Copy, QueryId)]
11pub struct NoConflictTarget;
12
13impl<DB> QueryFragment<DB> for NoConflictTarget
14where
15 DB: Backend,
16 DB::OnConflictClause: sql_dialect::on_conflict_clause::SupportsOnConflictClause,
17{
18 fn walk_ast<'b>(&'b self, _: AstPass<'_, 'b, DB>) -> QueryResult<()> {
19 Ok(())
20 }
21}
22
23impl<Table> OnConflictTarget<Table> for NoConflictTarget {}
24
25#[doc(hidden)]
26#[derive(Debug, Clone, Copy, QueryId)]
27pub struct ConflictTarget<T>(pub T);
28
29impl<DB, T> QueryFragment<DB> for ConflictTarget<T>
30where
31 DB: Backend,
32 Self: QueryFragment<DB, DB::OnConflictClause>,
33{
34 fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
35 <Self as QueryFragment<DB, DB::OnConflictClause>>::walk_ast(self, pass)
36 }
37}
38
39impl<DB, T, SP> QueryFragment<DB, SP> for ConflictTarget<T>
40where
41 DB: Backend<OnConflictClause = SP>,
42 SP: sql_dialect::on_conflict_clause::PgLikeOnConflictClause,
43 T: Column,
44{
45 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
46 out.push_sql(" (");
47 out.push_identifier(T::NAME)?;
48 out.push_sql(")");
49 Ok(())
50 }
51}
52
53impl<T> OnConflictTarget<T::Table> for ConflictTarget<T> where T: Column {}
54
55impl<DB, ST, SP> QueryFragment<DB, SP> for ConflictTarget<SqlLiteral<ST>>
56where
57 DB: Backend<OnConflictClause = SP>,
58 SP: sql_dialect::on_conflict_clause::PgLikeOnConflictClause,
59 SqlLiteral<ST>: QueryFragment<DB>,
60{
61 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
62 out.push_sql(" ");
63 self.0.walk_ast(out.reborrow())?;
64 Ok(())
65 }
66}
67
68impl<Tab, ST> OnConflictTarget<Tab> for ConflictTarget<SqlLiteral<ST>> {}
69
70impl<DB, T, SP> QueryFragment<DB, SP> for ConflictTarget<(T,)>
71where
72 DB: Backend<OnConflictClause = SP>,
73 SP: sql_dialect::on_conflict_clause::PgLikeOnConflictClause,
74 T: Column,
75{
76 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
77 out.push_sql(" (");
78 out.push_identifier(T::NAME)?;
79 out.push_sql(")");
80 Ok(())
81 }
82}
83
84impl<T> OnConflictTarget<T::Table> for ConflictTarget<(T,)> where T: Column {}
85
86macro_rules! on_conflict_tuples {
87 ($(
88 $Tuple:tt {
89 $(($idx:tt) -> $T:ident, $ST:ident, $TT:ident,)*
90 }
91 )+) => {
92 $(
93 impl<_DB, _T, _SP, $($T),*> QueryFragment<_DB, _SP> for ConflictTarget<(_T, $($T),*)> where
94 _DB: Backend<OnConflictClause = _SP>,
95 _SP: sql_dialect::on_conflict_clause::PgLikeOnConflictClause,
96 _T: Column,
97 $($T: Column<Table=_T::Table>,)*
98 {
99 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, _DB>) -> QueryResult<()>
100 {
101 out.push_sql(" (");
102 out.push_identifier(_T::NAME)?;
103 $(
104 out.push_sql(", ");
105 out.push_identifier($T::NAME)?;
106 )*
107 out.push_sql(")");
108 Ok(())
109 }
110 }
111
112 impl<_T, $($T),*> OnConflictTarget<_T::Table> for ConflictTarget<(_T, $($T),*)> where
113 _T: Column,
114 $($T: Column<Table=_T::Table>,)*
115 {
116 }
117 )*
118 }
119}
120
121diesel_derives::__diesel_for_each_tuple!(on_conflict_tuples);