blob: 7412e56352e2a2f73250ae4c933e44a6ad8943c8 [file] [log] [blame]
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::distinct_clause::*;
use crate::query_builder::group_by_clause::*;
use crate::query_builder::insert_statement::InsertFromSelect;
use crate::query_builder::limit_clause::*;
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::*;
use crate::query_builder::where_clause::*;
use crate::query_builder::{AsQuery, Query, QueryFragment, SelectQuery, SelectStatement};
use crate::query_dsl::boxed_dsl::BoxedDsl;
use crate::query_dsl::methods::*;
use crate::query_dsl::*;
use crate::query_source::joins::{Join, JoinOn, JoinTo};
use crate::query_source::QuerySource;
use crate::sql_types::{BigInt, Bool};
impl<F, S, D, W, O, L, Of, G, LC, Rhs, Kind, On> InternalJoinDsl<Rhs, Kind, On>
for SelectStatement<F, S, D, W, O, L, Of, G, LC>
where
SelectStatement<JoinOn<Join<F, Rhs, Kind>, On>, S, D, W, O, L, Of, G, LC>: AsQuery,
{
type Output = SelectStatement<JoinOn<Join<F, Rhs, Kind>, On>, S, D, W, O, L, Of, G, LC>;
fn join(self, rhs: Rhs, kind: Kind, on: On) -> Self::Output {
SelectStatement::new(
self.select,
Join::new(self.from, rhs, kind).on(on),
self.distinct,
self.where_clause,
self.order,
self.limit,
self.offset,
self.group_by,
self.locking,
)
}
}
impl<F, S, D, W, O, L, Of, G, LC, Selection> SelectDsl<Selection>
for SelectStatement<F, S, D, W, O, L, Of, G, LC>
where
G: ValidGroupByClause,
Selection: SelectableExpression<F> + ValidGrouping<G::Expressions>,
SelectStatement<F, SelectClause<Selection>, D, W, O, L, Of, G, LC>: SelectQuery,
{
type Output = SelectStatement<F, SelectClause<Selection>, D, W, O, L, Of, G, LC>;
fn select(self, selection: Selection) -> Self::Output {
SelectStatement::new(
SelectClause(selection),
self.from,
self.distinct,
self.where_clause,
self.order,
self.limit,
self.offset,
self.group_by,
self.locking,
)
}
}
impl<ST, F, S, D, W, O, L, Of, G> DistinctDsl for SelectStatement<F, S, D, W, O, L, Of, G>
where
Self: SelectQuery<SqlType = ST>,
SelectStatement<F, S, DistinctClause, W, O, L, Of, G>: SelectQuery<SqlType = ST>,
{
type Output = SelectStatement<F, S, DistinctClause, W, O, L, Of, G>;
fn distinct(self) -> Self::Output {
SelectStatement::new(
self.select,
self.from,
DistinctClause,
self.where_clause,
self.order,
self.limit,
self.offset,
self.group_by,
self.locking,
)
}
}
impl<F, S, D, W, O, L, Of, G, LC, Predicate> FilterDsl<Predicate>
for SelectStatement<F, S, D, W, O, L, Of, G, LC>
where
Predicate: Expression<SqlType = Bool> + NonAggregate,
W: WhereAnd<Predicate>,
{
type Output = SelectStatement<F, S, D, W::Output, O, L, Of, G, 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,
self.offset,
self.group_by,
self.locking,
)
}
}
impl<F, S, D, W, O, L, Of, G, LC, Predicate> OrFilterDsl<Predicate>
for SelectStatement<F, S, D, W, O, L, Of, G, LC>
where
Predicate: Expression<SqlType = Bool> + NonAggregate,
W: WhereOr<Predicate>,
{
type Output = SelectStatement<F, S, D, W::Output, O, L, Of, G, 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,
self.offset,
self.group_by,
self.locking,
)
}
}
use crate::dsl::Filter;
use crate::expression_methods::EqAll;
use crate::query_source::Table;
impl<F, S, D, W, O, L, Of, G, LC, PK> FindDsl<PK> for SelectStatement<F, S, D, W, O, L, Of, G, 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.primary_key();
FilterDsl::filter(self, primary_key.eq_all(id))
}
}
impl<ST, F, S, D, W, O, L, Of, G, LC, Expr> OrderDsl<Expr>
for SelectStatement<F, S, D, W, O, L, Of, G, LC>
where
Expr: AppearsOnTable<F>,
Self: SelectQuery<SqlType = ST>,
SelectStatement<F, S, D, W, OrderClause<Expr>, L, Of, G, LC>: SelectQuery<SqlType = ST>,
{
type Output = SelectStatement<F, S, D, W, OrderClause<Expr>, L, Of, G, 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,
self.offset,
self.group_by,
self.locking,
)
}
}
impl<F, S, D, W, O, L, Of, G, LC, Expr> ThenOrderDsl<Expr>
for SelectStatement<F, S, D, W, OrderClause<O>, L, Of, G, LC>
where
Expr: AppearsOnTable<F>,
{
type Output = SelectStatement<F, S, D, W, OrderClause<(O, Expr)>, L, Of, G, 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,
self.offset,
self.group_by,
self.locking,
)
}
}
impl<F, S, D, W, L, Of, G, LC, Expr> ThenOrderDsl<Expr>
for SelectStatement<F, S, D, W, NoOrderClause, L, Of, 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)]
pub type Limit = AsExprOf<i64, BigInt>;
impl<ST, F, S, D, W, O, L, Of, G, LC> LimitDsl for SelectStatement<F, S, D, W, O, L, Of, G, LC>
where
Self: SelectQuery<SqlType = ST>,
SelectStatement<F, S, D, W, O, LimitClause<Limit>, Of, G, LC>: SelectQuery<SqlType = ST>,
{
type Output = SelectStatement<F, S, D, W, O, LimitClause<Limit>, Of, G, 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,
limit_clause,
self.offset,
self.group_by,
self.locking,
)
}
}
#[doc(hidden)]
pub type Offset = Limit;
impl<ST, F, S, D, W, O, L, Of, G, LC> OffsetDsl for SelectStatement<F, S, D, W, O, L, Of, G, LC>
where
Self: SelectQuery<SqlType = ST>,
SelectStatement<F, S, D, W, O, L, OffsetClause<Offset>, G, LC>: SelectQuery<SqlType = ST>,
{
type Output = SelectStatement<F, S, D, W, O, L, OffsetClause<Offset>, G, 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,
self.limit,
offset_clause,
self.group_by,
self.locking,
)
}
}
impl<F, S, D, W, O, L, Of, G, Expr> GroupByDsl<Expr> for SelectStatement<F, S, D, W, O, L, Of, G>
where
SelectStatement<F, S, D, W, O, L, Of, GroupByClause<Expr>>: SelectQuery,
Expr: Expression,
{
type Output = SelectStatement<F, S, D, W, O, L, Of, GroupByClause<Expr>>;
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,
self.offset,
group_by,
self.locking,
)
}
}
impl<F, S, W, O, L, Of, Lock> LockingDsl<Lock>
for SelectStatement<F, S, NoDistinctClause, W, O, L, Of>
{
type Output = SelectStatement<
F,
S,
NoDistinctClause,
W,
O,
L,
Of,
NoGroupByClause,
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,
self.offset,
self.group_by,
LockingClause::new(lock, NoModifier),
)
}
}
impl<F, S, D, W, O, L, Of, G, LC, LM, Modifier> ModifyLockDsl<Modifier>
for SelectStatement<F, S, D, W, O, L, Of, G, LockingClause<LC, LM>>
{
type Output = SelectStatement<F, S, D, W, O, L, Of, G, 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,
self.offset,
self.group_by,
LockingClause::new(self.locking.lock_mode, modifier),
)
}
}
impl<'a, F, S, D, W, O, L, Of, G, DB> BoxedDsl<'a, DB>
for SelectStatement<F, SelectClause<S>, D, W, O, L, Of, G>
where
Self: AsQuery,
DB: Backend,
S: QueryFragment<DB> + SelectableExpression<F> + Send + 'a,
D: QueryFragment<DB> + Send + 'a,
W: Into<BoxedWhereClause<'a, DB>>,
O: Into<Option<Box<dyn QueryFragment<DB> + Send + 'a>>>,
L: QueryFragment<DB> + Send + 'a,
Of: QueryFragment<DB> + Send + 'a,
G: QueryFragment<DB> + Send + 'a,
{
type Output = BoxedSelectStatement<'a, S::SqlType, F, DB>;
fn internal_into_boxed(self) -> Self::Output {
BoxedSelectStatement::new(
Box::new(self.select.0),
self.from,
Box::new(self.distinct),
self.where_clause.into(),
self.order.into(),
Box::new(self.limit),
Box::new(self.offset),
Box::new(self.group_by),
)
}
}
impl<'a, F, D, W, O, L, Of, G, DB> BoxedDsl<'a, DB>
for SelectStatement<F, DefaultSelectClause, D, W, O, L, Of, G>
where
Self: AsQuery,
DB: Backend,
F: QuerySource,
F::DefaultSelection: QueryFragment<DB> + Send + 'a,
D: QueryFragment<DB> + Send + 'a,
W: Into<BoxedWhereClause<'a, DB>>,
O: Into<Option<Box<dyn QueryFragment<DB> + Send + 'a>>>,
L: QueryFragment<DB> + Send + 'a,
Of: QueryFragment<DB> + Send + 'a,
G: QueryFragment<DB> + Send + 'a,
{
type Output = BoxedSelectStatement<'a, <F::DefaultSelection as Expression>::SqlType, F, DB>;
fn internal_into_boxed(self) -> Self::Output {
BoxedSelectStatement::new(
Box::new(self.from.default_selection()),
self.from,
Box::new(self.distinct),
self.where_clause.into(),
self.order.into(),
Box::new(self.limit),
Box::new(self.offset),
Box::new(self.group_by),
)
}
}
impl<F, S, D, W, O, L, Of, G, LC> HasTable for SelectStatement<F, S, D, W, O, L, Of, G, LC>
where
F: HasTable,
{
type Table = F::Table;
fn table() -> Self::Table {
F::table()
}
}
impl<F, W> IntoUpdateTarget for SelectStatement<F, DefaultSelectClause, NoDistinctClause, W>
where
SelectStatement<F, DefaultSelectClause, NoDistinctClause, W>: 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,
}
}
}
// FIXME: Should we disable joining when `.group_by` has been called? Are there
// any other query methods where a join no longer has the same semantics as
// joining on just the table?
impl<F, S, D, W, O, L, Of, G, LC, Rhs> JoinTo<Rhs> for SelectStatement<F, S, D, W, O, L, Of, G, LC>
where
F: JoinTo<Rhs>,
{
type FromClause = F::FromClause;
type OnClause = F::OnClause;
fn join_target(rhs: Rhs) -> (Self::FromClause, Self::OnClause) {
F::join_target(rhs)
}
}
impl<F, S, D, W, O, L, Of, G, LC> QueryDsl for SelectStatement<F, S, D, W, O, L, Of, G, LC> {}
impl<F, S, D, W, O, L, Of, G, LC, Conn> RunQueryDsl<Conn>
for SelectStatement<F, S, D, W, O, L, Of, G, LC>
{
}
impl<F, S, D, W, O, L, Of, G, LC, Tab> Insertable<Tab>
for SelectStatement<F, S, D, W, O, L, Of, G, LC>
where
Tab: Table,
Self: Query,
{
type Values = InsertFromSelect<Self, Tab::AllColumns>;
fn values(self) -> Self::Values {
InsertFromSelect::new(self)
}
}
impl<'a, F, S, D, W, O, L, Of, G, LC, Tab> Insertable<Tab>
for &'a SelectStatement<F, S, D, W, O, L, Of, G, LC>
where
Tab: Table,
Self: Query,
{
type Values = InsertFromSelect<Self, Tab::AllColumns>;
fn values(self) -> Self::Values {
InsertFromSelect::new(self)
}
}
impl<'a, F, S, D, W, O, L, Of, G> SelectNullableDsl
for SelectStatement<F, SelectClause<S>, D, W, O, L, Of, G>
{
type Output = SelectStatement<F, SelectClause<Nullable<S>>, D, W, O, L, Of, G>;
fn nullable(self) -> Self::Output {
SelectStatement::new(
SelectClause(Nullable::new(self.select.0)),
self.from,
self.distinct,
self.where_clause,
self.order,
self.limit,
self.offset,
self.group_by,
self.locking,
)
}
}
impl<'a, F, D, W, O, L, Of, G> SelectNullableDsl
for SelectStatement<F, DefaultSelectClause, D, W, O, L, Of, G>
where
F: QuerySource,
{
type Output =
SelectStatement<F, SelectClause<Nullable<F::DefaultSelection>>, D, W, O, L, Of, G>;
fn nullable(self) -> Self::Output {
SelectStatement::new(
SelectClause(Nullable::new(self.from.default_selection())),
self.from,
self.distinct,
self.where_clause,
self.order,
self.limit,
self.offset,
self.group_by,
self.locking,
)
}
}