pub(crate) mod prelude {
#[cfg_attr(
any(feature = "huge-tables", feature = "large-tables"),
allow(deprecated)
)]
#[allow(unreachable_pub, unused_imports)]
#[doc(inline)]
pub use crate::{
allow_columns_to_appear_in_same_group_by_clause, allow_tables_to_appear_in_same_query,
joinable, table,
};
}
#[doc(inline)]
pub use diesel_derives::table_proc as table;
#[macro_export]
macro_rules! joinable {
($($child:ident)::* -> $($parent:ident)::* ($source:ident)) => {
$crate::joinable_inner!($($child)::* ::table => $($parent)::* ::table : ($($child)::* ::$source = $($parent)::* ::table));
$crate::joinable_inner!($($parent)::* ::table => $($child)::* ::table : ($($child)::* ::$source = $($parent)::* ::table));
}
}
#[macro_export]
#[doc(hidden)]
macro_rules! joinable_inner {
($left_table:path => $right_table:path : ($foreign_key:path = $parent_table:path)) => {
$crate::joinable_inner!(
left_table_ty = $left_table,
right_table_ty = $right_table,
right_table_expr = $right_table,
foreign_key = $foreign_key,
primary_key_ty = <$parent_table as $crate::query_source::Table>::PrimaryKey,
primary_key_expr =
<$parent_table as $crate::query_source::Table>::primary_key(&$parent_table),
);
};
(
left_table_ty = $left_table_ty:ty,
right_table_ty = $right_table_ty:ty,
right_table_expr = $right_table_expr:expr,
foreign_key = $foreign_key:path,
primary_key_ty = $primary_key_ty:ty,
primary_key_expr = $primary_key_expr:expr,
) => {
impl $crate::JoinTo<$right_table_ty> for $left_table_ty {
type FromClause = $right_table_ty;
type OnClause = $crate::dsl::Eq<
$crate::internal::table_macro::NullableExpression<$foreign_key>,
$crate::internal::table_macro::NullableExpression<$primary_key_ty>,
>;
fn join_target(rhs: $right_table_ty) -> (Self::FromClause, Self::OnClause) {
use $crate::{ExpressionMethods, NullableExpressionMethods};
(
rhs,
$foreign_key.nullable().eq($primary_key_expr.nullable()),
)
}
}
};
}
#[macro_export]
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 {}
$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,)+);
};
($last_table:ident,) => {};
() => {};
}
#[doc(hidden)]
#[macro_export]
#[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>
for $crate::query_builder::Only<$right::table>
{
}
impl $crate::query_source::TableNotEqual<$right::table>
for $crate::query_builder::Only<$left::table>
{
}
impl $crate::query_source::TableNotEqual<$crate::query_builder::Only<$left::table>>
for $right::table
{
}
impl $crate::query_source::TableNotEqual<$crate::query_builder::Only<$right::table>>
for $left::table
{
}
impl<TSM> $crate::query_source::TableNotEqual<$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>
for $crate::query_builder::Tablesample<$left::table, TSM>
where
TSM: $crate::internal::table_macro::TablesampleMethod,
{
}
impl<TSM>
$crate::query_source::TableNotEqual<
$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_builder::Tablesample<$right::table, TSM>,
> for $left::table
where
TSM: $crate::internal::table_macro::TablesampleMethod,
{
}
};
}
#[doc(hidden)]
#[macro_export]
#[cfg(not(feature = "postgres_backend"))]
macro_rules! __diesel_internal_backend_specific_allow_tables_to_appear_in_same_query {
($left:ident, $right:ident) => {};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __diesel_impl_allow_in_same_group_by_clause {
(
left = [$($left_path:tt)::+],
) => {};
(
left = [$($left_path:tt)::+],
$($right_path:tt)::+
) => {
$crate::__diesel_impl_allow_in_same_group_by_clause! {
left = [$($left_path)+],
right = [$($right_path)+],
left_tbl = [],
left_path = [],
}
};
(
left = [$($left_path:tt)::+],
$($right_path:tt)::+,
$($other:tt)*
) => {
$crate::__diesel_impl_allow_in_same_group_by_clause! {
left = [$($left_path)+],
right = [$($right_path)+],
left_tbl = [],
left_path = [],
}
$crate::__diesel_impl_allow_in_same_group_by_clause! {
left = [$($left_path)::+],
$($other)*
}
};
(
left = [$left_path_p1: tt $($left_path: tt)+],
right = [$($right_path: tt)*],
left_tbl = [$($left_tbl:tt)?],
left_path = [$($left_out_path:tt)*],
) => {
$crate::__diesel_impl_allow_in_same_group_by_clause! {
left = [$($left_path)+],
right = [$($right_path)*],
left_tbl = [$left_path_p1],
left_path = [$($left_out_path)* $($left_tbl)?],
}
};
(
left = [$left_col: tt],
right = [$($right_path: tt)*],
left_tbl = [$($left_tbl:tt)?],
left_path = [$($left_out_path:tt)*],
) => {
$crate::__diesel_impl_allow_in_same_group_by_clause! {
left = [$left_col],
right = [$($right_path)*],
left_tbl = [$($left_tbl)?],
left_path = [$($left_out_path)*],
right_tbl = [],
right_path = [],
}
};
(
left = [$left_col: tt ],
right = [$right_path_p1: tt $($right_path: tt)+],
left_tbl = [$($left_tbl:tt)?],
left_path = [$($left_out_path:tt)*],
right_tbl = [$($right_tbl:tt)?],
right_path = [$($right_out_path:tt)*],
) => {
$crate::__diesel_impl_allow_in_same_group_by_clause! {
left = [$left_col],
right = [$($right_path)+],
left_tbl = [$($left_tbl)?],
left_path = [$($left_out_path)*],
right_tbl = [$right_path_p1],
right_path = [$($right_out_path)* $($right_tbl)?],
}
};
(
left = [$left_col: tt],
right = [$right_col: tt],
left_tbl = [$left_tbl:tt],
left_path = [$($left_begin:tt)*],
right_tbl = [$right_tbl:tt],
right_path = [$($right_begin:tt)*],
) => {
$crate::static_cond! {
if $left_tbl != $right_tbl {
impl $crate::expression::IsContainedInGroupBy<$($left_begin ::)* $left_tbl :: $left_col> for $($right_begin ::)* $right_tbl :: $right_col {
type Output = $crate::expression::is_contained_in_group_by::No;
}
impl $crate::expression::IsContainedInGroupBy<$($right_begin ::)* $right_tbl :: $right_col> for $($left_begin ::)* $left_tbl :: $left_col {
type Output = $crate::expression::is_contained_in_group_by::No;
}
}
}
};
(
left = [$left_col: tt],
right = [$right_col: tt],
left_tbl = [$($left_tbl:tt)?],
left_path = [$($left_begin:tt)*],
right_tbl = [$($right_tbl:tt)?],
right_path = [$($right_begin:tt)*],
) => {
impl $crate::expression::IsContainedInGroupBy<$($left_begin ::)* $($left_tbl ::)? $left_col> for $($right_begin ::)* $($right_tbl ::)? $right_col {
type Output = $crate::expression::is_contained_in_group_by::No;
}
impl $crate::expression::IsContainedInGroupBy<$($right_begin ::)* $($right_tbl ::)? $right_col> for $($left_begin ::)* $($left_tbl ::)? $left_col {
type Output = $crate::expression::is_contained_in_group_by::No;
}
};
}
#[macro_export]
macro_rules! allow_columns_to_appear_in_same_group_by_clause {
($($left_path:tt)::+, $($right_path:tt)::+ $(,)?) => {
$crate::__diesel_impl_allow_in_same_group_by_clause! {
left = [$($left_path)::+],
$($right_path)::+,
}
};
($($left_path:tt)::+, $($right_path:tt)::+, $($other: tt)*) => {
$crate::__diesel_impl_allow_in_same_group_by_clause! {
left = [$($left_path)::+],
$($right_path)::+,
$($other)*
}
$crate::allow_columns_to_appear_in_same_group_by_clause! {
$($right_path)::+,
$($other)*
}
};
($last_col:ty,) => {};
() => {};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __diesel_with_dollar_sign {
($($body:tt)*) => {
macro_rules! __with_dollar_sign { $($body)* }
__with_dollar_sign!($);
}
}
#[macro_use]
mod internal;
#[macro_use]
mod static_cond;
#[macro_use]
mod ops;
#[cfg(test)]
mod tests {
use crate::prelude::*;
table! {
foo.bars {
id -> Integer,
baz -> Text,
}
}
mod my_types {
#[derive(Debug, Clone, Copy, crate::sql_types::SqlType)]
pub struct MyCustomType;
}
table! {
use crate::sql_types::*;
use crate::macros::tests::my_types::*;
table_with_custom_types {
id -> Integer,
my_type -> MyCustomType,
}
}
table! {
use crate::sql_types::*;
use crate::macros::tests::my_types::*;
table_with_custom_type_and_id (a) {
a -> Integer,
my_type -> MyCustomType,
}
}
#[diesel_test_helper::test]
#[cfg(feature = "postgres")]
fn table_with_custom_schema() {
use crate::pg::Pg;
let expected_sql = r#"SELECT "foo"."bars"."baz" FROM "foo"."bars" -- binds: []"#;
assert_eq!(
expected_sql,
&crate::debug_query::<Pg, _>(&bars::table.select(bars::baz)).to_string()
);
}
table! {
use crate::sql_types;
use crate::sql_types::*;
table_with_arbitrarily_complex_types {
id -> sql_types::Integer,
qualified_nullable -> sql_types::Nullable<sql_types::Integer>,
deeply_nested_type -> Nullable<Nullable<Integer>>,
}
}
table!(
foo {
id -> Integer,
#[sql_name = "type"]
mytype -> Integer,
#[sql_name = "bleh"]
hey -> Integer,
}
);
#[diesel_test_helper::test]
#[cfg(feature = "postgres")]
fn table_with_column_renaming_postgres() {
use crate::pg::Pg;
let expected_sql = r#"SELECT "foo"."id", "foo"."type", "foo"."bleh" FROM "foo" WHERE ("foo"."type" = $1) -- binds: [1]"#;
assert_eq!(
expected_sql,
crate::debug_query::<Pg, _>(&foo::table.filter(foo::mytype.eq(1))).to_string()
);
}
#[diesel_test_helper::test]
#[cfg(feature = "mysql")]
fn table_with_column_renaming_mysql() {
use crate::mysql::Mysql;
let expected_sql = r#"SELECT `foo`.`id`, `foo`.`type`, `foo`.`bleh` FROM `foo` WHERE (`foo`.`type` = ?) -- binds: [1]"#;
assert_eq!(
expected_sql,
crate::debug_query::<Mysql, _>(&foo::table.filter(foo::mytype.eq(1))).to_string()
);
}
#[diesel_test_helper::test]
#[cfg(feature = "sqlite")]
fn table_with_column_renaming_sqlite() {
use crate::sqlite::Sqlite;
let expected_sql = r#"SELECT `foo`.`id`, `foo`.`type`, `foo`.`bleh` FROM `foo` WHERE (`foo`.`type` = ?) -- binds: [1]"#;
assert_eq!(
expected_sql,
crate::debug_query::<Sqlite, _>(&foo::table.filter(foo::mytype.eq(1))).to_string()
);
}
table!(
use crate::sql_types::*;
#[sql_name="mod"]
bar {
id -> Integer,
}
);
#[diesel_test_helper::test]
#[cfg(feature = "postgres")]
fn table_renaming_postgres() {
use crate::pg::Pg;
let expected_sql = r#"SELECT "mod"."id" FROM "mod" -- binds: []"#;
assert_eq!(
expected_sql,
crate::debug_query::<Pg, _>(&bar::table.select(bar::id)).to_string()
);
}
#[diesel_test_helper::test]
#[cfg(feature = "mysql")]
fn table_renaming_mysql() {
use crate::mysql::Mysql;
let expected_sql = r#"SELECT `mod`.`id` FROM `mod` -- binds: []"#;
assert_eq!(
expected_sql,
crate::debug_query::<Mysql, _>(&bar::table.select(bar::id)).to_string()
);
}
#[diesel_test_helper::test]
#[cfg(feature = "sqlite")]
fn table_renaming_sqlite() {
use crate::sqlite::Sqlite;
let expected_sql = r#"SELECT `mod`.`id` FROM `mod` -- binds: []"#;
assert_eq!(
expected_sql,
crate::debug_query::<Sqlite, _>(&bar::table.select(bar::id)).to_string()
);
}
mod tests_for_allow_combined_group_by_syntax {
use crate::table;
table! {
a(b) {
b -> Text,
c -> Text,
d -> Text,
e -> Text,
}
}
table! {
b(a) {
a -> Text,
c -> Text,
d -> Text,
}
}
table! {
c(a) {
a -> Text,
b -> Text,
d -> Text,
}
}
allow_columns_to_appear_in_same_group_by_clause!(a::b, b::a, a::d,);
allow_columns_to_appear_in_same_group_by_clause!(self::a::c, self::b::c, self::b::d,);
use self::a::d as a_d;
use self::b::d as b_d;
use self::c::d as c_d;
allow_columns_to_appear_in_same_group_by_clause!(a_d, b_d, c_d);
allow_columns_to_appear_in_same_group_by_clause!(c_d, self::b::a, a::e,);
}
}