Conditions (Cond)
Relevant source files
The following files were used as context for generating this wiki page:
The Condition system in SeaQuery provides a fluent and type-safe API for constructing complex SQL logical expressions. It serves as the primary mechanism for building WHERE and HAVING clauses, allowing developers to combine multiple expressions using AND or OR logic while managing operator precedence and grouping automatically.
Sources: src/query/condition.rs:1-12, src/lib.rs:370-375, README.md:143-150
Core Architecture
Conditions are represented as an Abstract Syntax Tree (AST) through the Condition struct. This structure recursively holds ConditionExpression variants, which can either be a leaf SQL expression (Expr) or another nested Condition. This nesting enables the construction of arbitrarily complex logical trees.
Data Structures
| Struct/Enum | Description |
|---|---|
Condition (alias Cond) | The main container for a logical group, managing a list of sub-conditions and a ConditionType. |
ConditionType | Enum defining the logical operator used to join sub-conditions: Any (OR) or All (AND). |
ConditionExpression | An internal enum representing either a raw Expr or a nested Condition. |
ConditionHolder | A wrapper used in statement builders to store the current state of conditions. |
Sources: src/query/condition.rs:5-24, src/query/condition.rs:60-64, src/query/condition.rs:75-78
Logical Relationships
The following diagram illustrates how conditions are structured and recursively nested:
The Condition struct manages logical grouping, while ConditionExpression allows for recursive nesting.
Sources: src/query/condition.rs:5-58
Usage and Implementation
Condition Types: Any vs All
SeaQuery distinguishes between disjunctive (OR) and conjunctive (AND) groupings through static constructors:
Cond::any(): Initializes a condition set where elements are joined byOR.Cond::all(): Initializes a condition set where elements are joined byAND.
Sources: src/query/condition.rs:136-160
Fluent API Methods
The Condition struct provides methods to dynamically build logical sets:
add<C>(condition: C): Adds a new expression or sub-condition to the current set.add_option<C>(other: Option<C>): Conditionally adds a sub-condition if the option isSome.not(): Negates the entire condition block, wrapping it inNOT (...)during SQL serialization.
Sources: src/query/condition.rs:80-134, src/query/condition.rs:162-214
Macros
Convenience macros any! and all! are provided to simplify the creation of nested logic without manual method chaining.
// Using macros for nested logic
Query::select().cond_where(any![
Expr::col(Glyph::Aspect).is_in([3, 4]),
all![
Expr::col(Glyph::Aspect).is_null(),
Expr::col(Glyph::Image).like("A%")
]
]);
Sources: src/query/condition.rs:293-334, README.md:330-340
Integration with Statements
The ConditionalStatement trait allows query builders like SelectStatement, UpdateStatement, and DeleteStatement to ingest conditions.
Statement Methods
| Method | Description |
|---|---|
and_where(Expr) | Appends a raw expression to the statement's WHERE clause using AND. |
cond_where(Condition) | Conjoins a complex Condition object to the existing WHERE clause. |
and_having(Expr) | Appends an expression to the HAVING clause in SELECT statements. |
Sources: src/query/condition.rs:341-365, src/query/select.rs:1320-1345
Internal Handling (ConditionHolder)
Statement builders use a ConditionHolder to track how conditions are added. If a user mixes legacy and_where calls with the modern cond_where API, the system is designed to handle the transition, though certain combinations may trigger a panic to prevent ambiguous logic.
Sources: src/query/condition.rs:500-545
SQL Serialization
During the build process, the QueryBuilder trait translates the Condition AST into string segments.
The serialization process ensures correct placement of logical operators and parentheses.
Sources: src/backend/query_builder.rs:1090-1115, src/query/condition.rs:253-280
Precedence and Parentheses
SeaQuery's QueryBuilder logic includes a PrecedenceDecider to determine when parentheses are required. This ensures that the generated SQL is both valid and readable without excessive nesting.
Sources: src/backend/query_builder.rs:885-915, src/backend/query_builder.rs:1010-1050
Conclusion
The Condition module is a vital component of SeaQuery that abstracts the complexity of SQL logical operators into a structured Rust API. By utilizing the Cond alias and associated macros, developers can build complex, nested queries that remain maintainable and database-agnostic.