Skip to main content

IncompleteOnConflict

Struct IncompleteOnConflict 

Source
pub struct IncompleteOnConflict<Stmt, Target> { /* private fields */ }
Expand description

A partially constructed ON CONFLICT clause.

Implementations§

Source§

impl<T: QuerySource, U, Op, Ret, Target> IncompleteOnConflict<InsertStatement<T, U, Op, Ret>, Target>

Source

pub fn do_nothing(self) -> DoNothing<Self>

Creates a query with ON CONFLICT (target) DO NOTHING

If you want to do nothing when any constraint conflicts, use on_conflict_do_nothing instead. See on_conflict for usage examples.

Source

pub fn do_update(self) -> DoUpdate<Self>

Used to create a query in the form ON CONFLICT (...) DO UPDATE ... [WHERE ...]

Call .set on the result of this function with the changes you want to apply. The argument to set can be anything that implements AsChangeset (e.g. anything you could pass to set on a normal update statement).

Note: When inserting more than one row at a time, this query can still fail if the rows being inserted conflict with each other.

For some backends (PostgreSQL, SQLite) a WHERE clause can be used to limit the rows actually updated. For PostgreSQL and SQLite you can use the .filter() method to add conditions like that.

§Examples
§Set specific value on conflict

PostgreSQL/SQLite:

let user = User {
    id: 1,
    name: "Pascal",
};
let user2 = User {
    id: 1,
    name: "Sean",
};

assert_eq!(
    Ok(1),
    diesel::insert_into(users).values(&user).execute(conn)
);

let insert_count = diesel::insert_into(users)
    .values(&user2)
    .on_conflict(id)
    .do_update()
    .set(name.eq("I DONT KNOW ANYMORE"))
    .execute(conn);
assert_eq!(Ok(1), insert_count);
assert_eq!(Ok(2), insert_count);

let users_in_db = users.load(conn);
assert_eq!(
    Ok(vec![(1, "I DONT KNOW ANYMORE".to_string())]),
    users_in_db
);

MySQL:

let user = User {
    id: 1,
    name: "Pascal",
};
let user2 = User {
    id: 1,
    name: "Sean",
};

assert_eq!(
    Ok(1),
    diesel::insert_into(users).values(&user).execute(conn)
);

diesel::insert_into(users)
    .values(&user2)
    .on_conflict(diesel::dsl::DuplicatedKeys)
    .do_update()
    .set(name.eq("I DONT KNOW ANYMORE"))
    .execute(conn)?;

let users_in_db = users.load(conn);
assert_eq!(
    Ok(vec![(1, "I DONT KNOW ANYMORE".to_string())]),
    users_in_db
);
§Set AsChangeset struct on conflict

PostgreSQL & SQLite:

let user = User {
    id: 1,
    name: "Pascal",
};
let user2 = User {
    id: 1,
    name: "Sean",
};

assert_eq!(
    Ok(1),
    diesel::insert_into(users).values(&user).execute(conn)
);

let insert_count = diesel::insert_into(users)
    .values(&user2)
    .on_conflict(id)
    .do_update()
    .set(&user2)
    .execute(conn);
assert_eq!(Ok(1), insert_count);

let users_in_db = users.load(conn);
assert_eq!(Ok(vec![(1, "Sean".to_string())]), users_in_db);

MySQL:


let user = User {
    id: 1,
    name: "Pascal",
};
let user2 = User {
    id: 1,
    name: "Sean",
};

assert_eq!(
    Ok(1),
    diesel::insert_into(users).values(&user).execute(conn)
);

diesel::insert_into(users)
    .values(&user2)
    .on_conflict(diesel::dsl::DuplicatedKeys)
    .do_update()
    .set(&user2)
    .execute(conn)?;

let users_in_db = users.load(conn);
assert_eq!(Ok(vec![(1, "Sean".to_string())]), users_in_db);
§Use excluded to get the rejected value
use diesel::upsert::excluded;

let user = User {
    id: 1,
    name: "Pascal",
};
let user2 = User {
    id: 1,
    name: "Sean",
};
let user3 = User {
    id: 2,
    name: "Tess",
};

assert_eq!(
    Ok(1),
    diesel::insert_into(users).values(&user).execute(conn)
);

#[cfg(feature = "postgres")]
let insert_count = diesel::insert_into(users)
    .values(&vec![user2, user3])
    .on_conflict(id)
    .do_update()
    .set(name.eq(excluded(name)))
    .execute(conn);
assert_eq!(Ok(2), insert_count);

let users_in_db = users.load(conn);
assert_eq!(
    Ok(vec![(1, "Sean".to_string()), (2, "Tess".to_string())]),
    users_in_db
);
§Use .filter()method to limit the rows actually updated
use self::users::dsl::*;
let user = User {
    id: 1,
    name: "Pascal",
};
let user2 = User {
    id: 1,
    name: "Sean",
};

assert_eq!(
    Ok(1),
    diesel::insert_into(users).values(&user).execute(conn)
);

let insert_count = diesel::insert_into(users)
    .values(&user2)
    .on_conflict(id)
    .do_update()
    .set(&user2)
    .filter(id.ge(5))
    .execute(conn);
assert_eq!(Ok(0), insert_count);

let users_in_db = users.load(conn);
assert_eq!(Ok(vec![(1, "Pascal".to_string())]), users_in_db);

Trait Implementations§

Source§

impl<Stmt: Clone, Target: Clone> Clone for IncompleteOnConflict<Stmt, Target>

Source§

fn clone(&self) -> IncompleteOnConflict<Stmt, Target>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<Stmt: Copy, Target: Copy> Copy for IncompleteOnConflict<Stmt, Target>

Source§

impl<Stmt: Debug, Target: Debug> Debug for IncompleteOnConflict<Stmt, Target>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<Stmt, T, P> DecoratableTarget<P> for IncompleteOnConflict<Stmt, T>

Source§

fn filter_target(self, predicate: P) -> Self::FilterOutput

Adds a WHERE predicate to the ON CONFLICT target, telling PostgreSQL which unique index to check for conflicts.

This generates ON CONFLICT (target) WHERE predicate DO ... SQL. PostgreSQL selects unique indexes whose WHERE clause is implied by the predicate. The predicate does not need to exactly match the index’s WHERE clause; implication is sufficient.

Calling .filter_target() multiple times combines the predicates with AND. PostgreSQL only.

§Example

diesel::sql_query(
    "CREATE UNIQUE INDEX users_name_active ON users (name) WHERE id > 5",
)
.execute(conn)?;

let user = User { id: 10, name: "Sean" };
diesel::insert_into(users).values(&user).execute(conn)?;

// id=11 satisfies the partial index predicate, so uniqueness is violated: does nothing.
let count = diesel::insert_into(users)
    .values(User { id: 11, name: "Sean" })
    .on_conflict(name)
    .filter_target(id.gt(5))
    .do_nothing()
    .execute(conn)?;
assert_eq!(count, 0);

// id=3 does not satisfy the partial index predicate, so it is not covered by the index:
// no uniqueness violation, inserts normally.
let count = diesel::insert_into(users)
    .values(User { id: 3, name: "Sean" })
    .on_conflict(name)
    .filter_target(id.gt(5))
    .do_nothing()
    .execute(conn)?;
assert_eq!(count, 1);
§Do update

diesel::sql_query(
    "CREATE UNIQUE INDEX users_name_do_update ON users (name) WHERE id > 5",
)
.execute(conn)?;

diesel::insert_into(users)
    .values(User { id: 10, name: "Sean" })
    .execute(conn)?;

// id=11 satisfies the partial index predicate, so uniqueness is violated: name updated.
diesel::insert_into(users)
    .values(User { id: 11, name: "Sean" })
    .on_conflict(name)
    .filter_target(id.gt(5))
    .do_update()
    .set(name.eq("Updated"))
    .execute(conn)?;

let names = users.filter(id.gt(5)).select(name).load::<String>(conn)?;
assert_eq!(names, vec!["Updated"]);
§Chaining filter_target

Calling .filter_target() multiple times combines the predicates with AND, which is useful when the unique index WHERE clause has multiple conditions.


diesel::sql_query(
    "CREATE UNIQUE INDEX users_name_range ON users (name) WHERE id > 5 AND id < 100",
)
.execute(conn)?;

diesel::insert_into(users)
    .values(User { id: 10, name: "Sean" })
    .execute(conn)?;

// Combined predicate matches the partial index, conflict detected: do nothing.
let count = diesel::insert_into(users)
    .values(User { id: 11, name: "Sean" })
    .on_conflict(name)
    .filter_target(id.gt(5))
    .filter_target(id.lt(100))
    .do_nothing()
    .execute(conn)?;
assert_eq!(count, 0);
Source§

type FilterOutput = IncompleteOnConflict<Stmt, <T as DecoratableTarget<P>>::FilterOutput>

The type returned by filter_target.

Auto Trait Implementations§

§

impl<Stmt, Target> Freeze for IncompleteOnConflict<Stmt, Target>
where Stmt: Freeze, Target: Freeze,

§

impl<Stmt, Target> RefUnwindSafe for IncompleteOnConflict<Stmt, Target>
where Stmt: RefUnwindSafe, Target: RefUnwindSafe,

§

impl<Stmt, Target> Send for IncompleteOnConflict<Stmt, Target>
where Stmt: Send, Target: Send,

§

impl<Stmt, Target> Sync for IncompleteOnConflict<Stmt, Target>
where Stmt: Sync, Target: Sync,

§

impl<Stmt, Target> Unpin for IncompleteOnConflict<Stmt, Target>
where Stmt: Unpin, Target: Unpin,

§

impl<Stmt, Target> UnsafeUnpin for IncompleteOnConflict<Stmt, Target>
where Stmt: UnsafeUnpin, Target: UnsafeUnpin,

§

impl<Stmt, Target> UnwindSafe for IncompleteOnConflict<Stmt, Target>
where Stmt: UnwindSafe, Target: UnwindSafe,

Blanket Implementations§

Source§

impl<T> AggregateExpressionMethods for T

Source§

fn aggregate_distinct(self) -> AggregateDistinct<Self>
where Self: DistinctDsl,

DISTINCT modifier for aggregate functions Read more
Source§

fn aggregate_all(self) -> AggregateAll<Self>
where Self: AllDsl,

ALL modifier for aggregate functions Read more
Source§

fn aggregate_filter<P>(self, f: P) -> AggregateFilter<Self, P>
where P: AsExpression<Bool>, Self: FilterDsl<P::Expression>,

Add an aggregate function filter Read more
Source§

fn aggregate_order<O>(self, o: O) -> AggregateOrder<Self, O>
where Self: OrderAggregateDsl<O>,

Add an aggregate function order Read more
Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSend for T
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoSql for T

Source§

fn into_sql<T>(self) -> AsExprOf<Self, T>

Convert self to an expression for Diesel’s query builder. Read more
Source§

fn as_sql<'a, T>(&'a self) -> AsExprOf<&'a Self, T>
where &'a Self: AsExpression<T>, T: SqlType + TypedExpressionType,

Convert &self to an expression for Diesel’s query builder. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WindowExpressionMethods for T

Source§

fn over(self) -> Over<Self>
where Self: OverDsl,

Turn a function call into a window function call Read more
Source§

fn window_filter<P>(self, f: P) -> WindowFilter<Self, P>
where P: AsExpression<Bool>, Self: FilterDsl<P::Expression>,

Add a filter to the current window function Read more
Source§

fn partition_by<E>(self, expr: E) -> PartitionBy<Self, E>
where Self: PartitionByDsl<E>,

Add a partition clause to the current window function Read more
Source§

fn window_order<E>(self, expr: E) -> WindowOrder<Self, E>
where Self: OrderWindowDsl<E>,

Add a order clause to the current window function Read more
Source§

fn frame_by<E>(self, expr: E) -> FrameBy<Self, E>
where Self: FrameDsl<E>,

Add a frame clause to the current window function Read more