Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds support for Views. #4077

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
6 changes: 4 additions & 2 deletions diesel/src/expression/operators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,12 +557,14 @@ use crate::insertable::{ColumnInsertValue, Insertable};
use crate::query_builder::{QueryFragment, QueryId, ValuesClause};
use crate::query_source::Column;
use crate::sql_types::{DieselNumericOps, SqlType};
use crate::Table;

impl<T, U> Insertable<T::Table> for Eq<T, U>
impl<T, U> Insertable<T::Source> for Eq<T, U>
where
T: Column,
T::Source: Table,
{
type Values = ValuesClause<ColumnInsertValue<T, U>, T::Table>;
type Values = ValuesClause<ColumnInsertValue<T, U>, T::Source>;

fn values(self) -> Self::Values {
ValuesClause::new(ColumnInsertValue::new(self.right))
Expand Down
9 changes: 6 additions & 3 deletions diesel/src/insertable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,12 @@ impl<T> Default for DefaultableColumnInsertValue<T> {
}
}

impl<Col, Expr, DB> InsertValues<DB, Col::Table>
impl<Col, Expr, DB> InsertValues<DB, Col::Source>
for DefaultableColumnInsertValue<ColumnInsertValue<Col, Expr>>
where
DB: Backend + SqlDialect<InsertWithDefaultKeyword = sql_dialect::default_keyword_for_insert::IsoSqlDefaultKeyword>,
Col: Column,
Col::Source: Table,
Expr: Expression<SqlType = Col::SqlType> + AppearsOnTable<NoFromClause>,
Self: QueryFragment<DB>,
{
Expand All @@ -168,10 +169,11 @@ where
}
}

impl<Col, Expr, DB> InsertValues<DB, Col::Table> for ColumnInsertValue<Col, Expr>
impl<Col, Expr, DB> InsertValues<DB, Col::Source> for ColumnInsertValue<Col, Expr>
where
DB: Backend,
Col: Column,
Col::Source: Table,
Expr: Expression<SqlType = Col::SqlType> + AppearsOnTable<NoFromClause>,
Self: QueryFragment<DB>,
{
Expand Down Expand Up @@ -218,10 +220,11 @@ where
}

#[cfg(feature = "sqlite")]
impl<Col, Expr> InsertValues<crate::sqlite::Sqlite, Col::Table>
impl<Col, Expr> InsertValues<crate::sqlite::Sqlite, Col::Source>
for DefaultableColumnInsertValue<ColumnInsertValue<Col, Expr>>
where
Col: Column,
Col::Source: Table,
Expr: Expression<SqlType = Col::SqlType> + AppearsOnTable<NoFromClause>,
Self: QueryFragment<crate::sqlite::Sqlite>,
{
Expand Down
4 changes: 4 additions & 0 deletions diesel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,8 @@ pub mod prelude {
};
#[doc(inline)]
pub use diesel_derives::table_proc as table;
#[doc(inline)]
pub use diesel_derives::view_proc as view;

#[cfg(feature = "mysql")]
#[doc(inline)]
Expand All @@ -742,6 +744,8 @@ pub mod prelude {

#[doc(inline)]
pub use crate::macros::table;
#[doc(inline)]
pub use crate::macros::view;
pub use crate::prelude::*;
#[doc(inline)]
pub use crate::query_builder::debug_query;
Expand Down
22 changes: 12 additions & 10 deletions diesel/src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ pub(crate) mod prelude {

#[doc(inline)]
pub use diesel_derives::table_proc as table;
#[doc(inline)]
pub use diesel_derives::view_proc as view;

/// Allow two tables to be referenced in a join query without providing an
/// explicit `ON` clause.
Expand Down Expand Up @@ -211,8 +213,8 @@ macro_rules! joinable_inner {
macro_rules! allow_tables_to_appear_in_same_query {
($left_mod:ident, $($right_mod:ident),+ $(,)*) => {
$(
impl $crate::query_source::TableNotEqual<$left_mod::table> for $right_mod::table {}
impl $crate::query_source::TableNotEqual<$right_mod::table> for $left_mod::table {}
impl $crate::query_source::ViewNotEqual<$left_mod::table> for $right_mod::table {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm in some other places we name this around Source as the common denominator of view and table, it looks like this may be something we want to be consistent with here.

impl $crate::query_source::ViewNotEqual<$right_mod::table> for $left_mod::table {}
$crate::__diesel_internal_backend_specific_allow_tables_to_appear_in_same_query!($left_mod, $right_mod);
)+
$crate::allow_tables_to_appear_in_same_query!($($right_mod,)+);
Expand All @@ -227,44 +229,44 @@ macro_rules! allow_tables_to_appear_in_same_query {
#[cfg(feature = "postgres_backend")]
macro_rules! __diesel_internal_backend_specific_allow_tables_to_appear_in_same_query {
($left:ident, $right:ident) => {
impl $crate::query_source::TableNotEqual<$left::table>
impl $crate::query_source::ViewNotEqual<$left::table>
for $crate::query_builder::Only<$right::table>
{
}
impl $crate::query_source::TableNotEqual<$right::table>
impl $crate::query_source::ViewNotEqual<$right::table>
for $crate::query_builder::Only<$left::table>
{
}
impl $crate::query_source::TableNotEqual<$crate::query_builder::Only<$left::table>>
impl $crate::query_source::ViewNotEqual<$crate::query_builder::Only<$left::table>>
for $right::table
{
}
impl $crate::query_source::TableNotEqual<$crate::query_builder::Only<$right::table>>
impl $crate::query_source::ViewNotEqual<$crate::query_builder::Only<$right::table>>
for $left::table
{
}
impl<TSM> $crate::query_source::TableNotEqual<$left::table>
impl<TSM> $crate::query_source::ViewNotEqual<$left::table>
for $crate::query_builder::Tablesample<$right::table, TSM>
where
TSM: $crate::internal::table_macro::TablesampleMethod,
{
}
impl<TSM> $crate::query_source::TableNotEqual<$right::table>
impl<TSM> $crate::query_source::ViewNotEqual<$right::table>
for $crate::query_builder::Tablesample<$left::table, TSM>
where
TSM: $crate::internal::table_macro::TablesampleMethod,
{
}
impl<TSM>
$crate::query_source::TableNotEqual<
$crate::query_source::ViewNotEqual<
$crate::query_builder::Tablesample<$left::table, TSM>,
> for $right::table
where
TSM: $crate::internal::table_macro::TablesampleMethod,
{
}
impl<TSM>
$crate::query_source::TableNotEqual<
$crate::query_source::ViewNotEqual<
$crate::query_builder::Tablesample<$right::table, TSM>,
> for $left::table
where
Expand Down
5 changes: 3 additions & 2 deletions diesel/src/pg/expression/operators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::query_builder::{AstPass, QueryFragment, QueryId};
use crate::sql_types::{
Array, Bigint, Bool, DieselNumericOps, Inet, Integer, Jsonb, SqlType, Text,
};
use crate::{Column, QueryResult};
use crate::{Column, QueryResult, Table};

__diesel_infix_operator!(IsDistinctFrom, " IS DISTINCT FROM ", ConstantNullability Bool, backend: Pg);
__diesel_infix_operator!(IsNotDistinctFrom, " IS NOT DISTINCT FROM ", ConstantNullability Bool, backend: Pg);
Expand Down Expand Up @@ -94,8 +94,9 @@ where
impl<L, R> AssignmentTarget for ArrayIndex<L, R>
where
L: Column,
L::Source: Table,
{
type Table = <L as Column>::Table;
type Table = <L as Column>::Source;
type QueryAstNode = ArrayIndex<UncorrelatedColumn<L>, R>;

fn into_target(self) -> Self::QueryAstNode {
Expand Down
4 changes: 2 additions & 2 deletions diesel/src/pg/query_builder/copy/copy_from.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ macro_rules! impl_copy_from_insertable_helper_for_values_clause {
T>
where
T: Table,
$($ST: Column<Table = T>,)*
$($ST: Column<Source = T>,)*
($($ST,)*): CopyTarget,
$($TT: ToSql<$T, Pg>,)*
{
Expand Down Expand Up @@ -229,7 +229,7 @@ macro_rules! impl_copy_from_insertable_helper_for_values_clause {
T>
where
T: Table,
$($ST: Column<Table = T>,)*
$($ST: Column<Source = T>,)*
($($ST,)*): CopyTarget,
$($TT: ToSql<$T, Pg>,)*
{
Expand Down
2 changes: 1 addition & 1 deletion diesel/src/pg/query_builder/copy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ macro_rules! copy_target_for_columns {
$(
impl<T, $($ST,)*> CopyTarget for ($($ST,)*)
where
$($ST: Column<Table = T>,)*
$($ST: Column<Source = T>,)*
($(<$ST as Expression>::SqlType,)*): SqlType,
T: Table + StaticQueryFragment,
T::Component: QueryFragment<Pg>,
Expand Down
24 changes: 17 additions & 7 deletions diesel/src/pg/query_builder/only.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::expression::{Expression, ValidGrouping};
use crate::pg::Pg;
use crate::query_builder::{AsQuery, AstPass, FromClause, QueryFragment, QueryId, SelectStatement};
use crate::query_source::QuerySource;
use crate::query_source::{QuerySource, View};
use crate::result::QueryResult;
use crate::{JoinTo, SelectableExpression, Table};

Expand Down Expand Up @@ -74,22 +74,32 @@ where
<S as JoinTo<T>>::join_target(rhs)
}
}

impl<S> View for Only<S>
where
S: Table + Clone + AsQuery,

<S as Table>::PrimaryKey: SelectableExpression<Only<S>>,
<S as View>::AllColumns: SelectableExpression<Only<S>>,
<S as QuerySource>::DefaultSelection: ValidGrouping<()> + SelectableExpression<Only<S>>,
{
type AllColumns = <S as View>::AllColumns;
fn all_columns() -> Self::AllColumns {
S::all_columns()
}
}

impl<S> Table for Only<S>
where
S: Table + Clone + AsQuery,

<S as Table>::PrimaryKey: SelectableExpression<Only<S>>,
<S as Table>::AllColumns: SelectableExpression<Only<S>>,
<S as View>::AllColumns: SelectableExpression<Only<S>>,
<S as QuerySource>::DefaultSelection: ValidGrouping<()> + SelectableExpression<Only<S>>,
{
type PrimaryKey = <S as Table>::PrimaryKey;
type AllColumns = <S as Table>::AllColumns;

fn primary_key(&self) -> Self::PrimaryKey {
self.source.primary_key()
}

fn all_columns() -> Self::AllColumns {
S::all_columns()
}
}
26 changes: 19 additions & 7 deletions diesel/src/pg/query_builder/tablesample.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::expression::{Expression, ValidGrouping};
use crate::pg::Pg;
use crate::query_builder::{AsQuery, AstPass, FromClause, QueryFragment, QueryId, SelectStatement};
use crate::query_source::QuerySource;
use crate::query_source::{QuerySource, View};
use crate::result::QueryResult;
use crate::sql_types::{Double, SmallInt};
use crate::{JoinTo, SelectableExpression, Table};
Expand Down Expand Up @@ -147,26 +147,38 @@ where
}
}

impl<S, TSM> View for Tablesample<S, TSM>
where
S: Table + Clone + AsQuery,
TSM: TablesampleMethod,

<S as Table>::PrimaryKey: SelectableExpression<Tablesample<S, TSM>>,
<S as View>::AllColumns: SelectableExpression<Tablesample<S, TSM>>,
<S as QuerySource>::DefaultSelection:
ValidGrouping<()> + SelectableExpression<Tablesample<S, TSM>>,
{
type AllColumns = <S as View>::AllColumns;

fn all_columns() -> Self::AllColumns {
S::all_columns()
}
}

impl<S, TSM> Table for Tablesample<S, TSM>
where
S: Table + Clone + AsQuery,
TSM: TablesampleMethod,

<S as Table>::PrimaryKey: SelectableExpression<Tablesample<S, TSM>>,
<S as Table>::AllColumns: SelectableExpression<Tablesample<S, TSM>>,
<S as View>::AllColumns: SelectableExpression<Tablesample<S, TSM>>,
<S as QuerySource>::DefaultSelection:
ValidGrouping<()> + SelectableExpression<Tablesample<S, TSM>>,
{
type PrimaryKey = <S as Table>::PrimaryKey;
type AllColumns = <S as Table>::AllColumns;

fn primary_key(&self) -> Self::PrimaryKey {
self.source.primary_key()
}

fn all_columns() -> Self::AllColumns {
S::all_columns()
}
}

#[cfg(test)]
Expand Down
5 changes: 3 additions & 2 deletions diesel/src/query_builder/insert_statement/column_list.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::query_builder::*;
use crate::query_source::Column;
use crate::{query_builder::*, Table};

/// Represents the column list for use in an insert statement.
///
Expand All @@ -17,8 +17,9 @@ pub trait ColumnList {
impl<C> ColumnList for C
where
C: Column,
C::Source: Table,
{
type Table = <C as Column>::Table;
type Table = <C as Column>::Source;

fn walk_ast<DB: Backend>(&self, mut out: AstPass<'_, '_, DB>) -> QueryResult<()> {
out.push_identifier(C::NAME)?;
Expand Down
24 changes: 20 additions & 4 deletions diesel/src/query_builder/insert_statement/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,12 +322,18 @@ impl<'a, T, Tab> UndecoratedInsertRecord<Tab> for &'a T where
{
}

impl<T, U> UndecoratedInsertRecord<T::Table> for ColumnInsertValue<T, U> where T: Column {}
impl<T, U> UndecoratedInsertRecord<T::Source> for ColumnInsertValue<T, U>
where
T: Column,
T::Source: Table,
{
}

impl<T, U> UndecoratedInsertRecord<T::Table>
impl<T, U> UndecoratedInsertRecord<T::Source>
for DefaultableColumnInsertValue<ColumnInsertValue<T, U>>
where
T: Column,
T::Source: Table,
{
}

Expand All @@ -342,14 +348,24 @@ where

impl<T, Table> UndecoratedInsertRecord<Table> for Vec<T> where [T]: UndecoratedInsertRecord<Table> {}

impl<Lhs, Rhs> UndecoratedInsertRecord<Lhs::Table> for Eq<Lhs, Rhs> where Lhs: Column {}
impl<Lhs, Rhs> UndecoratedInsertRecord<Lhs::Source> for Eq<Lhs, Rhs>
where
Lhs: Column,
Lhs::Source: Table,
{
}

impl<Lhs, Rhs, Tab> UndecoratedInsertRecord<Tab> for Option<Eq<Lhs, Rhs>> where
Eq<Lhs, Rhs>: UndecoratedInsertRecord<Tab>
{
}

impl<Lhs, Rhs> UndecoratedInsertRecord<Lhs::Table> for Grouped<Eq<Lhs, Rhs>> where Lhs: Column {}
impl<Lhs, Rhs> UndecoratedInsertRecord<Lhs::Source> for Grouped<Eq<Lhs, Rhs>>
where
Lhs: Column,
Lhs::Source: Table,
{
}

impl<Lhs, Rhs, Tab> UndecoratedInsertRecord<Tab> for Option<Grouped<Eq<Lhs, Rhs>>> where
Eq<Lhs, Rhs>: UndecoratedInsertRecord<Tab>
Expand Down
3 changes: 2 additions & 1 deletion diesel/src/query_builder/update_statement/changeset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,9 @@ where
impl<C> AssignmentTarget for C
where
C: Column,
C::Source: Table,
{
type Table = C::Table;
type Table = C::Source;
type QueryAstNode = ColumnWrapperForUpdate<C>;

fn into_target(self) -> Self::QueryAstNode {
Expand Down
3 changes: 2 additions & 1 deletion diesel/src/query_builder/upsert/on_conflict_actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,10 @@ where
type SqlType = T::SqlType;
}

impl<T> AppearsOnTable<T::Table> for Excluded<T>
impl<T> AppearsOnTable<T::Source> for Excluded<T>
where
T: Column,
T::Source: Table,
Excluded<T>: Expression,
{
}
Loading
Loading