Expand description
SQL types, columns, and the typed expression AST.
Expr<Req, S> carries two purely phantom compile-time tags: Req (the
flat cons-list of tables this expression touches — see scope::Superset)
and S (its SQL type). The actual payload, ExprKind, is a plain closed
enum with no generics at all, so the renderer is never re-monomorphized
per query shape.
Structs§
- Agg
- The row key an aggregate over
Cis filed under: distinct per function and per column, sosum(a)andsum(b)don’t collide, and named after the column so a DTO field or a CTE column can match it. - Avg
avg(column). NULL over zero rows.- BigInt
- Bool
- Bytes
- Column
- A column reference, identified entirely by its
ColumnKey. Generated per-field by#[derive(Table)]as apub const NAME: Column<..>inside each table’s module (e.g.users::id). A plain,Copyvalue — not tied to any particular query — which is what lets it be reused across queries and passed as an ordinary function argument instead of through a scope-bound cursor closure. - Count
- The identity a selected
count(*)is filed under in a row. - CountOf
count(column)— non-NULL values, unlikecount()’scount(*)rows.- Date
- Expr
- A typed SQL expression.
Reqis the (possibly empty) flat list of tables this expression references — see the module docs andscope::Supersetfor how that’s checked against a query’s actual scope at the point the expression is used, not at the point it’s built. This is what letsorders::user_id.eq(users::id)be a plain, portable value with no dependency on which query it’ll eventually be used in. - Integer
- Keyed
- An expression that carries its own row key
K:count()and the window functions, whose identity is the function that produced them. Selecting two of the same one into a row is whatrow::Row::getrejects, and whatLabelExt::labelexists to resolve. - Labeled
- A selected item filed under a
LabelKeyinstead of under its own identity, and rendered with that name as itsAS. - Max
max(column). NULL over zero rows.- Min
min(column). NULL over zero rows.- Numeric
- RawSlot
- What a slot holds, opaque outside this crate: the
RawArgimpls are the only way to make one, so a slot always holds something the renderer can write. - Real
- Sum
sum(column). NULL over zero rows, so the result is always nullable.- Text
- Timestamptz
- Uuid
Enums§
- BinOp
- SortDir
- Sort direction. Shared by
ORDER BY(select::OrderKey) and window functions’OVER (.. ORDER BY ..)(window::Window), hence living here rather than in either module. - Value
- A closed, non-generic sum of every literal value the crate can bind as a
query parameter. Deliberately not
Box<dyn ToSql>: a plain enum keeps the renderer free of vtable dispatch and lets it stay a single non-generic function no matter how many query shapes exist.
Traits§
- Assigns
To - What an expression can be assigned to. The value’s type is
Selfand the column’s is the parameter, which is the direction assignment runs in: aTextvalue goes into aNullable<Text>column and a narrower number into a wider one, never the reverse. (Comparableis the symmetric, nullability-blind relation, and a comparison is symmetric.) - Bool
Like - What a
WHERE/HAVING/ONclause accepts.Nullable<Bool>belongs here because SQL takes it: a NULL condition selects no row, which is the same answerIS NOT TRUEwould give. - Column
Key - A column’s compile-time identity. One implementor per column in the
schema, generated by
#[derive(Table)](and bywith!{}for a CTE’s pseudo-columns), which is what lets a column be a key — two columns of the same table and SQL type are still distinct types here, so a row can be indexed by column without ambiguity. - Comparable
- Which SQL types may be compared with each other. A nullable column and a
non-nullable one hold the same values, so
users::manager_id.eq(users::id)is an ordinary join predicate; without this relation the two would be unrelated types and every optional foreign key would be unwritable. - Expr
Methods - Comparison/boolean-combinator methods, blanket-implemented for anything
convertible to a typed expression (columns, literals, and
Expritself). Kept separate fromIntoExprso one blanket impl can serve all three. - HasCount
- The identity a selected
count(*)is filed under in a row. - Into
Expr - Converts a value into a typed expression, tagging it with the set of
tables it references (
Nilfor a plain literal,Cons<T, Nil>for a bare column, or whateverReqan already-builtExprcarries). - Label
Ext - Files a selected item under a declared name: the way to select the same expression twice, and the way out of two tables’ same-named columns colliding.
- Label
Key - A caller-declared output-column name, generated by
label!{}. Being a marker overNamedis what keepslabel!{}the only way to make one, andNamed::NAMEthe only place the name is written. - Null
Value - A base SQL type’s typed NULL — see
Value::NullI32etc. for why this can’t just be a single untypedValue::Null. - Ordered
- What
min/maxaccept: a type the databases order. Its own marker for the reasonSummableis one —WrapNullable<MaybeNull>, which stood here before, is implemented for every leaf type, so it gated nothing andmax(bool_column)rendered SQL Postgres has no aggregate for. - RawArg
- One
?slot of asql!{}fragment: every expression, plus theOptiona request field already holds — a slot is the one place a NULL arrives as data rather than as a writtennull::<..>(). A slot that isn’t one reportsIntoExpr, since that is the bound this one is built on. - RawArgs
- The whole slot list of one
sql!{}, whoseReqis every table its slots name. - SqlType
- A SQL scalar type. Implemented only by the closed set of leaf types
declared via
sql_leaf_type!below, plusNullable<T>. - Summable
- What
sum(..)of a column decodes to.sumis NULL over zero rows, so every result is nullable however the column was declared.CASTkeeps the widened type a database picks for a sum inside the closed set of types this crate has: Postgres returnsnumericforsum(bigint)andavg(int), neither of which has a native here. - Text
Like - What
LIKEaccepts: a text expression, nullable or not. Its own marker rather thanComparable<Text>so the failure says what the operator needs instead of talking about comparison. - Writable
- A column a statement may write to:
#[derive(Table)]emits this for every column except the generated and primary-key ones, which are the same set*Updateleaves out.
Functions§
- all_of
- True when all of them are. An empty collection matches everything, which
is what a
WHEREwith no conditions does. - any_of
- True when any of the conditions is. Takes a runtime-length collection,
the way
is_intakes a runtime-length list of values, so theORa search box needs doesn’t have to be folded by hand — folding one by one growsReqand stops type-checking after the first pair. An empty collection matches nothing, which is whatis_in([])says too. - avg
avg(column). NULL over zero rows.- count
- Counts rows.
count_of(column)counts that column’s non-NULL values, which is the different question aLEFT JOINmakes visible. - count_
of count(column)— non-NULL values, unlikecount()’scount(*)rows.- max
max(column). NULL over zero rows.- min
min(column). NULL over zero rows.- null
- A typed SQL
NULL, for the one position anOptioncan’t say it:SET column = NULLassigns, and an assignment has noOptionto beNone.null::<Text>()isNullable<Text>, so only a nullable column accepts it. - sum
sum(column). NULL over zero rows, so the result is always nullable.
Type Aliases§
- Declared
- An expression that has stated what it decodes to but has no name: the
anonymous
Keyed, and so selectable, labellable and usable in a slot on exactly the same terms as any other keyed expression — except thatAnonis notSpelled, so it can’t be looked up or matched by name.