Insert Statement
Relevant source files
The following files were used as context for generating this wiki page:
The InsertStatement is a core component of the SeaQuery library designed to construct dynamic SQL INSERT queries. It provides a fluent, type-safe API for defining target tables, columns, and data sources, supporting various database backends including MySQL, PostgreSQL, and SQLite. Sources: src/query/insert.rs:35-46, src/lib.rs:18-24
In SeaQuery, an InsertStatement acts as an Abstract Syntax Tree (AST) node that can be serialized into backend-specific SQL strings or prepared statements with parameter bindings. This allows developers to target multiple database engines while maintaining a single source of query logic. Sources: src/lib.rs:170-178, src/query/insert.rs:567-573
Architecture and Data Structures
The InsertStatement structure encapsulates all necessary components of an SQL insert operation. It manages table references, column identifiers, and the source of the values to be inserted. Sources: src/query/insert.rs:47-56
Core Components
| Component | Type | Description |
|---|---|---|
replace | bool | Determines if REPLACE should be used instead of INSERT (MySQL/SQLite). |
table | Option<Box<TableRef>> | The target table for the operation. |
columns | Vec<DynIden> | The list of columns to be populated. |
source | Option<InsertValueSource> | The origin of data (either raw values or a sub-select). |
on_conflict | Option<OnConflict> | Logic for handling duplicate key conflicts. |
returning | Option<ReturningClause> | Specifies columns to return after the insert (Postgres/SQLite). |
default_values | Option<u32> | Number of rows to insert using DEFAULT values. |
with | Option<WithClause> | Common Table Expressions (CTE) associated with the query. |
Sources: src/query/insert.rs:47-56, src/query/insert.rs:105-115
Insert Value Sources
The data source for an insert operation is represented by the InsertValueSource enum, which allows for either direct value sets or dynamic selection from other tables. Sources: src/query/insert.rs:14-18
The diagram shows the relationship between the InsertStatement and its primary data provider. Sources: src/query/insert.rs:14-18, src/query/insert.rs:47-56
Query Construction Flow
Building an InsertStatement typically follows a builder pattern, starting with a table definition and progressing to data attachment. Sources: src/query/insert.rs:65-75
Data Binding Methods
The statement supports multiple ways to attach data, including individual rows, iterators, or complex subqueries. Sources: src/query/insert.rs:148-158, src/query/insert.rs:228-238
- Direct Values: Rows are added via
values()orvalues_panic(). The library validates that the number of values matches the defined columns. Sources: src/query/insert.rs:228-245 - Select From: The
select_from()method allows inserting the result of aSelectStatement. The number of selected expressions must match the insert columns. Sources: src/query/insert.rs:198-208 - Default Values: Using
or_default_values()oror_default_values_many(n)generatesDEFAULT VALUESor backend-specific equivalents. Sources: src/query/insert.rs:511-525
The flow diagram represents the standard sequence for constructing a valid insert query. Sources: src/query/insert.rs:38-44, src/query/insert.rs:148-158, src/query/insert.rs:198-208
Backend Serialization
The translation of an InsertStatement AST into raw SQL is handled by the QueryBuilder trait implementations (e.g., MysqlQueryBuilder, PostgresQueryBuilder). Sources: src/backend/query_builder.rs:24-34
Serialization Logic
The prepare_insert_statement_common function implements the core logic shared across backends: Sources: src/backend/query_builder.rs:34-40
- CTE Preparation: If a
WITHclause exists, it is serialized first. Sources: src/backend/query_builder.rs:35-37 - Keyword Selection: Decides between
INSERT INTOandREPLACE INTO. Sources: src/backend/query_builder.rs:39-40 - Column Listing: Serializes the list of target columns within parentheses. Sources: src/backend/query_builder.rs:56-68
- Source Serialization:
- For
Values, it iterates through rows and expressions, applying necessary parentheses and commas. Sources: src/backend/query_builder.rs:78-100 - For
Select, it delegates to the select statement's serializer. Sources: src/backend/query_builder.rs:104-106
- For
- Conflict and Return: Appends
ON CONFLICTandRETURNINGclauses at the end. Sources: src/backend/query_builder.rs:111-113
Backend Differences
While the structure is unified, backends exhibit different behaviors for specific features like conflict resolution. Sources: src/lib.rs:170-178
| Feature | MySQL | PostgreSQL | SQLite |
|---|---|---|---|
| Upsert | ON DUPLICATE KEY UPDATE | ON CONFLICT (...) DO UPDATE | ON CONFLICT (...) DO UPDATE |
| Replace | REPLACE INTO | Not Supported | REPLACE INTO |
| Returning | Not Supported | RETURNING ... | RETURNING ... |
| Default | VALUES () | VALUES (DEFAULT) | DEFAULT VALUES |
Sources: src/backend/query_builder.rs:43-52, src/backend/query_builder.rs:900-915, src/lib.rs:180-192
Conflict Handling
Conflict handling is managed via the OnConflict structure, which can be attached to an InsertStatement. This allows for "Upsert" operations. Sources: src/query/insert.rs:373-380
This sequence illustrates how conflict logic is integrated during the build process. Sources: src/query/insert.rs:373-380, src/backend/query_builder.rs:111-113, src/backend/query_builder.rs:780-788
Summary
The InsertStatement provides a robust abstraction for SQL insertion operations. By separating the logical structure of the query from the backend-specific syntax, it enables dynamic query generation and cross-database compatibility. Its support for raw values, subqueries, and complex conflict resolution makes it a versatile tool for database interactions in Rust. Sources: src/lib.rs:18-24, src/query/insert.rs:35-46