use crate::backend::{Backend, sql_dialect};
use crate::expression::nullable::Nullable;
use crate::expression::subselect::SubselectGroupBy;
use crate::expression::{
AppearsOnTable, Expression, SelectableExpression, ValidGrouping, is_aggregate,
};
use crate::query_builder::returning::{
InsertStmtWithOnConflictDoUpdate, OldIdent, ReturningQuerySource, UpdateStmt,
};
use crate::query_builder::{AstPass, QueryFragment, QueryId};
use crate::query_source::{AppearsInFromClause, Column};
use crate::result::QueryResult;
#[derive(Debug, Clone, Copy)]
pub struct Old<C> {
_column: C,
}
impl<C> Old<C> {
pub(crate) fn new(c: C) -> Self {
Old { _column: c }
}
}
pub fn old<C: Column>(col: C) -> Old<C> {
Old::new(col)
}
impl<C> QueryId for Old<C> {
type QueryId = ();
const HAS_STATIC_QUERY_ID: bool = false;
}
impl<C> Expression for Old<C>
where
C: Column + Expression,
{
type SqlType = <C as Expression>::SqlType;
}
impl<C> ValidGrouping<()> for Old<C>
where
C: Column,
{
type IsAggregate = is_aggregate::No;
}
impl<C, GB, From> ValidGrouping<SubselectGroupBy<GB, From>> for Old<C>
where
C: Column,
Self: ValidGrouping<GB>,
{
type IsAggregate = <Self as ValidGrouping<GB>>::IsAggregate;
}
impl<C, QS> AppearsOnTable<QS> for Old<C>
where
C: Column,
Self: Expression,
QS: AppearsInFromClause<OldIdent, Count = crate::query_source::Once>,
QS: AppearsInFromClause<
ReturningQuerySource<OldIdent, C::Table>,
Count = crate::query_source::Once,
>,
{
}
impl<C> SelectableExpression<ReturningQuerySource<UpdateStmt, C::Table>> for Old<C>
where
C: Column,
Self: AppearsOnTable<ReturningQuerySource<UpdateStmt, C::Table>>,
{
}
impl<C> SelectableExpression<ReturningQuerySource<InsertStmtWithOnConflictDoUpdate, C::Table>>
for Nullable<Old<C>>
where
C: Column,
Self: AppearsOnTable<ReturningQuerySource<InsertStmtWithOnConflictDoUpdate, C::Table>>,
{
}
impl<C, DB> QueryFragment<DB> for Old<C>
where
DB: Backend,
Self: QueryFragment<DB, DB::ReturningClause>,
{
fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
<Self as QueryFragment<DB, DB::ReturningClause>>::walk_ast(self, pass)
}
}
impl<C, DB> QueryFragment<DB, sql_dialect::returning_clause::PgLikeReturningClause> for Old<C>
where
DB: Backend<ReturningClause = sql_dialect::returning_clause::PgLikeReturningClause>,
C: Column,
{
fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
out.push_sql("old.");
out.push_identifier(C::NAME)?;
Ok(())
}
}
pub use return_type_helpers_reexported::*;
pub(crate) mod return_type_helpers_reexported {
use super::Old;
#[allow(non_camel_case_types)]
pub type old<C> = Old<C>;
}