diesel/query_builder/upsert/
on_conflict_clause.rs

1use super::on_conflict_actions::*;
2use super::on_conflict_target::*;
3use crate::backend::sql_dialect;
4use crate::insertable::*;
5use crate::query_builder::where_clause::{NoWhereClause, WhereClause};
6use crate::query_builder::*;
7
8#[doc(hidden)]
9#[derive(Debug, Clone, Copy)]
10pub struct OnConflictValues<Values, Target, Action, WhereClause = NoWhereClause> {
11    pub(crate) values: Values,
12    pub(crate) target: Target,
13    pub(crate) action: Action,
14    /// Allow to apply filters on ON CONFLICT ... DO UPDATE ... WHERE ...
15    pub(crate) where_clause: WhereClause,
16}
17
18impl<Values, Target, Action, WhereClause> QueryId
19    for OnConflictValues<Values, Target, Action, WhereClause>
20{
21    type QueryId = ();
22
23    const HAS_STATIC_QUERY_ID: bool = false;
24}
25
26impl<Values, T> OnConflictValues<Values, NoConflictTarget, DoNothing<T>, NoWhereClause> {
27    pub(crate) fn do_nothing(values: Values) -> Self {
28        Self::new(values, NoConflictTarget, DoNothing::new(), NoWhereClause)
29    }
30}
31
32impl<Values, Target, Action, WhereClause> OnConflictValues<Values, Target, Action, WhereClause> {
33    pub(crate) fn new(
34        values: Values,
35        target: Target,
36        action: Action,
37        where_clause: WhereClause,
38    ) -> Self {
39        OnConflictValues {
40            values,
41            target,
42            action,
43            where_clause,
44        }
45    }
46
47    pub(crate) fn replace_where<Where, F>(
48        self,
49        f: F,
50    ) -> OnConflictValues<Values, Target, Action, Where>
51    where
52        F: FnOnce(WhereClause) -> Where,
53    {
54        OnConflictValues::new(self.values, self.target, self.action, f(self.where_clause))
55    }
56}
57
58impl<DB, Values, Target, Action, WhereClause> CanInsertInSingleQuery<DB>
59    for OnConflictValues<Values, Target, Action, WhereClause>
60where
61    DB: Backend,
62    DB::OnConflictClause: sql_dialect::on_conflict_clause::SupportsOnConflictClause,
63    Values: CanInsertInSingleQuery<DB>,
64{
65    fn rows_to_insert(&self) -> Option<usize> {
66        self.values.rows_to_insert()
67    }
68}
69
70impl<DB, Values, Target, Action> QueryFragment<DB>
71    for OnConflictValues<Values, Target, Action, NoWhereClause>
72where
73    DB: Backend,
74    DB::OnConflictClause: sql_dialect::on_conflict_clause::SupportsOnConflictClause,
75    Self: QueryFragment<DB, DB::OnConflictClause>,
76{
77    fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
78        <Self as QueryFragment<DB, DB::OnConflictClause>>::walk_ast(self, pass)
79    }
80}
81
82impl<DB, Values, Target, Action, SD> QueryFragment<DB, SD>
83    for OnConflictValues<Values, Target, Action, NoWhereClause>
84where
85    DB: Backend<OnConflictClause = SD>,
86    SD: sql_dialect::on_conflict_clause::PgLikeOnConflictClause,
87    Values: QueryFragment<DB>,
88    Target: QueryFragment<DB>,
89    Action: QueryFragment<DB>,
90{
91    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
92        self.values.walk_ast(out.reborrow())?;
93        out.push_sql(" ON CONFLICT");
94        self.target.walk_ast(out.reborrow())?;
95        self.action.walk_ast(out.reborrow())?;
96        Ok(())
97    }
98}
99
100impl<DB, Values, Target, Action, Expr> QueryFragment<DB>
101    for OnConflictValues<Values, Target, Action, WhereClause<Expr>>
102where
103    DB: Backend,
104    DB::OnConflictClause: sql_dialect::on_conflict_clause::SupportsOnConflictClause,
105    DB::OnConflictClause: sql_dialect::on_conflict_clause::SupportsOnConflictClauseWhere,
106    Values: QueryFragment<DB>,
107    Target: QueryFragment<DB>,
108    Action: QueryFragment<DB>,
109    WhereClause<Expr>: QueryFragment<DB>,
110{
111    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
112        self.values.walk_ast(out.reborrow())?;
113        out.push_sql(" ON CONFLICT");
114        self.target.walk_ast(out.reborrow())?;
115        self.action.walk_ast(out.reborrow())?;
116        self.where_clause.walk_ast(out.reborrow())?;
117        Ok(())
118    }
119}