Skip to main content

Select

Struct Select 

Source
pub struct Select<D, Scope, Sel, Outer = Nil> { /* private fields */ }
Expand description

A SELECT. Outer is the scope this query was built againstNil for a query of its own, and the outer query’s scope for one started by .correlated(..), which is what lets EXISTS report the outer tables it references. Defaulted, so a query that isn’t a subquery never spells it.

Implementations§

Source§

impl<D, Scope, Sel> Select<D, Scope, Sel>

Source

pub fn erase<Idx>(self) -> DynSelect<D, Sel::Output>
where Sel: Selection<Scope, Idx>,

Erases Scope. Sel::items() runs here, while Scope/Idx are still known; the resulting Vec<SelectItem> and the plain-Rust Output type are all DynSelect needs afterwards.

Source§

impl<D, Scope, Sel> Select<D, Scope, Sel>

Source

pub fn prepare<Params, Idx>( &self, _dialect: D, ) -> Prepared<D, Params, Sel::Output>
where D: Dialect, Sel: Selection<Scope, Idx>,

Renders this query once, leaving its Value::Placeholder slots unresolved. Output is captured here, as .erase() does for DynSelect, so the execution layer can decode rows without Sel (and therefore Scope) still being around.

Source

pub fn prepare_count<Params, Idx>( &self, _dialect: D, ) -> Prepared<D, Params, Total>
where D: Dialect, Sel: Selection<Scope, Idx>,

The same query prepared as its own total — count_sql with the placeholders still unresolved, so a paginated endpoint reuses one rendering for the page and one for the count. Total rather than i64: what a statement produces is what decides how it is run, and a total is a number, not a row.

Source§

impl<D: Dialect, Scope, Sel> Select<D, Scope, Sel>

Source

pub fn union<ScopeB, SelB, IdxA, IdxB>( &self, other: &Select<D, ScopeB, SelB>, ) -> SetOp<D, Sel::Output>
where Sel: Selection<Scope, IdxA>, SelB: Selection<ScopeB, IdxB>, SelB::Output: SameShape<Sel::Output>,

Starts a UNION chain — see SetOp’s doc comment for why the two branches only need matching Selection::Output, not matching Scope.

Source

pub fn union_all<ScopeB, SelB, IdxA, IdxB>( &self, other: &Select<D, ScopeB, SelB>, ) -> SetOp<D, Sel::Output>
where Sel: Selection<Scope, IdxA>, SelB: Selection<ScopeB, IdxB>, SelB::Output: SameShape<Sel::Output>,

Source

pub fn intersect<ScopeB, SelB, IdxA, IdxB>( &self, other: &Select<D, ScopeB, SelB>, ) -> SetOp<D, Sel::Output>
where Sel: Selection<Scope, IdxA>, SelB: Selection<ScopeB, IdxB>, SelB::Output: SameShape<Sel::Output>,

Source

pub fn except<ScopeB, SelB, IdxA, IdxB>( &self, other: &Select<D, ScopeB, SelB>, ) -> SetOp<D, Sel::Output>
where Sel: Selection<Scope, IdxA>, SelB: Selection<ScopeB, IdxB>, SelB::Output: SameShape<Sel::Output>,

Source§

impl<D, Scope, Sel, Outer> Select<D, Scope, Sel, Outer>

Source

pub fn reselect<NewSel>( self, selection: NewSel, ) -> Select<D, Scope, NewSel, Outer>

Swaps the selection list, keeping every clause. With Clone, this is how one built-up query serves both a count and a page.

Source

pub fn filter<C: Condition<D, Scope, Idxs>, Idxs>(self, cond: C) -> Self

AND-folded, and callable any number of times — conditionally, in a loop, from a helper — without changing Self’s type, so the most common kind of dynamic query needs no escape hatch.

Source

pub fn filter_all( self, conds: impl IntoIterator<Item = Predicate<D, Scope>>, ) -> Self

AND-folds a runtime-length collection of already-discharged conditions — the shape a search form has, where the conditions come from different tables and so can’t share one Expr type.

Source

pub fn order_by<K: SortBy<Scope, Idxs>, Idxs>(self, key: K) -> Self

Source

pub fn order_by_all( self, keys: impl IntoIterator<Item = SortKey<Scope>>, ) -> Self

Appends a runtime-length collection of already-discharged sort keys — the shape a ?sort= parameter has, where the keys name different tables and so can’t share one OrderKey type.

Source

pub fn distinct(self) -> Self

SELECT DISTINCT: one row per distinct selected tuple. The natural answer to a one-to-many join that repeats its left side, and unlike a GROUP BY of the whole selection it doesn’t have to be restated when the selection changes. Idempotent — a query is distinct or it isn’t.

Known limitation: Postgres requires a SELECT DISTINCT’s sort keys to be in its selection, and nothing here relates the two — the same gap GROUP BY has. Sorting a distinct query by a column it doesn’t select renders SQL the database rejects, and count_sql won’t show it, since a total drops the ORDER BY. Relating them would mean carrying “is distinct” in Select’s type and taking sort keys by identity (SetOp::order_by_column’s shape) — a type parameter through every builder signature for one clause.

Source

pub fn group_by<K: GroupBy<Scope, Idxs>, Idxs>(self, key: K) -> Self

Appends one grouping key; callable multiple times like .filter() (each call adds a column to the GROUP BY list, it doesn’t replace it), for the same “dynamic composition without a type change” reason.

Source

pub fn group_by_all( self, keys: impl IntoIterator<Item = Grouping<Scope>>, ) -> Self

The same for a runtime-length collection of discharged grouping keys, as order_by_all is to order_by.

Source

pub fn having<C: Condition<D, Scope, Idxs>, Idxs>(self, cond: C) -> Self

A WHERE-shaped filter applied after grouping (aggregate conditions) — AND-folded across calls exactly like .filter().

Source

pub fn having_all( self, conds: impl IntoIterator<Item = Predicate<D, Scope>>, ) -> Self

The same for a runtime-length collection of discharged conditions, as filter_all is to filter.

Source

pub fn limit(self, n: impl IntoRowCount) -> Self

Source

pub fn offset(self, n: impl IntoRowCount) -> Self

Source

pub fn inner_join<S: JoinSource<D>, C, Idxs>( self, source: S, on: C, ) -> Select<D, Cons<TableSlot<S::Table, NotNull>, Scope>, Sel, Outer>
where C: Condition<D, Cons<TableSlot<S::Table, NotNull>, Scope>, Idxs>,

The joined table is in scope for the ON condition, and so is everything already joined — the scope the condition is discharged against is the one the join produces, not the one it started from.

Source

pub fn left_join<S: JoinSource<D>, C, Idxs>( self, source: S, on: C, ) -> Select<D, Cons<TableSlot<S::Table, MaybeNull>, Scope>, Sel, Outer>
where C: Condition<D, Cons<TableSlot<S::Table, MaybeNull>, Scope>, Idxs>,

Source

pub fn right_join<S: JoinSource<D>, C, Idxs>( self, source: S, on: C, ) -> Select<D, Cons<TableSlot<S::Table, NotNull>, Scope::Output>, Sel, Outer>
where D: SupportsRightJoin, Scope: MapNullable, C: Condition<D, Cons<TableSlot<S::Table, NotNull>, Scope::Output>, Idxs>,

RIGHT JOIN retroactively flips every already-joined table to nullable (MapNullable) before adding the new, guaranteed-present table, mirroring Drizzle’s AppendToNullabilityMap rule.

Source

pub fn full_join<S: JoinSource<D>, C, Idxs>( self, source: S, on: C, ) -> Select<D, Cons<TableSlot<S::Table, MaybeNull>, Scope::Output>, Sel, Outer>
where D: SupportsFullOuterJoin, Scope: MapNullable, C: Condition<D, Cons<TableSlot<S::Table, MaybeNull>, Scope::Output>, Idxs>,

Source§

impl<D: Dialect, Scope, Sel> Select<D, Scope, Sel>

The terminal methods, and so only for a query of its own: a subquery (Outer != Nil) references its outer query’s tables, and rendering one on its own would name tables that aren’t in its FROM. It reaches SQL through exists/not_exists instead.

Source

pub fn to_sql<Idx>(&self, _dialect: D) -> (String, Vec<Value>)
where Sel: Selection<Scope, Idx>,

The terminal step, and the only point each selected column’s scope-membership is checked — proven as a side effect of Sel: Selection<Scope, Idx> type-checking at all.

The dialect is an argument rather than a turbofish, so a query that is rendered instead of executed says which SQL it wants in the one place that decides — and everything before it infers, the way a table or a column does.

Source

pub fn count_sql<Idx>(&self, _dialect: D) -> (String, Vec<Value>)
where Sel: Selection<Scope, Idx>,

How many rows this query would return, ignoring its ORDER BY/LIMIT/OFFSET — a total is about what matches, not about the page being shown. reselect(count()) keeps them, which is what makes it the wrong tool for a paginated total.

A grouped query counts its groups, since that is what a page of it would show, so the body becomes a subquery rather than having its GROUP BY dropped or kept.

Source§

impl<D, Scope, Sel, Outer> Select<D, Scope, Sel, Outer>

Source

pub fn correlated<S: JoinSource<D>, InnerSel>( &self, source: S, selection: InnerSel, ) -> Select<D, Cons<TableSlot<S::Table, NotNull>, Scope>, InnerSel, Scope>

Starts a correlated subquery: a fresh SELECT whose scope is Cons<TableSlot<T, NotNull>, Scope> — the new table, prepended onto this (outer) query’s entire scope. Because Find/Superset walk the whole flat cons-list regardless of where it came from, the subquery’s .filter() can reference both its own new table’s columns and any outer column already in Scope, with no special casing: growing the scope works the same whether the new table came from a join or from a subquery’s FROM.

The result is an ordinary Select — every clause it takes is the one Select already has — carrying this query’s scope as its Outer, which is what exists reports.

Source§

impl<D: Dialect, Scope, Sel, Outer: ScopeTables> Select<D, Scope, Sel, Outer>

Source

pub fn exists<Idx>(&self) -> Exists<D, Outer::Tables>
where Sel: Selection<Scope, Idx>,

EXISTS (<this query>), tagged with the outer tables it references so it can only be filtered onto a query that has them in scope. Its own column references were already checked against Scope when it was built. On a query that isn’t a subquery, Outer is Nil and this is an uncorrelated EXISTS.

Source

pub fn not_exists<Idx>(&self) -> Exists<D, Outer::Tables>
where Sel: Selection<Scope, Idx>,

Trait Implementations§

Source§

impl<D, Scope, Sel: Clone, Outer> Clone for Select<D, Scope, Sel, Outer>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

§

impl<D, Scope, Sel, Outer> Freeze for Select<D, Scope, Sel, Outer>

§

impl<D, Scope, Sel, Outer> RefUnwindSafe for Select<D, Scope, Sel, Outer>

§

impl<D, Scope, Sel, Outer> Send for Select<D, Scope, Sel, Outer>

§

impl<D, Scope, Sel, Outer> Sync for Select<D, Scope, Sel, Outer>

§

impl<D, Scope, Sel, Outer> Unpin for Select<D, Scope, Sel, Outer>

§

impl<D, Scope, Sel, Outer> UnsafeUnpin for Select<D, Scope, Sel, Outer>

§

impl<D, Scope, Sel, Outer> UnwindSafe for Select<D, Scope, Sel, Outer>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<S> Superset<Nil, Nil> for S

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WrapNullable<NotNull> for T