pub struct Query { /* private fields */ }Expand description
The fluent builder. Holds the Ast under construction plus a pending
correlation — the (child, parent) field pairs siphoned from
where(child, row.col(parent)) calls, which the enclosing sub /
where_exists drains.
Implementations§
Source§impl Query
impl Query
Sourcepub fn alias(self, alias: &str) -> Query
pub fn alias(self, alias: &str) -> Query
Set this query’s alias (the relationship name when it is a sub/exists
child). Usually left to Query::sub_as.
Sourcepub fn select(self, col: &str) -> Query
pub fn select(self, col: &str) -> Query
Project a column. Chain for several (.select("a").select("b")); omit
entirely to select all columns.
Sourcepub fn where(self, field: &str, value: impl IntoRhs) -> Query
pub fn where(self, field: &str, value: impl IntoRhs) -> Query
field = value — or, if value is a row.col(..) Parent ref, a
correlation to the parent (child field ↔ parent column). See module docs.
Sourcepub fn where_op(
self,
field: &str,
op: impl IntoOp,
value: impl IntoLit,
) -> Query
pub fn where_op( self, field: &str, op: impl IntoOp, value: impl IntoLit, ) -> Query
field <op> value with an explicit operator ("<", ">=", "LIKE", …
or an Op). The value is always a literal here — correlations go
through Query::where.
Sourcepub fn where_in<V: IntoLit>(
self,
field: &str,
values: impl IntoIterator<Item = V>,
) -> Query
pub fn where_in<V: IntoLit>( self, field: &str, values: impl IntoIterator<Item = V>, ) -> Query
field IN (values…).
Sourcepub fn sub(self, f: impl FnOnce(ParentRow) -> Query) -> Query
pub fn sub(self, f: impl FnOnce(ParentRow) -> Query) -> Query
Add a correlated child relationship. The closure receives the parent
ParentRow and returns the child query; its where(child, row.col(parent))
calls define the Correlation. (Generic related; the closure picks the
child table.)
Sourcepub fn sub_as(self, alias: &str, f: impl FnOnce(ParentRow) -> Query) -> Query
pub fn sub_as(self, alias: &str, f: impl FnOnce(ParentRow) -> Query) -> Query
Like Query::sub, but names the relationship (sets the child’s alias).
Sourcepub fn count_as(self, alias: &str, f: impl FnOnce(ParentRow) -> Query) -> Query
pub fn count_as(self, alias: &str, f: impl FnOnce(ParentRow) -> Query) -> Query
Add a relationship aggregate — issue { commentCount: count(comments) }
(REDUCE-DESIGN.md §9). Same closure/correlation mechanism as Query::sub
(the child query relates to the parent via row.col(..)), but instead of
materializing the child rows the relationship surfaces a single scalar count(*)
of them, named alias. The builder lowers it to a grouped reduce + a
scalar-projected singular relationship; an empty (childless) parent reads 0.
Sourcepub fn sum_as(
self,
alias: &str,
col: &str,
f: impl FnOnce(ParentRow) -> Query,
) -> Query
pub fn sum_as( self, alias: &str, col: &str, f: impl FnOnce(ParentRow) -> Query, ) -> Query
Add a relationship aggregate surfacing sum(col) of the child rows —
issue { totalEstimate: sum(subtasks.estimate) } (REDUCE-DESIGN.md §9). Like
count_as but the scalar is the Σ of the child column col
(non-NULL values); a childless parent reads NULL (SQL’s sum of no rows).
Sourcepub fn avg_as(
self,
alias: &str,
col: &str,
f: impl FnOnce(ParentRow) -> Query,
) -> Query
pub fn avg_as( self, alias: &str, col: &str, f: impl FnOnce(ParentRow) -> Query, ) -> Query
Add a relationship aggregate surfacing avg(col) of the child rows —
issue { avgEstimate: avg(subtasks.estimate) } (REDUCE-DESIGN.md §9). Like
count_as but the scalar is the mean of the child column col
over its non-NULL values; a childless parent reads NULL.
Sourcepub fn count(self) -> Query
pub fn count(self) -> Query
Aggregate this query’s own rows into a top-level count(*)
(REDUCE-DESIGN.md §8) — the SQL SELECT count(*) FROM table. Without
group_by it is a global count (one [count] row, value
0 even on empty input); with it, one [group…, count] row per group. Distinct
from count_as, which counts a child relationship; this
reshapes the query itself into the aggregate. Combine with
having to filter the post-aggregation rows.
Sourcepub fn avg(self, col: &str) -> Query
pub fn avg(self, col: &str) -> Query
Aggregate this query’s own rows into a top-level avg(col)
(REDUCE-DESIGN.md §8) — the SQL SELECT avg(col) FROM table. Global by default
(one [avg] row, NULL on empty input); with group_by, one
[group…, avg] row per group.
Sourcepub fn having(self, f: impl FnOnce(Cond) -> Cond) -> Query
pub fn having(self, f: impl FnOnce(Cond) -> Cond) -> Query
Filter post-aggregation rows from count, sum,
or avg. The closure receives a fresh Cond over the output:
group columns plus the synthetic count, sum, or avg column. Clauses
combine with AND; nest with Cond::any / Cond::all. For example,
.group_by("status").count().having(|c| c.where_op("count", ">", 3)).
Sourcepub fn having_count(self, alias: &str, op: impl IntoOp, val: i64) -> Query
pub fn having_count(self, alias: &str, op: impl IntoOp, val: i64) -> Query
Filter this parent by a child relationship aggregate’s count —
issue WHERE count(comments) > 10 (PARENT-AGGREGATE-FILTER-DESIGN.md). alias
must name a count_as relationship already attached to this
query; this drops parents whose child count fails <op> <val>, maintained
incrementally (a child add/remove crossing the threshold adds/removes the parent).
The display count_as is untouched — the parent row still shows the real count.
Distinct from having, which filters a top-level
count’s own output rows; this gates a parent by a child
aggregate (lowered to an EXISTS over a HAVING-filtered reduce, design §3).
v1: high-pass predicates only. A childless parent forms no group, so the engine
rejects (at build, BuildError::Unsupported) a
predicate true at count 0 (<= n, < n for n ≥ 1, = 0, >= 0); those need
row-widening. Examples that pass are > n (n ≥ 0), >= n/= n
(n ≥ 1), and != 0. != n for nonzero n is rejected because it is true
at zero. Panics if alias is not a count_as relationship.
Sourcepub fn where_exists(self, f: impl FnOnce(ParentRow) -> Query) -> Query
pub fn where_exists(self, f: impl FnOnce(ParentRow) -> Query) -> Query
WHERE EXISTS (<correlated child>). Same closure/correlation mechanism as
Query::sub, but the child becomes an EXISTS filter rather than a
materialized relationship.
Sourcepub fn where_exists_with(
self,
f: impl FnOnce(ParentRow) -> Query,
opts: ExistsOpts,
) -> Query
pub fn where_exists_with( self, f: impl FnOnce(ParentRow) -> Query, opts: ExistsOpts, ) -> Query
Query::where_exists with ExistsOpts — e.g. ExistsOpts { scalar: true }
to request a build-time scalar fold (SCALAR-SUBQUERY-DESIGN.md).
Sourcepub fn where_not_exists(self, f: impl FnOnce(ParentRow) -> Query) -> Query
pub fn where_not_exists(self, f: impl FnOnce(ParentRow) -> Query) -> Query
WHERE NOT EXISTS (<correlated child>).
Sourcepub fn where_not_exists_with(
self,
f: impl FnOnce(ParentRow) -> Query,
opts: ExistsOpts,
) -> Query
pub fn where_not_exists_with( self, f: impl FnOnce(ParentRow) -> Query, opts: ExistsOpts, ) -> Query
Sourcepub fn where_exists_no_sync(self, f: impl FnOnce(ParentRow) -> Query) -> Query
pub fn where_exists_no_sync(self, f: impl FnOnce(ParentRow) -> Query) -> Query
WHERE EXISTS (<correlated child>) as a server-only, non-syncing gate
(exists_noSync, EXISTS-NOSYNC-DESIGN.md). Stamps the subquery system: Permissions, which (a) gates parent visibility server-side exactly like
where_exists, but (b) marks the gate so the normalized
serializer prunes its witnesses from the footprint — the permission table’s rows are
never synced to the client, and the client never re-evaluates the gate. Build this on
the server’s query; the client holds its own un-gated query.
Sourcepub fn where_not_exists_no_sync(
self,
f: impl FnOnce(ParentRow) -> Query,
) -> Query
pub fn where_not_exists_no_sync( self, f: impl FnOnce(ParentRow) -> Query, ) -> Query
WHERE NOT EXISTS (<correlated child>) as a server-only, non-syncing gate — the
NOT EXISTS form of where_exists_no_sync (a deny-style
permission rule). A NOT EXISTS gate passes on zero children, so it carries no
witnesses to sync; the system: Permissions stamp is recorded for symmetry and to keep
the gate off the client.
Sourcepub fn where_any(self, f: impl FnOnce(Cond) -> Cond) -> Query
pub fn where_any(self, f: impl FnOnce(Cond) -> Cond) -> Query
WHERE (c1 OR c2 OR …) — an OR group. The closure receives a fresh
Cond to which it adds clauses (where/where_op/where_in/
where_exists, or nested any/all). The group AND-combines with any
other top-level wheres, exactly like the simple forms.
Sourcepub fn where_all(self, f: impl FnOnce(Cond) -> Cond) -> Query
pub fn where_all(self, f: impl FnOnce(Cond) -> Cond) -> Query
WHERE (c1 AND c2 AND …) — an explicit AND group. Redundant at the top
level (chained wheres already AND), but the way to express a grouped
AND nested inside a Query::where_any, e.g. (a AND b) OR c.
Sourcepub fn one(self) -> Query
pub fn one(self) -> Query
Return a single row: the result is presented as one object (or
null/absent) instead of an array. Records the intent on the AST
(Ast::one) and caps the query to one row (limit = 1). The engine stays
plural internally; the single-element unwrap happens at the result boundary.
Used on a sub/sub_as child query, it makes that relationship singular.
Sourcepub fn order_by(self, field: &str, dir: impl IntoDir) -> Query
pub fn order_by(self, field: &str, dir: impl IntoDir) -> Query
Append an ordering term ("asc"/"desc" or a Dir). Chain for a
compound sort.
Sourcepub fn start_at(self, col: &str, val: impl IntoLit) -> Query
pub fn start_at(self, col: &str, val: impl IntoLit) -> Query
Page from col = val, inclusive of that row.
Sourcepub fn start_after(self, col: &str, val: impl IntoLit) -> Query
pub fn start_after(self, col: &str, val: impl IntoLit) -> Query
Page from col = val, exclusive of that row.