Struct diesel::query_builder::BoxedSelectStatement
source · pub struct BoxedSelectStatement<'a, ST, QS, DB, GB = ()> {
pub select: Box<dyn QueryFragment<DB> + Send + 'a>,
pub from: QS,
pub distinct: Box<dyn QueryFragment<DB> + Send + 'a>,
pub where_clause: BoxedWhereClause<'a, DB>,
pub order: Option<Box<dyn QueryFragment<DB> + Send + 'a>>,
pub limit_offset: BoxedLimitOffsetClause<'a, DB>,
pub group_by: Box<dyn QueryFragment<DB> + Send + 'a>,
pub having: Box<dyn QueryFragment<DB> + Send + 'a>,
/* private fields */
}
Expand description
This type represents a boxed select query
Using this type directly is only meaningful for custom backends
that need to provide a custom QueryFragment
implementation
Fields§
§select: Box<dyn QueryFragment<DB> + Send + 'a>
The select clause of the query
from: QS
The from clause of the query
distinct: Box<dyn QueryFragment<DB> + Send + 'a>
The distinct clause of the query
where_clause: BoxedWhereClause<'a, DB>
The where clause of the query
order: Option<Box<dyn QueryFragment<DB> + Send + 'a>>
The order clause of the query
limit_offset: BoxedLimitOffsetClause<'a, DB>
The combined limit/offset clause of the query
group_by: Box<dyn QueryFragment<DB> + Send + 'a>
The group by clause of the query
having: Box<dyn QueryFragment<DB> + Send + 'a>
The having clause of the query
Trait Implementations§
source§impl<'a, ST, QS, DB, GB> AsInExpression<ST> for BoxedSelectStatement<'a, ST, QS, DB, GB>where
ST: SqlType + TypedExpressionType,
Subselect<BoxedSelectStatement<'a, ST, QS, DB, GB>, ST>: Expression<SqlType = ST>,
impl<'a, ST, QS, DB, GB> AsInExpression<ST> for BoxedSelectStatement<'a, ST, QS, DB, GB>where ST: SqlType + TypedExpressionType, Subselect<BoxedSelectStatement<'a, ST, QS, DB, GB>, ST>: Expression<SqlType = ST>,
§type InExpression = Subselect<BoxedSelectStatement<'a, ST, QS, DB, GB>, ST>
type InExpression = Subselect<BoxedSelectStatement<'a, ST, QS, DB, GB>, ST>
Type of the expression returned by AsInExpression::as_in_expression
source§fn as_in_expression(self) -> Self::InExpression
fn as_in_expression(self) -> Self::InExpression
Construct the diesel query dsl representation of
the
IN (values)
clause for the given typesource§impl<'a, ST, QS, DB, GB> CombineDsl for BoxedSelectStatement<'a, ST, QS, DB, GB>where
Self: Query,
impl<'a, ST, QS, DB, GB> CombineDsl for BoxedSelectStatement<'a, ST, QS, DB, GB>where Self: Query,
§type Query = BoxedSelectStatement<'a, ST, QS, DB, GB>
type Query = BoxedSelectStatement<'a, ST, QS, DB, GB>
What kind of query does this type represent?
source§fn union<Rhs>(self, rhs: Rhs) -> Union<Self, Rhs>where
Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
fn union<Rhs>(self, rhs: Rhs) -> Union<Self, Rhs>where Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
Combine two queries using a SQL
UNION
Read moresource§fn union_all<Rhs>(self, rhs: Rhs) -> UnionAll<Self, Rhs>where
Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
fn union_all<Rhs>(self, rhs: Rhs) -> UnionAll<Self, Rhs>where Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
Combine two queries using a SQL
UNION ALL
source§fn intersect<Rhs>(self, rhs: Rhs) -> Intersect<Self, Rhs>where
Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
fn intersect<Rhs>(self, rhs: Rhs) -> Intersect<Self, Rhs>where Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
Combine two queries using a SQL
INTERSECT
source§fn intersect_all<Rhs>(self, rhs: Rhs) -> IntersectAll<Self, Rhs>where
Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
fn intersect_all<Rhs>(self, rhs: Rhs) -> IntersectAll<Self, Rhs>where Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
Combine two queries using a SQL
INTERSECT ALL
source§impl<'a, ST, QS, DB, GB> DistinctDsl for BoxedSelectStatement<'a, ST, QS, DB, GB>where
DB: Backend,
DistinctClause: QueryFragment<DB>,
impl<'a, ST, QS, DB, GB> DistinctDsl for BoxedSelectStatement<'a, ST, QS, DB, GB>where DB: Backend, DistinctClause: QueryFragment<DB>,
source§impl<'a, ST, DB, Predicate, GB> FilterDsl<Predicate> for BoxedSelectStatement<'a, ST, NoFromClause, DB, GB>where
BoxedWhereClause<'a, DB>: WhereAnd<Predicate, Output = BoxedWhereClause<'a, DB>>,
Predicate: AppearsOnTable<NoFromClause> + NonAggregate,
Predicate::SqlType: BoolOrNullableBool,
impl<'a, ST, DB, Predicate, GB> FilterDsl<Predicate> for BoxedSelectStatement<'a, ST, NoFromClause, DB, GB>where BoxedWhereClause<'a, DB>: WhereAnd<Predicate, Output = BoxedWhereClause<'a, DB>>, Predicate: AppearsOnTable<NoFromClause> + NonAggregate, Predicate::SqlType: BoolOrNullableBool,
§type Output = BoxedSelectStatement<'a, ST, NoFromClause, DB, GB>
type Output = BoxedSelectStatement<'a, ST, NoFromClause, DB, GB>
The type returned by
.filter
.source§impl<'a, ST, QS, DB, GB, Predicate> HavingDsl<Predicate> for BoxedSelectStatement<'a, ST, QS, DB, GB>where
DB: Backend,
GB: Expression,
HavingClause<Predicate>: QueryFragment<DB> + Send + 'a,
Predicate: AppearsOnTable<QS>,
Predicate::SqlType: BoolOrNullableBool,
impl<'a, ST, QS, DB, GB, Predicate> HavingDsl<Predicate> for BoxedSelectStatement<'a, ST, QS, DB, GB>where DB: Backend, GB: Expression, HavingClause<Predicate>: QueryFragment<DB> + Send + 'a, Predicate: AppearsOnTable<QS>, Predicate::SqlType: BoolOrNullableBool,
source§impl<'a, 'b, ST, QS, DB, T, GB> Insertable<T> for &'b BoxedSelectStatement<'a, ST, QS, DB, GB>where
T: Table,
Self: Query,
<T::AllColumns as ValidGrouping<()>>::IsAggregate: MixedAggregates<No, Output = No>,
impl<'a, 'b, ST, QS, DB, T, GB> Insertable<T> for &'b BoxedSelectStatement<'a, ST, QS, DB, GB>where T: Table, Self: Query, <T::AllColumns as ValidGrouping<()>>::IsAggregate: MixedAggregates<No, Output = No>,
§type Values = InsertFromSelect<&'b BoxedSelectStatement<'a, ST, QS, DB, GB>, <T as Table>::AllColumns>
type Values = InsertFromSelect<&'b BoxedSelectStatement<'a, ST, QS, DB, GB>, <T as Table>::AllColumns>
The
VALUES
clause to insert these records Read moresource§fn insert_into(self, table: T) -> InsertStatement<T, Self::Values>where
T: Table,
Self: Sized,
fn insert_into(self, table: T) -> InsertStatement<T, Self::Values>where T: Table, Self: Sized,
Insert
self
into a given table. Read moresource§impl<'a, ST, QS, DB, T, GB> Insertable<T> for BoxedSelectStatement<'a, ST, QS, DB, GB>where
T: Table,
Self: Query,
<T::AllColumns as ValidGrouping<()>>::IsAggregate: MixedAggregates<No, Output = No>,
impl<'a, ST, QS, DB, T, GB> Insertable<T> for BoxedSelectStatement<'a, ST, QS, DB, GB>where T: Table, Self: Query, <T::AllColumns as ValidGrouping<()>>::IsAggregate: MixedAggregates<No, Output = No>,
§type Values = InsertFromSelect<BoxedSelectStatement<'a, ST, QS, DB, GB>, <T as Table>::AllColumns>
type Values = InsertFromSelect<BoxedSelectStatement<'a, ST, QS, DB, GB>, <T as Table>::AllColumns>
The
VALUES
clause to insert these records Read moresource§fn insert_into(self, table: T) -> InsertStatement<T, Self::Values>where
T: Table,
Self: Sized,
fn insert_into(self, table: T) -> InsertStatement<T, Self::Values>where T: Table, Self: Sized,
Insert
self
into a given table. Read moresource§impl<'a, ST, QS, DB, GB> LimitDsl for BoxedSelectStatement<'a, ST, QS, DB, GB>where
DB: Backend,
LimitClause<AsExprOf<i64, BigInt>>: QueryFragment<DB>,
impl<'a, ST, QS, DB, GB> LimitDsl for BoxedSelectStatement<'a, ST, QS, DB, GB>where DB: Backend, LimitClause<AsExprOf<i64, BigInt>>: QueryFragment<DB>,
source§impl<'a, ST, QS, DB, GB> OffsetDsl for BoxedSelectStatement<'a, ST, QS, DB, GB>where
DB: Backend,
OffsetClause<AsExprOf<i64, BigInt>>: QueryFragment<DB>,
impl<'a, ST, QS, DB, GB> OffsetDsl for BoxedSelectStatement<'a, ST, QS, DB, GB>where DB: Backend, OffsetClause<AsExprOf<i64, BigInt>>: QueryFragment<DB>,
source§impl<'a, ST, DB, Predicate, GB> OrFilterDsl<Predicate> for BoxedSelectStatement<'a, ST, NoFromClause, DB, GB>where
BoxedWhereClause<'a, DB>: WhereOr<Predicate, Output = BoxedWhereClause<'a, DB>>,
Predicate: AppearsOnTable<NoFromClause> + NonAggregate,
Predicate::SqlType: BoolOrNullableBool,
impl<'a, ST, DB, Predicate, GB> OrFilterDsl<Predicate> for BoxedSelectStatement<'a, ST, NoFromClause, DB, GB>where BoxedWhereClause<'a, DB>: WhereOr<Predicate, Output = BoxedWhereClause<'a, DB>>, Predicate: AppearsOnTable<NoFromClause> + NonAggregate, Predicate::SqlType: BoolOrNullableBool,
§type Output = BoxedSelectStatement<'a, ST, NoFromClause, DB, GB>
type Output = BoxedSelectStatement<'a, ST, NoFromClause, DB, GB>
The type returned by
.filter
.source§impl<'a, ST, QS, DB, GB> Query for BoxedSelectStatement<'a, ST, QS, DB, GB>where
DB: Backend,
impl<'a, ST, QS, DB, GB> Query for BoxedSelectStatement<'a, ST, QS, DB, GB>where DB: Backend,
source§impl<'a, ST, QS, DB, GB> QueryDsl for BoxedSelectStatement<'a, ST, QS, DB, GB>
impl<'a, ST, QS, DB, GB> QueryDsl for BoxedSelectStatement<'a, ST, QS, DB, GB>
source§fn distinct_on<Expr>(self, expr: Expr) -> DistinctOn<Self, Expr>where
Self: DistinctOnDsl<Expr>,
fn distinct_on<Expr>(self, expr: Expr) -> DistinctOn<Self, Expr>where Self: DistinctOnDsl<Expr>,
Adds the
DISTINCT ON
clause to a query. Read moresource§fn select<Selection>(self, selection: Selection) -> Select<Self, Selection>where
Selection: Expression,
Self: SelectDsl<Selection>,
fn select<Selection>(self, selection: Selection) -> Select<Self, Selection>where Selection: Expression, Self: SelectDsl<Selection>,
Adds a
SELECT
clause to the query. Read moresource§fn inner_join<Rhs>(self, rhs: Rhs) -> InnerJoin<Self, Rhs>where
Self: JoinWithImplicitOnClause<Rhs, Inner>,
fn inner_join<Rhs>(self, rhs: Rhs) -> InnerJoin<Self, Rhs>where Self: JoinWithImplicitOnClause<Rhs, Inner>,
Join two tables using a SQL
INNER JOIN
. Read moresource§fn left_outer_join<Rhs>(self, rhs: Rhs) -> LeftJoin<Self, Rhs>where
Self: JoinWithImplicitOnClause<Rhs, LeftOuter>,
fn left_outer_join<Rhs>(self, rhs: Rhs) -> LeftJoin<Self, Rhs>where Self: JoinWithImplicitOnClause<Rhs, LeftOuter>,
Join two tables using a SQL
LEFT OUTER JOIN
. Read moresource§fn left_join<Rhs>(self, rhs: Rhs) -> LeftJoin<Self, Rhs>where
Self: JoinWithImplicitOnClause<Rhs, LeftOuter>,
fn left_join<Rhs>(self, rhs: Rhs) -> LeftJoin<Self, Rhs>where Self: JoinWithImplicitOnClause<Rhs, LeftOuter>,
Alias for
left_outer_join
.source§fn filter<Predicate>(self, predicate: Predicate) -> Filter<Self, Predicate>where
Self: FilterDsl<Predicate>,
fn filter<Predicate>(self, predicate: Predicate) -> Filter<Self, Predicate>where Self: FilterDsl<Predicate>,
Adds to the
WHERE
clause of a query. Read moresource§fn or_filter<Predicate>(self, predicate: Predicate) -> OrFilter<Self, Predicate>where
Self: OrFilterDsl<Predicate>,
fn or_filter<Predicate>(self, predicate: Predicate) -> OrFilter<Self, Predicate>where Self: OrFilterDsl<Predicate>,
source§fn find<PK>(self, id: PK) -> Find<Self, PK>where
Self: FindDsl<PK>,
fn find<PK>(self, id: PK) -> Find<Self, PK>where Self: FindDsl<PK>,
Attempts to find a single record from the given table by primary key. Read more
source§fn order<Expr>(self, expr: Expr) -> Order<Self, Expr>where
Expr: Expression,
Self: OrderDsl<Expr>,
fn order<Expr>(self, expr: Expr) -> Order<Self, Expr>where Expr: Expression, Self: OrderDsl<Expr>,
Sets the order clause of a query. Read more
source§fn order_by<Expr>(self, expr: Expr) -> Order<Self, Expr>where
Expr: Expression,
Self: OrderDsl<Expr>,
fn order_by<Expr>(self, expr: Expr) -> Order<Self, Expr>where Expr: Expression, Self: OrderDsl<Expr>,
Alias for
order
source§fn then_order_by<Order>(self, order: Order) -> ThenOrderBy<Self, Order>where
Self: ThenOrderDsl<Order>,
fn then_order_by<Order>(self, order: Order) -> ThenOrderBy<Self, Order>where Self: ThenOrderDsl<Order>,
Appends to the
ORDER BY
clause of this SQL query. Read moresource§fn group_by<GB>(self, group_by: GB) -> GroupBy<Self, GB>where
GB: Expression,
Self: GroupByDsl<GB>,
fn group_by<GB>(self, group_by: GB) -> GroupBy<Self, GB>where GB: Expression, Self: GroupByDsl<GB>,
Sets the
group by
clause of a query. Read moresource§impl<'a, ST, QS, DB, GB> QueryFragment<DB, AnsiSqlSelectStatement> for BoxedSelectStatement<'a, ST, QS, DB, GB>where
DB: Backend<SelectStatementSyntax = AnsiSqlSelectStatement> + DieselReserveSpecialization,
QS: QueryFragment<DB>,
BoxedLimitOffsetClause<'a, DB>: QueryFragment<DB>,
impl<'a, ST, QS, DB, GB> QueryFragment<DB, AnsiSqlSelectStatement> for BoxedSelectStatement<'a, ST, QS, DB, GB>where DB: Backend<SelectStatementSyntax = AnsiSqlSelectStatement> + DieselReserveSpecialization, QS: QueryFragment<DB>, BoxedLimitOffsetClause<'a, DB>: QueryFragment<DB>,
source§fn walk_ast<'b>(&'b self, out: AstPass<'_, 'b, DB>) -> QueryResult<()>
fn walk_ast<'b>(&'b self, out: AstPass<'_, 'b, DB>) -> QueryResult<()>
Walk over this
QueryFragment
for all passes. Read moresource§fn to_sql(&self, out: &mut DB::QueryBuilder, backend: &DB) -> QueryResult<()>
fn to_sql(&self, out: &mut DB::QueryBuilder, backend: &DB) -> QueryResult<()>
Converts this
QueryFragment
to its SQL representation. Read moresource§fn collect_binds<'b>(
&'b self,
out: &mut <DB as HasBindCollector<'b>>::BindCollector,
metadata_lookup: &mut DB::MetadataLookup,
backend: &'b DB
) -> QueryResult<()>
fn collect_binds<'b>( &'b self, out: &mut <DB as HasBindCollector<'b>>::BindCollector, metadata_lookup: &mut DB::MetadataLookup, backend: &'b DB ) -> QueryResult<()>
Serializes all bind parameters in this query. Read more
source§fn is_safe_to_cache_prepared(&self, backend: &DB) -> QueryResult<bool>
fn is_safe_to_cache_prepared(&self, backend: &DB) -> QueryResult<bool>
Is this query safe to store in the prepared statement cache? Read more
source§impl<'a, ST, QS, DB, GB> QueryId for BoxedSelectStatement<'a, ST, QS, DB, GB>
impl<'a, ST, QS, DB, GB> QueryId for BoxedSelectStatement<'a, ST, QS, DB, GB>
source§const HAS_STATIC_QUERY_ID: bool = false
const HAS_STATIC_QUERY_ID: bool = false
Can the SQL generated by
Self
be uniquely identified by its type? Read moresource§impl<'a, ST, QS, DB, Conn, GB> RunQueryDsl<Conn> for BoxedSelectStatement<'a, ST, QS, DB, GB>
impl<'a, ST, QS, DB, Conn, GB> RunQueryDsl<Conn> for BoxedSelectStatement<'a, ST, QS, DB, GB>
source§fn load<'query, U>(self, conn: &mut Conn) -> QueryResult<Vec<U>>where
Self: LoadQuery<'query, Conn, U>,
fn load<'query, U>(self, conn: &mut Conn) -> QueryResult<Vec<U>>where Self: LoadQuery<'query, Conn, U>,
source§fn load_iter<'conn, 'query: 'conn, U, B>(
self,
conn: &'conn mut Conn
) -> QueryResult<LoadIter<'conn, 'query, Self, Conn, U, B>>where
U: 'conn,
Self: LoadQuery<'query, Conn, U, B> + 'conn,
fn load_iter<'conn, 'query: 'conn, U, B>( self, conn: &'conn mut Conn ) -> QueryResult<LoadIter<'conn, 'query, Self, Conn, U, B>>where U: 'conn, Self: LoadQuery<'query, Conn, U, B> + 'conn,
source§fn get_result<'query, U>(self, conn: &mut Conn) -> QueryResult<U>where
Self: LoadQuery<'query, Conn, U>,
fn get_result<'query, U>(self, conn: &mut Conn) -> QueryResult<U>where Self: LoadQuery<'query, Conn, U>,
Runs the command, and returns the affected row. Read more
source§fn get_results<'query, U>(self, conn: &mut Conn) -> QueryResult<Vec<U>>where
Self: LoadQuery<'query, Conn, U>,
fn get_results<'query, U>(self, conn: &mut Conn) -> QueryResult<Vec<U>>where Self: LoadQuery<'query, Conn, U>,
Runs the command, returning an
Vec
with the affected rows. Read moresource§impl<'a, ST, DB, Selection, GB> SelectDsl<Selection> for BoxedSelectStatement<'a, ST, NoFromClause, DB, GB>where
DB: Backend,
Selection: SelectableExpression<NoFromClause> + QueryFragment<DB> + ValidGrouping<GB> + Send + 'a,
impl<'a, ST, DB, Selection, GB> SelectDsl<Selection> for BoxedSelectStatement<'a, ST, NoFromClause, DB, GB>where DB: Backend, Selection: SelectableExpression<NoFromClause> + QueryFragment<DB> + ValidGrouping<GB> + Send + 'a,
§type Output = BoxedSelectStatement<'a, <Selection as Expression>::SqlType, NoFromClause, DB, GB>
type Output = BoxedSelectStatement<'a, <Selection as Expression>::SqlType, NoFromClause, DB, GB>
The type returned by
.select
source§impl<'a, ST, QS, DB, GB> SelectNullableDsl for BoxedSelectStatement<'a, ST, QS, DB, GB>where
ST: IntoNullable,
impl<'a, ST, QS, DB, GB> SelectNullableDsl for BoxedSelectStatement<'a, ST, QS, DB, GB>where ST: IntoNullable,
§type Output = BoxedSelectStatement<'a, <ST as IntoNullable>::Nullable, QS, DB, ()>
type Output = BoxedSelectStatement<'a, <ST as IntoNullable>::Nullable, QS, DB, ()>
The return type of
nullable
source§impl<'a, ST, QS, DB, GB> SelectQuery for BoxedSelectStatement<'a, ST, QS, DB, GB>where
DB: Backend,
impl<'a, ST, QS, DB, GB> SelectQuery for BoxedSelectStatement<'a, ST, QS, DB, GB>where DB: Backend,
Auto Trait Implementations§
impl<'a, ST, QS, DB, GB = ()> !RefUnwindSafe for BoxedSelectStatement<'a, ST, QS, DB, GB>
impl<'a, ST, QS, DB, GB> Send for BoxedSelectStatement<'a, ST, QS, DB, GB>where GB: Send, QS: Send, ST: Send,
impl<'a, ST, QS, DB, GB = ()> !Sync for BoxedSelectStatement<'a, ST, QS, DB, GB>
impl<'a, ST, QS, DB, GB> Unpin for BoxedSelectStatement<'a, ST, QS, DB, GB>where GB: Unpin, QS: Unpin, ST: Unpin,
impl<'a, ST, QS, DB, GB = ()> !UnwindSafe for BoxedSelectStatement<'a, ST, QS, DB, GB>
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
source§impl<Conn, DB, T> ExecuteDsl<Conn, DB> for Twhere
Conn: Connection<Backend = DB>,
DB: Backend,
T: QueryFragment<DB, NotSpecialized> + QueryId,
impl<Conn, DB, T> ExecuteDsl<Conn, DB> for Twhere Conn: Connection<Backend = DB>, DB: Backend, T: QueryFragment<DB, NotSpecialized> + QueryId,
source§impl<T> IntoSql for T
impl<T> IntoSql for T
source§fn into_sql<T>(self) -> AsExprOf<Self, T>where
Self: AsExpression<T> + Sized,
T: SqlType + TypedExpressionType,
fn into_sql<T>(self) -> AsExprOf<Self, T>where Self: AsExpression<T> + Sized, T: SqlType + TypedExpressionType,
Convert
self
to an expression for Diesel’s query builder. Read moresource§fn as_sql<'a, T>(&'a self) -> AsExprOf<&'a Self, T>where
&'a Self: AsExpression<T>,
T: SqlType + TypedExpressionType,
fn as_sql<'a, T>(&'a self) -> AsExprOf<&'a Self, T>where &'a Self: AsExpression<T>, T: SqlType + TypedExpressionType,
Convert
&self
to an expression for Diesel’s query builder. Read moresource§impl<T> SingleValueDsl for Twhere
T: SelectQuery + LimitDsl,
<T as SelectQuery>::SqlType: IntoNullable,
impl<T> SingleValueDsl for Twhere T: SelectQuery + LimitDsl, <T as SelectQuery>::SqlType: IntoNullable,
§type Output = Grouped<Subselect<<T as LimitDsl>::Output, <<T as SelectQuery>::SqlType as IntoNullable>::Nullable>>
type Output = Grouped<Subselect<<T as LimitDsl>::Output, <<T as SelectQuery>::SqlType as IntoNullable>::Nullable>>
The type returned by
.single_value
.source§fn single_value(self) -> <T as SingleValueDsl>::Output
fn single_value(self) -> <T as SingleValueDsl>::Output
See the trait documentation.