Repository: diesel-rs/diesel
File: diesel/src/query_builder/upsert/on_conflict_clause.rs (Rust)

Code before:
    }

    pub(crate) fn replace_where<Where, F>(
        self,
        f: F,
    ) -> OnConflictValues<Values, Target, Action, Where>
    where
        F: FnOnce(WhereClause) -> Where,
    {
        OnConflictValues::new(self.values, self.target, self.action, f(self.where_clause))
    }
}

impl<DB, Values, Target, Action, WhereClause> CanInsertInSingleQuery<DB>
    for OnConflictValues<Values, Target, Action, WhereClause>
where
    DB: Backend,
    DB::OnConflictClause: sql_dialect::on_conflict_clause::SupportsOnConflictClause,
    Values: CanInsertInSingleQuery<DB>,
{
    fn rows_to_insert(&self) -> Option<usize> {
        self.values.rows_to_insert()
    }
}

impl<DB, Values, Target, Action, WhereClause> QueryFragment<DB>
    for OnConflictValues<Values, Target, Action, WhereClause>
where
    DB: Backend,
    DB::OnConflictClause: sql_dialect::on_conflict_clause::SupportsOnConflictClause,
    Values: QueryFragment<DB>,
    Target: QueryFragment<DB>,
    Action: QueryFragment<DB>,
    WhereClause: QueryFragment<DB>,
{
    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
        self.values.walk_ast(out.reborrow())?;
        out.push_sql(" ON CONFLICT");
        self.target.walk_ast(out.reborrow())?;
        self.action.walk_ast(out.reborrow())?;
        self.where_clause.walk_ast(out.reborrow())?;
        Ok(())
    }
}


Review comment (bug):
This needs to be split into two seperate impls. One for for `NoWhereClause` that's there for all supported backends and one for `WhereClause{}` that's only there for postgres

In addition I would like to see an additional compile fail test that demonstrates that this does not compile with non-postgres backends.

Code after:
    }

    pub(crate) fn replace_where<Where, F>(
        self,
        f: F,
    ) -> OnConflictValues<Values, Target, Action, Where>
    where
        F: FnOnce(WhereClause) -> Where,
    {
        OnConflictValues::new(self.values, self.target, self.action, f(self.where_clause))
    }
}

impl<DB, Values, Target, Action, WhereClause> CanInsertInSingleQuery<DB>
    for OnConflictValues<Values, Target, Action, WhereClause>
where
    DB: Backend,
    DB::OnConflictClause: sql_dialect::on_conflict_clause::SupportsOnConflictClause,
    Values: CanInsertInSingleQuery<DB>,
{
    fn rows_to_insert(&self) -> Option<usize> {
        self.values.rows_to_insert()
    }
}

impl<DB, Values, Target, Action> QueryFragment<DB>
    for OnConflictValues<Values, Target, Action, NoWhereClause>
where
    DB: Backend,
    DB::OnConflictClause: sql_dialect::on_conflict_clause::SupportsOnConflictClause,
    Values: QueryFragment<DB>,
    Target: QueryFragment<DB>,
    Action: QueryFragment<DB>,
{
    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
        self.values.walk_ast(out.reborrow())?;
        out.push_sql(" ON CONFLICT");
        self.target.walk_ast(out.reborrow())?;
        self.action.walk_ast(out.reborrow())?;
        Ok(())
    }
}

impl<DB, Values, Target, Action, Expr> QueryFragment<DB>
    for OnConflictValues<Values, Target, Action, WhereClause<Expr>>
where
    DB: Backend,
    DB::OnConflictClause: sql_dialect::on_conflict_clause::SupportsOnConflictClause,
    DB::OnConflictClause: sql_dialect::on_conflict_clause::SupportsOnConflictClauseWhere,
    Values: QueryFragment<DB>,
    Target: QueryFragment<DB>,