use super::BoxedSelectStatement;
use crate::associations::HasTable;
use crate::backend::Backend;
use crate::dsl::AsExprOf;
use crate::expression::nullable::Nullable;
use crate::expression::*;
use crate::insertable::Insertable;
use crate::query_builder::combination_clause::*;
use crate::query_builder::distinct_clause::*;
use crate::query_builder::from_clause::AsQuerySource;
use crate::query_builder::from_clause::FromClause;
use crate::query_builder::group_by_clause::*;
use crate::query_builder::insert_statement::InsertFromSelect;
use crate::query_builder::limit_clause::*;
use crate::query_builder::limit_offset_clause::{BoxedLimitOffsetClause, LimitOffsetClause};
use crate::query_builder::locking_clause::*;
use crate::query_builder::offset_clause::*;
use crate::query_builder::order_clause::*;
use crate::query_builder::select_clause::*;
use crate::query_builder::update_statement::target::*;
use crate::query_builder::where_clause::*;
use crate::query_builder::NoFromClause;
use crate::query_builder::{
AsQuery, IntoBoxedClause, Query, QueryFragment, SelectQuery, SelectStatement,
};
use crate::query_dsl::boxed_dsl::BoxedDsl;
use crate::query_dsl::methods::*;
use crate::query_dsl::order_dsl::ValidOrderingForDistinct;
use crate::query_dsl::*;
use crate::query_source::joins::{Join, JoinOn, JoinTo};
use crate::query_source::QuerySource;
use crate::sql_types::{BigInt, BoolOrNullableBool};
impl<F, D, W, O, LOf, G, H, LC, Rhs, Kind, On> InternalJoinDsl<Rhs, Kind, On>
for SelectStatement<FromClause<F>, DefaultSelectClause<FromClause<F>>, D, W, O, LOf, G, H, LC>
where
F: QuerySource,
Rhs: QuerySource,
JoinOn<Join<F, Rhs, Kind>, On>: QuerySource,
SelectStatement<
FromClause<JoinOn<Join<F, Rhs, Kind>, On>>,
DefaultSelectClause<FromClause<JoinOn<Join<F, Rhs, Kind>, On>>>,
D,
W,
O,
LOf,
G,
H,
LC,
>: AsQuery,
{
type Output = SelectStatement<
FromClause<JoinOn<Join<F, Rhs, Kind>, On>>,
DefaultSelectClause<FromClause<JoinOn<Join<F, Rhs, Kind>, On>>>,
D,
W,
O,
LOf,
G,
H,
LC,
>;
fn join(self, rhs: Rhs, kind: Kind, on: On) -> Self::Output {
let from = FromClause::new(Join::new(self.from.source, rhs, kind).on(on));
SelectStatement::new(
DefaultSelectClause::new(&from),
from,
self.distinct,
self.where_clause,
self.order,
self.limit_offset,
self.group_by,
self.having,
self.locking,
)
}
}
impl<F, S, D, W, O, LOf, G, H, LC, Rhs, Kind, On> InternalJoinDsl<Rhs, Kind, On>
for SelectStatement<FromClause<F>, SelectClause<S>, D, W, O, LOf, G, H, LC>
where
F: QuerySource,
Rhs: QuerySource,
JoinOn<Join<F, Rhs, Kind>, On>: QuerySource,
SelectStatement<
FromClause<JoinOn<Join<F, Rhs, Kind>, On>>,
SelectClause<S>,
D,
W,
O,
LOf,
G,
H,
LC,
>: AsQuery,
{
type Output = SelectStatement<
FromClause<JoinOn<Join<F, Rhs, Kind>, On>>,
SelectClause<S>,
D,
W,
O,
LOf,
G,
H,
LC,
>;
fn join(self, rhs: Rhs, kind: Kind, on: On) -> Self::Output {
SelectStatement::new(
self.select,
FromClause::new(Join::new(self.from.source, rhs, kind).on(on)),
self.distinct,
self.where_clause,
self.order,
self.limit_offset,
self.group_by,
self.having,
self.locking,
)
}
}
impl<F, S, D, W, O, LOf, G, H, LC, Selection> SelectDsl<Selection>
for SelectStatement<FromClause<F>, S, D, W, O, LOf, G, H, LC>
where
G: ValidGroupByClause,
F: QuerySource,
Selection: SelectableExpression<F> + ValidGrouping<G::Expressions>,
SelectStatement<FromClause<F>, SelectClause<Selection>, D, W, O, LOf, G, H, LC>: SelectQuery,
{
type Output = SelectStatement<FromClause<F>, SelectClause<Selection>, D, W, O, LOf, G, H, LC>;
fn select(self, selection: Selection) -> Self::Output {
SelectStatement::new(
SelectClause(selection),
self.from,
self.distinct,
self.where_clause,
self.order,
self.limit_offset,
self.group_by,
self.having,
self.locking,
)
}
}
impl<S, D, W, O, LOf, G, H, LC, Selection> SelectDsl<Selection>
for SelectStatement<NoFromClause, S, D, W, O, LOf, G, H, LC>
where
G: ValidGroupByClause,
Selection: SelectableExpression<NoFromClause> + ValidGrouping<G::Expressions>,
SelectStatement<NoFromClause, SelectClause<Selection>, D, W, O, LOf, G, H, LC>: SelectQuery,
{
type Output = SelectStatement<NoFromClause, SelectClause<Selection>, D, W, O, LOf, G, H, LC>;
fn select(self, selection: Selection) -> Self::Output {
SelectStatement::new(
SelectClause(selection),
self.from,
self.distinct,
self.where_clause,
self.order,
self.limit_offset,
self.group_by,
self.having,
self.locking,
)
}
}
impl<ST, F, S, D, W, O, LOf, G, H> DistinctDsl for SelectStatement<F, S, D, W, O, LOf, G, H>
where
Self: SelectQuery<SqlType = ST>,
SelectStatement<F, S, DistinctClause, W, O, LOf, G, H>: SelectQuery<SqlType = ST>,
{
type Output = SelectStatement<F, S, DistinctClause, W, O, LOf, G, H>;
fn distinct(self) -> Self::Output {
SelectStatement::new(
self.select,
self.from,
DistinctClause,
self.where_clause,
self.order,
self.limit_offset,
self.group_by,
self.having,
self.locking,
)
}
}
impl<F, S, D, W, O, LOf, G, H, LC, Predicate> FilterDsl<Predicate>
for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
where
Predicate: Expression + NonAggregate,
Predicate::SqlType: BoolOrNullableBool,
W: WhereAnd<Predicate>,
{
type Output = SelectStatement<F, S, D, W::Output, O, LOf, G, H, LC>;
fn filter(self, predicate: Predicate) -> Self::Output {
SelectStatement::new(
self.select,
self.from,
self.distinct,
self.where_clause.and(predicate),
self.order,
self.limit_offset,
self.group_by,
self.having,
self.locking,
)
}
}
impl<F, S, D, W, O, LOf, G, H, LC, Predicate> OrFilterDsl<Predicate>
for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
where
Predicate: Expression + NonAggregate,
Predicate::SqlType: BoolOrNullableBool,
W: WhereOr<Predicate>,
{
type Output = SelectStatement<F, S, D, W::Output, O, LOf, G, H, LC>;
fn or_filter(self, predicate: Predicate) -> Self::Output {
SelectStatement::new(
self.select,
self.from,
self.distinct,
self.where_clause.or(predicate),
self.order,
self.limit_offset,
self.group_by,
self.having,
self.locking,
)
}
}
use crate::dsl::Filter;
use crate::expression_methods::EqAll;
use crate::query_builder::having_clause::{HavingClause, NoHavingClause};
use crate::query_source::Table;
impl<F, S, D, W, O, LOf, G, H, LC, PK> FindDsl<PK>
for SelectStatement<FromClause<F>, S, D, W, O, LOf, G, H, LC>
where
F: Table,
F::PrimaryKey: EqAll<PK>,
Self: FilterDsl<<F::PrimaryKey as EqAll<PK>>::Output>,
{
type Output = Filter<Self, <F::PrimaryKey as EqAll<PK>>::Output>;
fn find(self, id: PK) -> Self::Output {
let primary_key = self.from.source.primary_key();
FilterDsl::filter(self, primary_key.eq_all(id))
}
}
impl<ST, F, S, D, W, O, LOf, G, H, LC, Expr> OrderDsl<Expr>
for SelectStatement<FromClause<F>, S, D, W, O, LOf, G, H, LC>
where
F: QuerySource,
Expr: AppearsOnTable<F>,
Self: SelectQuery<SqlType = ST>,
SelectStatement<FromClause<F>, S, D, W, OrderClause<Expr>, LOf, G, H, LC>:
SelectQuery<SqlType = ST>,
OrderClause<Expr>: ValidOrderingForDistinct<D>,
{
type Output = SelectStatement<FromClause<F>, S, D, W, OrderClause<Expr>, LOf, G, H, LC>;
fn order(self, expr: Expr) -> Self::Output {
let order = OrderClause(expr);
SelectStatement::new(
self.select,
self.from,
self.distinct,
self.where_clause,
order,
self.limit_offset,
self.group_by,
self.having,
self.locking,
)
}
}
impl<F, S, D, W, O, LOf, G, H, LC, Expr> ThenOrderDsl<Expr>
for SelectStatement<FromClause<F>, S, D, W, OrderClause<O>, LOf, G, H, LC>
where
F: QuerySource,
Expr: AppearsOnTable<F>,
{
type Output = SelectStatement<FromClause<F>, S, D, W, OrderClause<(O, Expr)>, LOf, G, H, LC>;
fn then_order_by(self, expr: Expr) -> Self::Output {
SelectStatement::new(
self.select,
self.from,
self.distinct,
self.where_clause,
OrderClause((self.order.0, expr)),
self.limit_offset,
self.group_by,
self.having,
self.locking,
)
}
}
impl<F, S, D, W, LOf, G, LC, Expr> ThenOrderDsl<Expr>
for SelectStatement<F, S, D, W, NoOrderClause, LOf, G, LC>
where
Expr: Expression,
Self: OrderDsl<Expr>,
{
type Output = crate::dsl::Order<Self, Expr>;
fn then_order_by(self, expr: Expr) -> Self::Output {
self.order_by(expr)
}
}
#[doc(hidden)]
type Limit = AsExprOf<i64, BigInt>;
impl<ST, F, S, D, W, O, L, Of, G, H, LC> LimitDsl
for SelectStatement<F, S, D, W, O, LimitOffsetClause<L, Of>, G, H, LC>
where
Self: SelectQuery<SqlType = ST>,
SelectStatement<F, S, D, W, O, LimitOffsetClause<LimitClause<Limit>, Of>, G, H, LC>:
SelectQuery<SqlType = ST>,
{
type Output =
SelectStatement<F, S, D, W, O, LimitOffsetClause<LimitClause<Limit>, Of>, G, H, LC>;
fn limit(self, limit: i64) -> Self::Output {
let limit_clause = LimitClause(limit.into_sql::<BigInt>());
SelectStatement::new(
self.select,
self.from,
self.distinct,
self.where_clause,
self.order,
LimitOffsetClause {
limit_clause,
offset_clause: self.limit_offset.offset_clause,
},
self.group_by,
self.having,
self.locking,
)
}
}
#[doc(hidden)]
type Offset = Limit;
impl<ST, F, S, D, W, O, L, Of, G, H, LC> OffsetDsl
for SelectStatement<F, S, D, W, O, LimitOffsetClause<L, Of>, G, H, LC>
where
Self: SelectQuery<SqlType = ST>,
SelectStatement<F, S, D, W, O, LimitOffsetClause<L, OffsetClause<Offset>>, G, H, LC>:
SelectQuery<SqlType = ST>,
{
type Output =
SelectStatement<F, S, D, W, O, LimitOffsetClause<L, OffsetClause<Offset>>, G, H, LC>;
fn offset(self, offset: i64) -> Self::Output {
let offset_clause = OffsetClause(offset.into_sql::<BigInt>());
SelectStatement::new(
self.select,
self.from,
self.distinct,
self.where_clause,
self.order,
LimitOffsetClause {
limit_clause: self.limit_offset.limit_clause,
offset_clause,
},
self.group_by,
self.having,
self.locking,
)
}
}
impl<F, S, D, W, O, LOf, G, H, Expr> GroupByDsl<Expr> for SelectStatement<F, S, D, W, O, LOf, G, H>
where
SelectStatement<F, S, D, W, O, LOf, GroupByClause<Expr>, H>: SelectQuery,
Expr: Expression + AppearsOnTable<F>,
{
type Output = SelectStatement<F, S, D, W, O, LOf, GroupByClause<Expr>, H>;
fn group_by(self, expr: Expr) -> Self::Output {
let group_by = GroupByClause(expr);
SelectStatement::new(
self.select,
self.from,
self.distinct,
self.where_clause,
self.order,
self.limit_offset,
group_by,
self.having,
self.locking,
)
}
}
impl<F, S, W, O, LOf, Lock> LockingDsl<Lock>
for SelectStatement<F, S, NoDistinctClause, W, O, LOf>
{
type Output = SelectStatement<
F,
S,
NoDistinctClause,
W,
O,
LOf,
NoGroupByClause,
NoHavingClause,
LockingClause<Lock, NoModifier>,
>;
fn with_lock(self, lock: Lock) -> Self::Output {
SelectStatement::new(
self.select,
self.from,
self.distinct,
self.where_clause,
self.order,
self.limit_offset,
self.group_by,
self.having,
LockingClause::new(lock, NoModifier),
)
}
}
impl<F, S, D, W, O, LOf, G, H, LC, LM, Modifier> ModifyLockDsl<Modifier>
for SelectStatement<F, S, D, W, O, LOf, G, H, LockingClause<LC, LM>>
{
type Output = SelectStatement<F, S, D, W, O, LOf, G, H, LockingClause<LC, Modifier>>;
fn modify_lock(self, modifier: Modifier) -> Self::Output {
SelectStatement::new(
self.select,
self.from,
self.distinct,
self.where_clause,
self.order,
self.limit_offset,
self.group_by,
self.having,
LockingClause::new(self.locking.lock_mode, modifier),
)
}
}
impl<'a, F, S, D, W, O, LOf, G, H, DB> BoxedDsl<'a, DB>
for SelectStatement<FromClause<F>, S, D, W, O, LOf, G, H>
where
Self: AsQuery,
DB: Backend,
F: QuerySource,
S: SelectClauseExpression<FromClause<F>> + QueryFragment<DB> + Send + 'a,
S::Selection: ValidGrouping<G::Expressions>,
D: QueryFragment<DB> + Send + 'a,
W: Into<BoxedWhereClause<'a, DB>>,
O: Into<Option<Box<dyn QueryFragment<DB> + Send + 'a>>>,
LOf: IntoBoxedClause<'a, DB, BoxedClause = BoxedLimitOffsetClause<'a, DB>>,
G: ValidGroupByClause + QueryFragment<DB> + Send + 'a,
H: QueryFragment<DB> + Send + 'a,
{
type Output =
BoxedSelectStatement<'a, S::SelectClauseSqlType, FromClause<F>, DB, G::Expressions>;
fn internal_into_boxed(self) -> Self::Output {
BoxedSelectStatement::new(
self.select,
self.from,
Box::new(self.distinct),
self.where_clause.into(),
self.order.into(),
self.limit_offset.into_boxed(),
self.group_by,
Box::new(self.having),
)
}
}
impl<'a, S, D, W, O, LOf, G, H, DB> BoxedDsl<'a, DB>
for SelectStatement<NoFromClause, S, D, W, O, LOf, G, H>
where
Self: AsQuery,
DB: Backend,
S: SelectClauseExpression<NoFromClause> + QueryFragment<DB> + Send + 'a,
S::Selection: ValidGrouping<G::Expressions>,
D: QueryFragment<DB> + Send + 'a,
W: Into<BoxedWhereClause<'a, DB>>,
O: Into<Option<Box<dyn QueryFragment<DB> + Send + 'a>>>,
LOf: IntoBoxedClause<'a, DB, BoxedClause = BoxedLimitOffsetClause<'a, DB>>,
G: ValidGroupByClause + QueryFragment<DB> + Send + 'a,
H: QueryFragment<DB> + Send + 'a,
{
type Output =
BoxedSelectStatement<'a, S::SelectClauseSqlType, NoFromClause, DB, G::Expressions>;
fn internal_into_boxed(self) -> Self::Output {
BoxedSelectStatement::new_no_from_clause(
self.select,
self.from,
Box::new(self.distinct),
self.where_clause.into(),
self.order.into(),
self.limit_offset.into_boxed(),
self.group_by,
Box::new(self.having),
)
}
}
impl<F, S, D, W, O, LOf, G, H, LC> HasTable
for SelectStatement<FromClause<F>, S, D, W, O, LOf, G, H, LC>
where
F: HasTable + QuerySource,
{
type Table = F::Table;
fn table() -> Self::Table {
F::table()
}
}
impl<F, W> IntoUpdateTarget
for SelectStatement<FromClause<F>, DefaultSelectClause<FromClause<F>>, NoDistinctClause, W>
where
F: QuerySource,
Self: HasTable,
W: ValidWhereClause<F>,
{
type WhereClause = W;
fn into_update_target(self) -> UpdateTarget<Self::Table, Self::WhereClause> {
UpdateTarget {
table: Self::table(),
where_clause: self.where_clause,
}
}
}
impl<F, S, D, W, O, LOf, G, H, LC, Rhs> JoinTo<Rhs>
for SelectStatement<FromClause<F>, S, D, W, O, LOf, G, H, LC>
where
F: JoinTo<Rhs> + QuerySource,
{
type FromClause = <F as JoinTo<Rhs>>::FromClause;
type OnClause = F::OnClause;
fn join_target(rhs: Rhs) -> (Self::FromClause, Self::OnClause) {
F::join_target(rhs)
}
}
impl<F, S, D, W, O, LOf, G, H, LC> QueryDsl for SelectStatement<F, S, D, W, O, LOf, G, H, LC> {}
impl<F, S, D, W, O, LOf, G, H, LC, Conn> RunQueryDsl<Conn>
for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
{
}
impl<F, S, D, W, O, LOf, G, H, LC, Tab> Insertable<Tab>
for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
where
Tab: Table,
Self: Query,
<Tab::AllColumns as ValidGrouping<()>>::IsAggregate:
MixedAggregates<is_aggregate::No, Output = is_aggregate::No>,
{
type Values = InsertFromSelect<Self, Tab::AllColumns>;
fn values(self) -> Self::Values {
InsertFromSelect::new(self)
}
}
impl<'a, F, S, D, W, O, LOf, G, H, LC, Tab> Insertable<Tab>
for &'a SelectStatement<F, S, D, W, O, LOf, G, H, LC>
where
Tab: Table,
Self: Query,
<Tab::AllColumns as ValidGrouping<()>>::IsAggregate:
MixedAggregates<is_aggregate::No, Output = is_aggregate::No>,
{
type Values = InsertFromSelect<Self, Tab::AllColumns>;
fn values(self) -> Self::Values {
InsertFromSelect::new(self)
}
}
impl<F, S, D, W, O, LOf, G, H> SelectNullableDsl
for SelectStatement<F, SelectClause<S>, D, W, O, LOf, G, H>
{
type Output = SelectStatement<F, SelectClause<Nullable<S>>, D, W, O, LOf, G, H>;
fn nullable(self) -> Self::Output {
SelectStatement::new(
SelectClause(Nullable::new(self.select.0)),
self.from,
self.distinct,
self.where_clause,
self.order,
self.limit_offset,
self.group_by,
self.having,
self.locking,
)
}
}
impl<F, D, W, O, LOf, G, H> SelectNullableDsl
for SelectStatement<F, DefaultSelectClause<F>, D, W, O, LOf, G, H>
where
F: AsQuerySource,
{
type Output = SelectStatement<
F,
SelectClause<Nullable<<F::QuerySource as QuerySource>::DefaultSelection>>,
D,
W,
O,
LOf,
G,
H,
>;
fn nullable(self) -> Self::Output {
SelectStatement::new(
SelectClause(Nullable::new(
self.from.as_query_source().default_selection(),
)),
self.from,
self.distinct,
self.where_clause,
self.order,
self.limit_offset,
self.group_by,
self.having,
self.locking,
)
}
}
impl<F, S, D, W, O, LOf, G, H, Predicate> HavingDsl<Predicate>
for SelectStatement<FromClause<F>, S, D, W, O, LOf, GroupByClause<G>, H>
where
F: QuerySource,
Predicate: AppearsOnTable<F>,
Predicate: Expression,
Predicate::SqlType: BoolOrNullableBool,
{
type Output =
SelectStatement<FromClause<F>, S, D, W, O, LOf, GroupByClause<G>, HavingClause<Predicate>>;
fn having(self, predicate: Predicate) -> Self::Output {
SelectStatement::new(
self.select,
self.from,
self.distinct,
self.where_clause,
self.order,
self.limit_offset,
self.group_by,
HavingClause(predicate),
self.locking,
)
}
}
impl<F, S, D, W, O, LOf, G, H, LC> CombineDsl for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
where
Self: Query,
{
type Query = Self;
fn union<Rhs>(self, rhs: Rhs) -> crate::dsl::Union<Self, Rhs>
where
Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
{
CombinationClause::new(Union, Distinct, self, rhs.as_query())
}
fn union_all<Rhs>(self, rhs: Rhs) -> crate::dsl::UnionAll<Self, Rhs>
where
Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
{
CombinationClause::new(Union, All, self, rhs.as_query())
}
fn intersect<Rhs>(self, rhs: Rhs) -> crate::dsl::Intersect<Self, Rhs>
where
Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
{
CombinationClause::new(Intersect, Distinct, self, rhs.as_query())
}
fn intersect_all<Rhs>(self, rhs: Rhs) -> crate::dsl::IntersectAll<Self, Rhs>
where
Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
{
CombinationClause::new(Intersect, All, self, rhs.as_query())
}
fn except<Rhs>(self, rhs: Rhs) -> crate::dsl::Except<Self, Rhs>
where
Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
{
CombinationClause::new(Except, Distinct, self, rhs.as_query())
}
fn except_all<Rhs>(self, rhs: Rhs) -> crate::dsl::ExceptAll<Self, Rhs>
where
Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
{
CombinationClause::new(Except, All, self, rhs.as_query())
}
}