Update Statement
Relevant source files
The following files were used as context for generating this wiki page:
The UpdateStatement is a core component of the SeaQuery library used to construct dynamic SQL UPDATE queries. It provides a fluent Rust API to define target tables, modify column values, apply conditional filters, and handle database-specific features like RETURNING clauses or Common Table Expressions (CTEs).
Sources: src/query/update.rs:1-35, src/lib.rs:1-40
Architecture and Data Structure
The UpdateStatement is structured as an Abstract Syntax Tree (AST) node that collects all necessary information to build a valid SQL string for different database backends (MySQL, Postgres, and SQLite).
The UpdateStatement Struct
The internal structure maintains several vectors and options to store the query state:
| Field | Type | Description |
|---|---|---|
table | Option<Box<TableRef>> | The primary table being updated. |
from | Vec<TableRef> | Additional tables for UPDATE .. FROM or join syntax. |
values | Vec<(DynIden, Box<Expr>)> | A collection of column identifiers and their new values (expressions). |
where | ConditionHolder | Filters applied to determine which rows to update. |
orders | Vec<OrderExpr> | Ordering criteria (primarily for MySQL/SQLite limit support). |
limit | Option<Value> | Maximum number of rows to update. |
returning | Option<ReturningClause> | Specifies columns to return after the update (Postgres/SQLite). |
with | Option<WithClause> | Common Table Expressions (CTEs) associated with the query. |
Sources: src/query/update.rs:43-52
Component Relationships
This diagram shows how UpdateStatement interacts with other query components:
Sources: src/query/update.rs:43-52, src/lib.rs:560-590
Query Construction Logic
Assigning Values
The API provides two primary ways to set new values:
value(col, expr): Sets a single column to a specific expression or value.values([(col, expr), ...]): Sets multiple column-value pairs simultaneously.
Sources: src/query/update.rs:152-162, src/query/update.rs:188-193
Joins and Multi-Table Updates
SeaQuery supports updating data based on other tables using the from() method. The implementation varies significantly by backend:
- Postgres/SQLite: Translated to the
UPDATE ... FROM ...syntax. - MySQL: Since MySQL does not support
UPDATE FROM, the builder transforms this into anUPDATE JOINsyntax.
Sources: src/query/update.rs:80-100, src/backend/mysql/query.rs:163-176
Execution Flow
The following sequence diagram illustrates the process of building an Update string from the statement:
Backend-Specific Implementations
Backend Capabilities Table
| Feature | MySQL Support | Postgres Support | SQLite Support |
|---|---|---|---|
UPDATE FROM | Transformed to JOIN | Native | Native |
LIMIT | Yes | No | Yes |
ORDER BY | Yes | No | Yes |
RETURNING | No | Yes | Yes |
Sources: src/backend/query_builder.rs:240-270, src/backend/mysql/query.rs:180-205, README.md:320-340
MySQL Join Transformation
In src/backend/mysql/query.rs, the prepare_update_join function handles the specific logic for MySQL. It injects a JOIN clause immediately after the UPDATE table declaration and uses the provided conditions to form the ON clause.
Sources: src/backend/mysql/query.rs:163-176
Statement Explanations
UpdateStatement can be used within an ExplainStatement to analyze query performance. The ExplainableStatement enum wraps the update statement, allowing query builders to prepare the appropriate EXPLAIN UPDATE ... syntax.
impl From<UpdateStatement> for ExplainableStatement {
fn from(value: UpdateStatement) -> Self {
Self::Update(value)
}
}
Sources: src/query/explain.rs:55-75
Usage Example
The fluent interface allows for building complex updates conditionally.
let query = Query::update()
.table(Glyph::Table)
.value(Glyph::Aspect, Expr::cust("60 * 24 * 24"))
.values([
(Glyph::Image, "abc".into()),
])
.and_where(Expr::col(Glyph::Id).eq(1))
.to_owned();
Sources: src/query/update.rs:165-185
Conclusion
The UpdateStatement provides a robust, type-safe abstraction for SQL UPDATE operations. By abstracting the syntactical differences between MySQL's join-based updates and Postgres's from-based updates, it allows developers to write backend-agnostic update logic that remains performant and accurate.