Select
db.select(table) starts a query. Every method is a value-returning step, so a query can be
built, stored, returned from a function and composed before anything runs.
Filter
filter adds a condition. Repeated calls are joined with AND.
or and and compose conditions explicitly when AND between calls is not what you mean:
The whole operator list is in operators.
Order
MySQL has no NULLS FIRST / NULLS LAST; the dialect emulates the common cases with an
IS NULL prefix, which is a different query plan and is documented as such.
Limit and offset
MySQL requires a LIMIT before an OFFSET, so the dialect supplies an unbounded one when
only offset is set.
Distinct
Projection
select(table) returns every column of every table in the query, decoded into T::Model.
pick chooses exactly what comes back, and the row type follows from the selection:
Derived table
A SELECT can read another SELECT as if it were a table, which is how an outer statement
filters or aggregates a limited or grouped result:
select consumes its source, so pass the handle by reference when its columns are also
needed. Subqueries covers column access, expression columns and
the alias rules.
Aggregate
sum and avg return Float8; count_all and count_distinct return Int8.
Join
See joins for the five join kinds, the nullability rules for outer joins, and the row types they produce.
Load a relation
with runs one extra statement instead of a join, so a parent with no children gets
Vec::new() rather than an absent row:
See relations.
Row locking
SQLite has no row locking; the dialect records an error rather than emitting the clause.
Set operations and subqueries
- Set operations —
union,union_all,intersect,except - Subqueries —
EXISTS,IN (SELECT ...), scalar subqueries and derived tables
Streaming
all collects the result set. stream decodes one row at a time, which is what you want when
the set is too large to hold:
The statement is rendered first because a cursor borrows the SQL text for as long as it is open.
What is checked
- The table and column must exist on the table in the query; a join adds its table to the allowed set, and referencing a table you did not join does not compile.
- A filter must be a
Boolexpression, and comparisons require matching SQL types: comparing a text column with an integer is a compile error. pickfixes the row type;allandfirstdecode into exactly that.- An outer join widens the joined side of the row type to
Option, souser.postcannot be used as if it were always present.
Gotchas
order_byon a nullable column is stable per dialect, not per SQL standard. Writenulls_first/nulls_lastif it matters, and check the dialect caveat above.limitandoffsetbind parameters, soLIMITon PostgreSQL is$n, not a literal.firstsetsLIMIT 1; it does not add anORDER BY. Without one, which row you get is the database's choice.- A
GROUP BYquery that projects a column which is neither grouped nor aggregated is accepted by SQLite and rejected by PostgreSQL and MySQL. The type system cannot see this.
