diff --git a/CHANGELOG.md b/CHANGELOG.md index eaa59a4827d1..2402a513412e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ Increasing the minimal supported Rust version will always be coupled at least wi ### Changed * The minimal officially supported rustc version is now 1.70.0 +* Deprecated `sql_function!` in favour of `define_sql_function!` which provides compatibility with `#[dsl::auto_type]` ## [2.1.0] 2023-05-26 diff --git a/diesel/src/expression/count.rs b/diesel/src/expression/count.rs index 0a8ea4d2dbc4..e3512b22995c 100644 --- a/diesel/src/expression/count.rs +++ b/diesel/src/expression/count.rs @@ -1,6 +1,6 @@ use std::marker::PhantomData; -use super::functions::sql_function; +use super::functions::define_sql_function; use super::{is_aggregate, AsExpression}; use super::{Expression, ValidGrouping}; use crate::backend::Backend; @@ -9,7 +9,7 @@ use crate::result::QueryResult; use crate::sql_types::{BigInt, DieselNumericOps, SingleValue, SqlType}; use crate::{AppearsOnTable, SelectableExpression}; -sql_function! { +define_sql_function! { /// Creates a SQL `COUNT` expression /// /// As with most bare functions, this is not exported by default. You can import diff --git a/diesel/src/expression/exists.rs b/diesel/src/expression/exists.rs index 82779bfbc049..ff6a8d5d65cf 100644 --- a/diesel/src/expression/exists.rs +++ b/diesel/src/expression/exists.rs @@ -4,7 +4,7 @@ use crate::backend::{sql_dialect, Backend, SqlDialect}; use crate::expression::subselect::Subselect; use crate::expression::{AppearsOnTable, Expression, SelectableExpression, ValidGrouping}; -use crate::helper_types::exists; +use crate::helper_types; use crate::query_builder::*; use crate::result::QueryResult; use crate::sql_types::Bool; @@ -32,7 +32,7 @@ use crate::sql_types::Bool; /// assert_eq!(Ok(false), jim_exists); /// # } /// ``` -pub fn exists(query: T) -> exists { +pub fn exists(query: T) -> helper_types::exists { Exists { subselect: Subselect::new(query), } diff --git a/diesel/src/expression/functions/aggregate_folding.rs b/diesel/src/expression/functions/aggregate_folding.rs index fb8b9b2bd464..7d0f3732072e 100644 --- a/diesel/src/expression/functions/aggregate_folding.rs +++ b/diesel/src/expression/functions/aggregate_folding.rs @@ -1,7 +1,7 @@ -use crate::expression::functions::sql_function; +use crate::expression::functions::define_sql_function; use crate::sql_types::Foldable; -sql_function! { +define_sql_function! { /// Represents a SQL `SUM` function. This function can only take types which are /// Foldable. /// @@ -21,7 +21,7 @@ sql_function! { fn sum(expr: ST) -> ST::Sum; } -sql_function! { +define_sql_function! { /// Represents a SQL `AVG` function. This function can only take types which are /// Foldable. /// diff --git a/diesel/src/expression/functions/aggregate_ordering.rs b/diesel/src/expression/functions/aggregate_ordering.rs index aa95e1d1a64f..c36b6cc0b96b 100644 --- a/diesel/src/expression/functions/aggregate_ordering.rs +++ b/diesel/src/expression/functions/aggregate_ordering.rs @@ -1,7 +1,7 @@ use self::private::SqlOrdAggregate; -use crate::expression::functions::sql_function; +use crate::expression::functions::define_sql_function; -sql_function! { +define_sql_function! { /// Represents a SQL `MAX` function. This function can only take types which are /// ordered. /// @@ -20,7 +20,7 @@ sql_function! { fn max(expr: ST) -> ST::Ret; } -sql_function! { +define_sql_function! { /// Represents a SQL `MIN` function. This function can only take types which are /// ordered. /// diff --git a/diesel/src/expression/functions/date_and_time.rs b/diesel/src/expression/functions/date_and_time.rs index 22d51a470cec..8433d5db8524 100644 --- a/diesel/src/expression/functions/date_and_time.rs +++ b/diesel/src/expression/functions/date_and_time.rs @@ -1,6 +1,6 @@ use crate::backend::Backend; use crate::expression::coerce::Coerce; -use crate::expression::functions::sql_function; +use crate::expression::functions::define_sql_function; use crate::expression::{AsExpression, Expression, ValidGrouping}; use crate::query_builder::*; use crate::result::QueryResult; @@ -27,7 +27,7 @@ impl_selectable_expression!(now); operator_allowed!(now, Add, add); operator_allowed!(now, Sub, sub); -sql_function! { +define_sql_function! { /// Represents the SQL `DATE` function. The argument should be a Timestamp /// expression, and the return value will be an expression of type Date. /// diff --git a/diesel/src/expression/functions/helper_types.rs b/diesel/src/expression/functions/helper_types.rs index ff757c350447..4f6bd2be06ab 100644 --- a/diesel/src/expression/functions/helper_types.rs +++ b/diesel/src/expression/functions/helper_types.rs @@ -8,16 +8,16 @@ use crate::expression::operators; pub type not = operators::Not>; /// The return type of [`max(expr)`](crate::dsl::max()) -pub type max = super::aggregate_ordering::max::HelperType, Expr>; +pub type max = super::aggregate_ordering::max, Expr>; /// The return type of [`min(expr)`](crate::dsl::min()) -pub type min = super::aggregate_ordering::min::HelperType, Expr>; +pub type min = super::aggregate_ordering::min, Expr>; /// The return type of [`sum(expr)`](crate::dsl::sum()) -pub type sum = super::aggregate_folding::sum::HelperType, Expr>; +pub type sum = super::aggregate_folding::sum, Expr>; /// The return type of [`avg(expr)`](crate::dsl::avg()) -pub type avg = super::aggregate_folding::avg::HelperType, Expr>; +pub type avg = super::aggregate_folding::avg, Expr>; /// The return type of [`exists(expr)`](crate::dsl::exists()) pub type exists = crate::expression::exists::Exists; diff --git a/diesel/src/expression/functions/mod.rs b/diesel/src/expression/functions/mod.rs index f37261412495..db8f79e7a730 100644 --- a/diesel/src/expression/functions/mod.rs +++ b/diesel/src/expression/functions/mod.rs @@ -1,6 +1,10 @@ //! Helper macros to define custom sql functions #[doc(inline)] +pub use diesel_derives::define_sql_function; + +#[doc(inline)] +#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))] pub use diesel_derives::sql_function_proc as sql_function; #[macro_export] @@ -73,7 +77,7 @@ macro_rules! no_arg_sql_function_body { /// function. #[deprecated( since = "2.0.0", - note = "Use `sql_function!` instead. See `CHANGELOG.md` for migration instructions" + note = "Use `define_sql_function!` instead. See `CHANGELOG.md` for migration instructions" )] #[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))] macro_rules! no_arg_sql_function { diff --git a/diesel/src/expression/helper_types.rs b/diesel/src/expression/helper_types.rs index 5104b93a0c05..4ca14ad6daa7 100644 --- a/diesel/src/expression/helper_types.rs +++ b/diesel/src/expression/helper_types.rs @@ -26,6 +26,9 @@ pub type Eq = Grouped>>; /// [`lhs.ne(rhs)`](crate::expression_methods::ExpressionMethods::ne()) pub type NotEq = Grouped>>; +#[doc(hidden)] // required for `#[auto_type]` +pub type Ne = NotEq; + /// The return type of /// [`lhs.eq_any(rhs)`](crate::expression_methods::ExpressionMethods::eq_any()) pub type EqAny = Grouped>>::InExpression>>; @@ -35,6 +38,9 @@ pub type EqAny = Grouped pub type NeAny = Grouped>>::InExpression>>; +#[doc(hidden)] // required for `#[auto_type]` +pub type NeAll = NeAny; + /// The return type of /// [`expr.is_null()`](crate::expression_methods::ExpressionMethods::is_null()) pub type IsNull = Grouped>; @@ -51,6 +57,9 @@ pub type Gt = Grouped>>; /// [`lhs.ge(rhs)`](crate::expression_methods::ExpressionMethods::ge()) pub type GtEq = Grouped>>; +#[doc(hidden)] // required for `#[auto_type]` +pub type Ge = GtEq; + /// The return type of /// [`lhs.lt(rhs)`](crate::expression_methods::ExpressionMethods::lt()) pub type Lt = Grouped>>; @@ -59,6 +68,9 @@ pub type Lt = Grouped>>; /// [`lhs.le(rhs)`](crate::expression_methods::ExpressionMethods::le()) pub type LtEq = Grouped>>; +#[doc(hidden)] // required for `#[auto_type]` +pub type Le = LtEq; + /// The return type of /// [`lhs.between(lower, upper)`](crate::expression_methods::ExpressionMethods::between()) pub type Between = Grouped< @@ -122,12 +134,12 @@ pub type Like = Grouped = Grouped>>>; /// The return type of [`case_when()`](expression::case_when::case_when) -#[allow(non_camel_case_types)] +#[allow(non_camel_case_types)] // required for `#[auto_type]` pub type case_when::SqlType> = expression::case_when::CaseWhen< expression::case_when::CaseWhenConditionsLeaf, Grouped>>, expression::case_when::NoElseExpression, >; -/// The return type of [`case_when(...).when(...)`](expression::case_when::CaseWhen::when) +/// The return type of [`case_when(...).when(...)`](expression::CaseWhen::when) pub type When = expression::case_when::CaseWhen< expression::case_when::CaseWhenConditionsIntermediateNode< Grouped, diff --git a/diesel/src/expression/mod.rs b/diesel/src/expression/mod.rs index f54d5244a470..be3c47d2a466 100644 --- a/diesel/src/expression/mod.rs +++ b/diesel/src/expression/mod.rs @@ -53,7 +53,7 @@ pub(crate) mod dsl { use crate::dsl::SqlTypeOf; #[doc(inline)] - pub use super::case_when::*; + pub use super::case_when::case_when; #[doc(inline)] pub use super::count::*; #[doc(inline)] @@ -65,6 +65,8 @@ pub(crate) mod dsl { #[doc(inline)] pub use super::functions::date_and_time::*; #[doc(inline)] + pub use super::helper_types::{case_when, Otherwise, When}; + #[doc(inline)] pub use super::not::not; #[doc(inline)] pub use super::sql_literal::sql; @@ -73,7 +75,7 @@ pub(crate) mod dsl { pub use crate::pg::expression::dsl::*; /// The return type of [`count(expr)`](crate::dsl::count()) - pub type count = super::count::count::HelperType, Expr>; + pub type count = super::count::count, Expr>; /// The return type of [`count_star()`](crate::dsl::count_star()) pub type count_star = super::count::CountStar; @@ -82,12 +84,14 @@ pub(crate) mod dsl { pub type count_distinct = super::count::CountDistinct, Expr>; /// The return type of [`date(expr)`](crate::dsl::date()) - pub type date = super::functions::date_and_time::date::HelperType; + pub type date = super::functions::date_and_time::date; #[cfg(feature = "mysql_backend")] pub use crate::mysql::query_builder::DuplicatedKeys; } +#[doc(inline)] +pub use self::case_when::CaseWhen; #[doc(inline)] pub use self::sql_literal::{SqlLiteral, UncheckedBind}; diff --git a/diesel/src/expression/not.rs b/diesel/src/expression/not.rs index 70fa1bade423..8280dc218c3f 100644 --- a/diesel/src/expression/not.rs +++ b/diesel/src/expression/not.rs @@ -1,6 +1,6 @@ use crate::expression::grouped::Grouped; use crate::expression::Expression; -use crate::helper_types::not; +use crate::helper_types; use crate::sql_types::BoolOrNullableBool; /// Creates a SQL `NOT` expression @@ -23,7 +23,7 @@ use crate::sql_types::BoolOrNullableBool; /// assert_eq!(Ok(2), users_not_with_name.first(connection)); /// # } /// ``` -pub fn not(expr: T) -> not +pub fn not(expr: T) -> helper_types::not where T: Expression, ::SqlType: BoolOrNullableBool, diff --git a/diesel/src/expression/operators.rs b/diesel/src/expression/operators.rs index 55b1372c4e0a..718cd0d149d1 100644 --- a/diesel/src/expression/operators.rs +++ b/diesel/src/expression/operators.rs @@ -529,7 +529,6 @@ infix_operator!(Escape, " ESCAPE "); infix_operator!(Eq, " = "); infix_operator!(Gt, " > "); infix_operator!(GtEq, " >= "); -infix_operator!(Like, " LIKE "); infix_operator!(Lt, " < "); infix_operator!(LtEq, " <= "); infix_operator!(NotEq, " != "); @@ -645,3 +644,106 @@ where Ok(()) } } + +// need an explicit impl here to control which types are allowed +#[derive( + Debug, + Clone, + Copy, + crate::query_builder::QueryId, + crate::sql_types::DieselNumericOps, + crate::expression::ValidGrouping, +)] +#[doc(hidden)] +pub struct Like { + pub(crate) left: T, + pub(crate) right: U, +} + +impl Like { + pub(crate) fn new(left: T, right: U) -> Self { + Like { left, right } + } +} + +impl crate::expression::SelectableExpression for Like +where + Like: crate::expression::AppearsOnTable, + T: crate::expression::SelectableExpression, + U: crate::expression::SelectableExpression, +{ +} + +impl crate::expression::AppearsOnTable for Like +where + Like: crate::expression::Expression, + T: crate::expression::AppearsOnTable, + U: crate::expression::AppearsOnTable, +{ +} + +impl crate::expression::Expression for Like +where + T: crate::expression::Expression, + U: crate::expression::Expression, + ::SqlType: crate::sql_types::SqlType, + ::SqlType: crate::sql_types::SqlType, + crate::sql_types::is_nullable::IsSqlTypeNullable<::SqlType>: + crate::sql_types::OneIsNullable< + crate::sql_types::is_nullable::IsSqlTypeNullable< + ::SqlType, + >, + >, + crate::sql_types::is_nullable::IsOneNullable< + ::SqlType, + ::SqlType, + >: crate::sql_types::MaybeNullableType, +{ + type SqlType = crate::sql_types::is_nullable::MaybeNullable< + crate::sql_types::is_nullable::IsOneNullable< + ::SqlType, + ::SqlType, + >, + crate::sql_types::Bool, + >; +} + +impl crate::query_builder::QueryFragment for Like +where + T: crate::query_builder::QueryFragment + crate::Expression, + U: crate::query_builder::QueryFragment, + DB: crate::backend::Backend, + DB: LikeIsAllowedForType, +{ + fn walk_ast<'b>( + &'b self, + mut out: crate::query_builder::AstPass<'_, 'b, DB>, + ) -> crate::result::QueryResult<()> { + (self.left.walk_ast(out.reborrow())?); + (out.push_sql(" LIKE ")); + (self.right.walk_ast(out.reborrow())?); + Ok(()) + } +} + +impl crate::internal::operators_macro::FieldAliasMapper for Like +where + S: crate::query_source::AliasSource, + T: crate::internal::operators_macro::FieldAliasMapper, + U: crate::internal::operators_macro::FieldAliasMapper, +{ + type Out = Like< + >::Out, + >::Out, + >; + fn map(self, alias: &crate::query_source::Alias) -> Self::Out { + Like { + left: self.left.map(alias), + right: self.right.map(alias), + } + } +} + +pub trait LikeIsAllowedForType: Backend {} + +impl LikeIsAllowedForType for DB where DB: Backend {} diff --git a/diesel/src/lib.rs b/diesel/src/lib.rs index 96e0bf2817de..2a74471dd626 100644 --- a/diesel/src/lib.rs +++ b/diesel/src/lib.rs @@ -57,7 +57,7 @@ //! They live in [the `dsl` module](dsl). //! Diesel only supports a very small number of these functions. //! You can declare additional functions you want to use -//! with [the `sql_function!` macro][`sql_function!`]. +//! with [the `define_sql_function!` macro][`define_sql_function!`]. //! //! [`std::ops`]: //doc.rust-lang.org/stable/std/ops/index.html //! @@ -416,10 +416,12 @@ pub mod helper_types { pub type ThenOrderBy = >::Output; /// Represents the return type of [`.limit()`](crate::prelude::QueryDsl::limit) - pub type Limit = ::Output; + pub type Limit = + >::Output; /// Represents the return type of [`.offset()`](crate::prelude::QueryDsl::offset) - pub type Offset = ::Output; + pub type Offset = + >::Output; /// Represents the return type of [`.inner_join(rhs)`](crate::prelude::QueryDsl::inner_join) pub type InnerJoin = @@ -631,6 +633,43 @@ pub mod helper_types { #[deprecated(note = "Use `LoadQuery::RowIter` directly")] pub type LoadIter<'conn, 'query, Q, Conn, U, B = crate::connection::DefaultLoadingMode> = >::RowIter<'conn>; + + /// Represents the return type of [`diesel::delete`] + #[allow(non_camel_case_types)] // required for `#[auto_type]` + pub type delete = crate::query_builder::DeleteStatement< + ::Table, + ::WhereClause, + >; + + /// Represents the return type of [`diesel::insert_into`] + #[allow(non_camel_case_types)] // required for `#[auto_type]` + pub type insert_into = crate::query_builder::IncompleteInsertStatement; + + /// Represents the return type of [`diesel::insert_or_ignore_into`] + #[allow(non_camel_case_types)] // required for `#[auto_type]` + pub type insert_or_ignore_into = crate::query_builder::IncompleteInsertOrIgnoreStatement; + + /// Represents the return type of [`diesel::replace_into`] + #[allow(non_camel_case_types)] // required for `#[auto_type]` + pub type replace_into = crate::query_builder::IncompleteReplaceStatement; + + /// Represents the return type of + /// [`IncompleteInsertStatement::values()`](crate::query_builder::IncompleteInsertStatement::values) + pub type Values = crate::query_builder::InsertStatement< + ::Table, + ::Table, + >>::Values, + ::Op, + >; + + /// Represents the return type of + /// [`UpdateStatement::set()`](crate::query_builder::UpdateStatement::set) + pub type Set = crate::query_builder::UpdateStatement< + ::Table, + ::Where, + ::Changeset, + >; } pub mod prelude { @@ -648,6 +687,8 @@ pub mod prelude { }; #[doc(inline)] + pub use crate::expression::functions::define_sql_function; + #[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))] pub use crate::expression::functions::sql_function; #[doc(inline)] diff --git a/diesel/src/pg/backend.rs b/diesel/src/pg/backend.rs index 7b151705ab53..db18d681c8d0 100644 --- a/diesel/src/pg/backend.rs +++ b/diesel/src/pg/backend.rs @@ -4,6 +4,7 @@ use super::query_builder::PgQueryBuilder; use super::{PgMetadataLookup, PgValue}; use crate::backend::*; use crate::deserialize::Queryable; +use crate::expression::operators::LikeIsAllowedForType; use crate::pg::metadata_lookup::PgMetadataCacheKey; use crate::query_builder::bind_collector::RawBytesBindCollector; use crate::sql_types::TypeMetadata; @@ -154,3 +155,5 @@ impl sql_dialect::on_conflict_clause::PgLikeOnConflictClause for PgOnConflictCla #[derive(Debug, Copy, Clone)] pub struct PgStyleArrayComparison; + +impl LikeIsAllowedForType for Pg {} diff --git a/diesel/src/pg/connection/mod.rs b/diesel/src/pg/connection/mod.rs index f7aadf954d65..3166e5f32842 100644 --- a/diesel/src/pg/connection/mod.rs +++ b/diesel/src/pg/connection/mod.rs @@ -584,7 +584,7 @@ mod tests { assert_eq!(2, connection.statement_cache.len()); } - sql_function!(fn lower(x: VarChar) -> VarChar); + define_sql_function!(fn lower(x: VarChar) -> VarChar); #[test] fn queries_with_identical_types_and_binds_but_different_sql_are_cached_separately() { diff --git a/diesel/src/pg/expression/expression_methods.rs b/diesel/src/pg/expression/expression_methods.rs index bc34c468de16..d1d4ed376649 100644 --- a/diesel/src/pg/expression/expression_methods.rs +++ b/diesel/src/pg/expression/expression_methods.rs @@ -8,10 +8,10 @@ use super::date_and_time::{AtTimeZone, DateTimeLike}; use super::operators::*; use crate::dsl; use crate::expression::grouped::Grouped; -use crate::expression::operators::{Asc, Desc}; +use crate::expression::operators::{Asc, Concat, Desc, Like, NotLike}; use crate::expression::{AsExpression, Expression, IntoSql, TypedExpressionType}; use crate::pg::expression::expression_methods::private::BinaryOrNullableBinary; -use crate::sql_types::{Array, Binary, Inet, Integer, Jsonb, SqlType, Text, VarChar}; +use crate::sql_types::{Array, Inet, Integer, SqlType, Text, VarChar}; use crate::EscapeExpressionMethods; /// PostgreSQL specific methods which are present on all expressions. @@ -253,7 +253,7 @@ pub trait PgArrayExpressionMethods: Expression + Sized { /// # Ok(()) /// # } /// ``` - fn contains(self, other: T) -> dsl::ArrayContains + fn contains(self, other: T) -> dsl::Contains where Self::SqlType: SqlType, T: AsExpression, @@ -363,7 +363,7 @@ pub trait PgArrayExpressionMethods: Expression + Sized { /// # Ok(()) /// # } /// ``` - fn index(self, other: T) -> dsl::ArrayIndex + fn index(self, other: T) -> dsl::Index where Self::SqlType: SqlType, T: AsExpression, @@ -409,12 +409,12 @@ pub trait PgArrayExpressionMethods: Expression + Sized { /// # Ok(()) /// # } /// - fn concat(self, other: T) -> dsl::ConcatArray + fn concat(self, other: T) -> dsl::Concat where Self::SqlType: SqlType, T: AsExpression, { - Grouped(ConcatArray::new(self, other.as_expression())) + Grouped(Concat::new(self, other.as_expression())) } } @@ -1303,11 +1303,12 @@ pub trait PgJsonbExpressionMethods: Expression + Sized { /// # Ok(()) /// # } /// ``` - fn concat(self, other: T) -> dsl::ConcatJsonb + fn concat(self, other: T) -> dsl::Concat where - T: AsExpression, + Self::SqlType: SqlType, + T: AsExpression, { - Grouped(ConcatJsonb::new(self, other.as_expression())) + Grouped(Concat::new(self, other.as_expression())) } /// Creates a PostgreSQL `?` expression. @@ -1546,11 +1547,12 @@ pub trait PgJsonbExpressionMethods: Expression + Sized { /// # Ok(()) /// # } /// ``` - fn contains(self, other: T) -> dsl::ContainsJsonb + fn contains(self, other: T) -> dsl::Contains where - T: AsExpression, + Self::SqlType: SqlType, + T: AsExpression, { - Grouped(ContainsJsonb::new(self, other.as_expression())) + Grouped(Contains::new(self, other.as_expression())) } /// Creates a PostgreSQL `<@` expression. @@ -1611,11 +1613,12 @@ pub trait PgJsonbExpressionMethods: Expression + Sized { /// # } /// ``` #[allow(clippy::wrong_self_convention)] // This is named after the sql operator - fn is_contained_by(self, other: T) -> dsl::IsContainedByJsonb + fn is_contained_by(self, other: T) -> dsl::IsContainedBy where - T: AsExpression, + Self::SqlType: SqlType, + T: AsExpression, { - Grouped(IsContainedByJsonb::new(self, other.as_expression())) + Grouped(IsContainedBy::new(self, other.as_expression())) } /// Creates a PostgreSQL `-` expression. @@ -2277,12 +2280,12 @@ pub trait PgBinaryExpressionMethods: Expression + Sized { /// assert_eq!(Ok(expected_names), names); /// # } /// ``` - fn concat(self, other: T) -> dsl::ConcatBinary + fn concat(self, other: T) -> dsl::Concat where Self::SqlType: SqlType, - T: AsExpression, + T: AsExpression, { - Grouped(ConcatBinary::new(self, other.as_expression())) + Grouped(Concat::new(self, other.as_expression())) } /// Creates a PostgreSQL binary `LIKE` expression. @@ -2327,12 +2330,12 @@ pub trait PgBinaryExpressionMethods: Expression + Sized { /// assert_eq!(Ok(vec![b"Sean".to_vec()]), starts_with_s); /// # } /// ``` - fn like(self, other: T) -> dsl::LikeBinary + fn like(self, other: T) -> dsl::Like where Self::SqlType: SqlType, - T: AsExpression, + T: AsExpression, { - Grouped(LikeBinary::new(self, other.as_expression())) + Grouped(Like::new(self, other.as_expression())) } /// Creates a PostgreSQL binary `LIKE` expression. @@ -2377,12 +2380,12 @@ pub trait PgBinaryExpressionMethods: Expression + Sized { /// assert_eq!(Ok(vec![b"Tess".to_vec()]), starts_with_s); /// # } /// ``` - fn not_like(self, other: T) -> dsl::NotLikeBinary + fn not_like(self, other: T) -> dsl::NotLike where Self::SqlType: SqlType, - T: AsExpression, + T: AsExpression, { - Grouped(NotLikeBinary::new(self, other.as_expression())) + Grouped(NotLike::new(self, other.as_expression())) } } @@ -2394,7 +2397,7 @@ where { } -mod private { +pub(in crate::pg) mod private { use crate::sql_types::{ Array, Binary, Cidr, Inet, Integer, Json, Jsonb, Nullable, Range, SqlType, Text, }; diff --git a/diesel/src/pg/expression/functions.rs b/diesel/src/pg/expression/functions.rs index 254856268564..b1593dfe16f6 100644 --- a/diesel/src/pg/expression/functions.rs +++ b/diesel/src/pg/expression/functions.rs @@ -1,61 +1,61 @@ //! PostgreSQL specific functions use super::expression_methods::InetOrCidr; -use crate::expression::functions::sql_function; +use crate::expression::functions::define_sql_function; use crate::sql_types::*; -sql_function! { +define_sql_function! { /// Creates an abbreviated display format as text. #[cfg(feature = "postgres_backend")] fn abbrev(addr: T) -> Text; } -sql_function! { +define_sql_function! { /// Computes the broadcast address for the address's network. #[cfg(feature = "postgres_backend")] fn broadcast(addr: T) -> Inet; } -sql_function! { +define_sql_function! { /// Returns the address's family: 4 for IPv4, 6 for IPv6. #[cfg(feature = "postgres_backend")] fn family(addr: T) -> Integer; } -sql_function! { +define_sql_function! { /// Returns the IP address as text, ignoring the netmask. #[cfg(feature = "postgres_backend")] fn host(addr: T) -> Text; } -sql_function! { +define_sql_function! { /// Computes the host mask for the address's network. #[cfg(feature = "postgres_backend")] fn hostmask(addr: T) -> Inet; } -sql_function! { +define_sql_function! { /// Computes the smallest network that includes both of the given networks. #[cfg(feature = "postgres_backend")] fn inet_merge(a: T, b: U) -> Cidr; } -sql_function! { +define_sql_function! { /// Tests whether the addresses belong to the same IP family. #[cfg(feature = "postgres_backend")] fn inet_same_family(a: T, b: U) -> Bool; } -sql_function! { +define_sql_function! { /// Returns the netmask length in bits. #[cfg(feature = "postgres_backend")] fn masklen(addr: T) -> Integer; } -sql_function! { +define_sql_function! { /// Computes the network mask for the address's network. #[cfg(feature = "postgres_backend")] fn netmask(addr: T) -> Inet; } -sql_function! { +define_sql_function! { /// Returns the network part of the address, zeroing out whatever is to the right of the /// netmask. (This is equivalent to casting the value to cidr.) #[cfg(feature = "postgres_backend")] fn network(addr: T) -> Cidr; } -sql_function! { +define_sql_function! { /// Sets the netmask length for an inet or cidr value. /// For inet, the address part does not changes. For cidr, address bits to the right of the new /// netmask are set to zero. diff --git a/diesel/src/pg/expression/helper_types.rs b/diesel/src/pg/expression/helper_types.rs index a8ba9570419b..c205e1d157a9 100644 --- a/diesel/src/pg/expression/helper_types.rs +++ b/diesel/src/pg/expression/helper_types.rs @@ -1,15 +1,21 @@ use crate::dsl::{AsExpr, AsExprOf, SqlTypeOf}; use crate::expression::grouped::Grouped; +use crate::expression::Expression; +use crate::pg::expression::expression_methods::private::{JsonIndex, JsonRemoveIndex}; use crate::pg::types::sql_types::Array; -use crate::sql_types::{Binary, Inet, Integer, Jsonb, VarChar}; +use crate::sql_types::{Inet, Integer, VarChar}; /// The return type of [`lhs.ilike(rhs)`](super::expression_methods::PgTextExpressionMethods::ilike) #[cfg(feature = "postgres_backend")] pub type ILike = Grouped>>; +#[doc(hidden)] // required for #[auto_type] +pub type Ilike = ILike; /// The return type of [`lhs.not_ilike(rhs)`](super::expression_methods::PgTextExpressionMethods::not_ilike) #[cfg(feature = "postgres_backend")] pub type NotILike = Grouped>>; +#[doc(hidden)] // required for #[auto_type] +pub type NotIlike = NotILike; /// The return type of [`lhs.similar_to(rhs)`](super::expression_methods::PgTextExpressionMethods::similar_to) #[cfg(feature = "postgres_backend")] @@ -37,7 +43,11 @@ pub type OverlapsWith = Grouped = Grouped>>; +pub type Contains = Grouped>>; + +#[doc(hidden)] +#[deprecated(note = "Use `Contains` instead")] +pub type ArrayContains = Contains; /// The return type of [`lhs.contains(rhs)`](super::expression_methods::PgRangeExpressionMethods::contains) /// for range expressions @@ -76,6 +86,9 @@ pub type ContainsNet = Grouped = Grouped>>; +#[doc(hidden)] // used by `#[auto_type]` +pub type ContainsOrEq = ContainsNetLoose; + /// The return type of [`lhs.is_contained_by(rhs)`]((super::expression_methods::PgNetExpressionMethods::is_contained_by) /// for network types #[cfg(feature = "postgres_backend")] @@ -87,6 +100,9 @@ pub type IsContainedByNet = pub type IsContainedByNetLoose = Grouped>>; +#[doc(hidden)] // is used by `#[auto_type]` +pub type IsContainedByOrEq = IsContainedByNetLoose; + /// The return type of [`lhs.overlaps_with(rhs)`](super::expression_methods::PgNetExpressionMethods::overlaps_with) /// for network types #[cfg(feature = "postgres_backend")] @@ -106,85 +122,125 @@ pub type OrNet = Grouped = Grouped>>; -/// The return type of [`lsh.concat(rhs)`](super::expression_methods::PgJsonbExpressionMethods::concat) -#[cfg(feature = "postgres_backend")] -pub type ConcatJsonb = Grouped>>; +#[doc(hidden)] // used by `#[auto_type]` +pub type Diff = DifferenceNet; + +#[doc(hidden)] +#[deprecated(note = "Use `dsl::Concat` instead")] +pub type ConcatJsonb = crate::dsl::Concat; /// The return type of [`lsh.has_key(rhs)`](super::expression_methods::PgJsonbExpressionMethods::has_key) #[cfg(feature = "postgres_backend")] pub type HasKeyJsonb = Grouped>>; +#[doc(hidden)] // needed for `#[auto_type]` +pub type HasKey = HasKeyJsonb; + /// The return type of [`lsh.has_any_key(rhs)`](super::expression_methods::PgJsonbExpressionMethods::has_any_key) #[cfg(feature = "postgres_backend")] pub type HasAnyKeyJsonb = Grouped>>>; +#[doc(hidden)] // needed for `#[auto_type]` +pub type HasAnyKey = HasAnyKeyJsonb; + /// The return type of [`lsh.has_all_keys(rhs)`](super::expression_methods::PgJsonbExpressionMethods::has_all_keys) #[cfg(feature = "postgres_backend")] pub type HasAllKeysJsonb = Grouped>>>; -/// The return type of [`lsh.contains(rhs)`](super::expression_methods::PgJsonbExpressionMethods::contains) -/// for jsonb types -#[cfg(feature = "postgres_backend")] -pub type ContainsJsonb = - Grouped>>; +#[doc(hidden)] // needed for `#[auto_type]` +pub type HasAllKeys = HasAllKeysJsonb; -/// The return type of [`lsh.is_contained_by(rhs)`](super::expression_methods::PgJsonbExpressionMethods::is_contained_by) -/// for jsonb types -#[cfg(feature = "postgres_backend")] -pub type IsContainedByJsonb = - Grouped>>; +#[doc(hidden)] +#[deprecated(note = "Use `dsl::Contains` instead")] +pub type ContainsJsonb = Contains; + +#[doc(hidden)] +#[deprecated(note = "Use `dsl::IsContainedBy` instead")] +pub type IsContainedByJsonb = IsContainedBy; /// The return type of [`lhs.index(rhs)`](super::expression_methods::PgArrayExpressionMethods::index) #[cfg(feature = "postgres_backend")] -pub type ArrayIndex = super::operators::ArrayIndex>; +pub type Index = super::operators::ArrayIndex>; + +#[doc(hidden)] +#[deprecated(note = "Use `Index` instead")] +pub type ArrayIndex = Index; /// The return type of [`lhs.remove(rhs)`](super::expression_methods::PgJsonbExpressionMethods::remove) #[cfg(feature = "postgres_backend")] pub type RemoveFromJsonb = Grouped>>; +#[doc(hidden)] // needed for `#[auto_type]` +pub type Remove = RemoveFromJsonb< + Lhs, + ::Expression, + <::Expression as Expression>::SqlType, +>; + /// The return type of [`lhs.retrieve_as_object(rhs)`](super::expression_methods::PgAnyJsonExpressionMethods::retrieve_as_object) #[cfg(feature = "postgres_backend")] pub type RetrieveAsObjectJson = Grouped>>; +#[doc(hidden)] // needed for `#[auto_type]` +pub type RetrieveAsObject = RetrieveAsObjectJson< + Lhs, + ::Expression, + <::Expression as Expression>::SqlType, +>; + /// The return type of [`lhs.retrieve_as_text(rhs)`](super::expression_methods::PgAnyJsonExpressionMethods::retrieve_as_text) #[cfg(feature = "postgres_backend")] pub type RetrieveAsTextJson = Grouped>>; +#[doc(hidden)] // needed for `#[auto_type]` +pub type RetrieveAsText = RetrieveAsTextJson< + Lhs, + ::Expression, + <::Expression as Expression>::SqlType, +>; + /// The return type of [`lhs.retrieve_by_path_as_object(rhs)`](super::expression_methods::PgAnyJsonExpressionMethods::retrieve_by_path_as_object) #[cfg(feature = "postgres_backend")] pub type RetrieveByPathAsObjectJson = Grouped>>>; +#[doc(hidden)] // needed for `#[auto_type]` +pub type RetrieveByPathAsObject = RetrieveByPathAsObjectJson; + /// The return type of [`lhs.retrieve_by_path_as_text(rhs)`](super::expression_methods::PgAnyJsonExpressionMethods::retrieve_by_path_as_text) #[cfg(feature = "postgres_backend")] pub type RetrieveByPathAsTextJson = Grouped>>>; +#[doc(hidden)] // needed for `#[auto_type]` +pub type RetrieveByPathAsText = RetrieveByPathAsTextJson; + /// The return type of [`lhs.remove_by_path(rhs)`](super::expression_methods::PgJsonbExpressionMethods::remove_by_path) #[cfg(feature = "postgres_backend")] pub type RemoveByPathFromJsonb = Grouped>>>; -/// The return type of [`lhs.remove_by_path(rhs)`](super::expression_methods::PgBinaryExpressionMethods::concat) -#[cfg(feature = "postgres_backend")] -pub type ConcatBinary = - Grouped>>; +#[doc(hidden)] // needed for `#[auto_type]` +pub type RemoveByPath = RemoveByPathFromJsonb; -/// The return type of [`lhs.remove_by_path(rhs)`](super::expression_methods::PgBinaryExpressionMethods::like) -#[cfg(feature = "postgres_backend")] -pub type LikeBinary = Grouped>>; +#[doc(hidden)] +#[deprecated(note = "Use `dsl::Concat` instead")] +pub type ConcatBinary = crate::dsl::Concat; -/// The return type of [`lhs.remove_by_path(rhs)`](super::expression_methods::PgBinaryExpressionMethods::not_like) -#[cfg(feature = "postgres_backend")] -pub type NotLikeBinary = - Grouped>>; +#[doc(hidden)] +#[deprecated(note = "Use `dsl::Like` instead")] +pub type LikeBinary = crate::dsl::Like; -/// The return type of [`lhs.concat(rhs)`](super::expression_methods::PgArrayExpressionMethods::concat) -#[cfg(feature = "postgres_backend")] -pub type ConcatArray = Grouped>>; +#[doc(hidden)] +#[deprecated(note = "Use `dsl::NotLike` instead")] +pub type NotLikeBinary = crate::dsl::NotLike; + +#[doc(hidden)] +#[deprecated(note = "Use `dsl::Concat` instead")] +pub type ConcatArray = crate::dsl::Concat; diff --git a/diesel/src/pg/expression/operators.rs b/diesel/src/pg/expression/operators.rs index a7220cbfb95e..8d7b834f29e8 100644 --- a/diesel/src/pg/expression/operators.rs +++ b/diesel/src/pg/expression/operators.rs @@ -5,7 +5,7 @@ use crate::pg::Pg; use crate::query_builder::update_statement::changeset::AssignmentTarget; use crate::query_builder::{AstPass, QueryFragment, QueryId}; use crate::sql_types::{ - Array, Bigint, Binary, Bool, DieselNumericOps, Inet, Integer, Jsonb, SqlType, Text, + Array, Bigint, Bool, DieselNumericOps, Inet, Integer, Jsonb, SqlType, Text, }; use crate::{Column, QueryResult}; @@ -27,12 +27,9 @@ infix_operator!(IsContainedByNetLoose, " <<= ", backend: Pg); infix_operator!(AndNet, " & ", Inet, backend: Pg); infix_operator!(OrNet, " | ", Inet, backend: Pg); infix_operator!(DifferenceNet, " - ", Bigint, backend: Pg); -infix_operator!(ConcatJsonb, " || ", Jsonb, backend: Pg); infix_operator!(HasKeyJsonb, " ? ", backend: Pg); infix_operator!(HasAnyKeyJsonb, " ?| ", backend: Pg); infix_operator!(HasAllKeysJsonb, " ?& ", backend: Pg); -infix_operator!(ContainsJsonb, " @> ", backend: Pg); -infix_operator!(IsContainedByJsonb, " <@ ", backend: Pg); infix_operator!(RemoveFromJsonb, " - ", Jsonb, backend: Pg); __diesel_infix_operator!( RetrieveAsObjectJson, @@ -49,15 +46,6 @@ __diesel_infix_operator!( ); infix_operator!(RetrieveByPathAsTextJson, " #>> ", Text, backend: Pg); infix_operator!(RemoveByPathFromJsonb, " #-", Jsonb, backend: Pg); -infix_operator!(ConcatBinary, " || ", Binary, backend: Pg); -infix_operator!(LikeBinary, " LIKE ", backend: Pg); -infix_operator!(NotLikeBinary, " NOT LIKE ", backend: Pg); -__diesel_infix_operator!( - ConcatArray, - " || ", - __diesel_internal_SameResultAsInput, - backend: Pg -); #[derive(Debug, Clone, Copy, QueryId, DieselNumericOps, ValidGrouping)] #[doc(hidden)] diff --git a/diesel/src/pg/metadata_lookup.rs b/diesel/src/pg/metadata_lookup.rs index bf08a9d2706e..7e09c643fd5d 100644 --- a/diesel/src/pg/metadata_lookup.rs +++ b/diesel/src/pg/metadata_lookup.rs @@ -214,4 +214,4 @@ table! { joinable!(pg_type -> pg_namespace(typnamespace)); allow_tables_to_appear_in_same_query!(pg_type, pg_namespace); -sql_function! { fn pg_my_temp_schema() -> Oid; } +define_sql_function! { fn pg_my_temp_schema() -> Oid; } diff --git a/diesel/src/query_builder/ast_pass.rs b/diesel/src/query_builder/ast_pass.rs index 9e4de8fc37ed..f1bf8c2a1d45 100644 --- a/diesel/src/query_builder/ast_pass.rs +++ b/diesel/src/query_builder/ast_pass.rs @@ -256,7 +256,7 @@ where #[cfg_attr( not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"), doc(hidden) - )] // This is used by the `sql_function` macro + )] // This is used by the `define_sql_function` macro #[cfg_attr( doc_cfg, doc(cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")) diff --git a/diesel/src/query_builder/insert_statement/mod.rs b/diesel/src/query_builder/insert_statement/mod.rs index dc7c2667d393..fd992de0c27b 100644 --- a/diesel/src/query_builder/insert_statement/mod.rs +++ b/diesel/src/query_builder/insert_statement/mod.rs @@ -18,6 +18,8 @@ use crate::query_source::{Column, Table}; use crate::{insertable::*, QuerySource}; use std::marker::PhantomData; +pub(crate) use self::private::InsertAutoTypeHelper; + #[cfg(feature = "sqlite")] mod insert_with_default_for_sqlite; @@ -537,4 +539,16 @@ mod private { Ok(()) } } + + // otherwise rustc complains at a different location that this trait is more private than the other item that uses it + #[allow(unreachable_pub)] + pub trait InsertAutoTypeHelper { + type Table; + type Op; + } + + impl InsertAutoTypeHelper for crate::query_builder::IncompleteInsertStatement { + type Table = T; + type Op = Op; + } } diff --git a/diesel/src/query_builder/update_statement/mod.rs b/diesel/src/query_builder/update_statement/mod.rs index d3df633abf2e..b234d35cc03a 100644 --- a/diesel/src/query_builder/update_statement/mod.rs +++ b/diesel/src/query_builder/update_statement/mod.rs @@ -14,6 +14,8 @@ use crate::query_source::Table; use crate::result::Error::QueryBuilderError; use crate::{query_builder::*, QuerySource}; +pub(crate) use self::private::UpdateAutoTypeHelper; + impl UpdateStatement { pub(crate) fn new(target: UpdateTarget) -> Self { UpdateStatement { @@ -287,3 +289,20 @@ impl UpdateStatement { /// Indicates that you have not yet called `.set` on an update statement #[derive(Debug, Clone, Copy)] pub struct SetNotCalled; + +mod private { + // otherwise rustc complains at a different location that this trait is more private than the other item that uses it + #[allow(unreachable_pub)] + pub trait UpdateAutoTypeHelper { + type Table; + type Where; + } + + impl UpdateAutoTypeHelper for crate::query_builder::UpdateStatement + where + T: crate::QuerySource, + { + type Table = T; + type Where = W; + } +} diff --git a/diesel/src/query_dsl/limit_dsl.rs b/diesel/src/query_dsl/limit_dsl.rs index 4f8b823c39b7..3aa73662fe47 100644 --- a/diesel/src/query_dsl/limit_dsl.rs +++ b/diesel/src/query_dsl/limit_dsl.rs @@ -7,7 +7,7 @@ use crate::query_source::Table; /// to call `limit` from generic code. /// /// [`QueryDsl`]: crate::QueryDsl -pub trait LimitDsl { +pub trait LimitDsl { /// The type returned by `.limit` type Output; diff --git a/diesel/src/query_dsl/offset_dsl.rs b/diesel/src/query_dsl/offset_dsl.rs index 0d783edfa478..fa625546357a 100644 --- a/diesel/src/query_dsl/offset_dsl.rs +++ b/diesel/src/query_dsl/offset_dsl.rs @@ -7,7 +7,7 @@ use crate::query_source::Table; /// to call `offset` from generic code. /// /// [`QueryDsl`]: crate::QueryDsl -pub trait OffsetDsl { +pub trait OffsetDsl { /// The type returned by `.offset`. type Output; diff --git a/diesel/src/sqlite/connection/mod.rs b/diesel/src/sqlite/connection/mod.rs index 05f7cc1f1c4d..8151ee0d12cb 100644 --- a/diesel/src/sqlite/connection/mod.rs +++ b/diesel/src/sqlite/connection/mod.rs @@ -20,6 +20,7 @@ use self::raw::RawConnection; use self::statement_iterator::*; use self::stmt::{Statement, StatementUse}; use super::SqliteAggregateFunction; +use crate::connection::instrumentation::InstrumentationEvent; use crate::connection::instrumentation::StrQueryHelper; use crate::connection::statement_cache::StatementCache; use crate::connection::*; @@ -633,12 +634,12 @@ mod tests { } use crate::sql_types::Text; - sql_function!(fn fun_case(x: Text) -> Text); + define_sql_function!(fn fun_case(x: Text) -> Text); #[test] fn register_custom_function() { let connection = &mut SqliteConnection::establish(":memory:").unwrap(); - fun_case::register_impl(connection, |x: String| { + fun_case_utils::register_impl(connection, |x: String| { x.chars() .enumerate() .map(|(i, c)| { @@ -658,23 +659,23 @@ mod tests { assert_eq!("fOoBaR", mapped_string); } - sql_function!(fn my_add(x: Integer, y: Integer) -> Integer); + define_sql_function!(fn my_add(x: Integer, y: Integer) -> Integer); #[test] fn register_multiarg_function() { let connection = &mut SqliteConnection::establish(":memory:").unwrap(); - my_add::register_impl(connection, |x: i32, y: i32| x + y).unwrap(); + my_add_utils::register_impl(connection, |x: i32, y: i32| x + y).unwrap(); let added = crate::select(my_add(1, 2)).get_result::(connection); assert_eq!(Ok(3), added); } - sql_function!(fn answer() -> Integer); + define_sql_function!(fn answer() -> Integer); #[test] fn register_noarg_function() { let connection = &mut SqliteConnection::establish(":memory:").unwrap(); - answer::register_impl(connection, || 42).unwrap(); + answer_utils::register_impl(connection, || 42).unwrap(); let answer = crate::select(answer()).get_result::(connection); assert_eq!(Ok(42), answer); @@ -683,19 +684,19 @@ mod tests { #[test] fn register_nondeterministic_noarg_function() { let connection = &mut SqliteConnection::establish(":memory:").unwrap(); - answer::register_nondeterministic_impl(connection, || 42).unwrap(); + answer_utils::register_nondeterministic_impl(connection, || 42).unwrap(); let answer = crate::select(answer()).get_result::(connection); assert_eq!(Ok(42), answer); } - sql_function!(fn add_counter(x: Integer) -> Integer); + define_sql_function!(fn add_counter(x: Integer) -> Integer); #[test] fn register_nondeterministic_function() { let connection = &mut SqliteConnection::establish(":memory:").unwrap(); let mut y = 0; - add_counter::register_nondeterministic_impl(connection, move |x: i32| { + add_counter_utils::register_nondeterministic_impl(connection, move |x: i32| { y += 1; x + y }) @@ -706,7 +707,7 @@ mod tests { assert_eq!(Ok((2, 3, 4)), added); } - sql_function! { + define_sql_function! { #[aggregate] fn my_sum(expr: Integer) -> Integer; } @@ -749,7 +750,7 @@ mod tests { .execute(connection) .unwrap(); - my_sum::register_impl::(connection).unwrap(); + my_sum_utils::register_impl::(connection).unwrap(); let result = my_sum_example .select(my_sum(value)) @@ -768,7 +769,7 @@ mod tests { .execute(connection) .unwrap(); - my_sum::register_impl::(connection).unwrap(); + my_sum_utils::register_impl::(connection).unwrap(); let result = my_sum_example .select(my_sum(value)) @@ -776,7 +777,7 @@ mod tests { assert_eq!(Ok(0), result); } - sql_function! { + define_sql_function! { #[aggregate] fn range_max(expr1: Integer, expr2: Integer, expr3: Integer) -> Nullable; } @@ -840,7 +841,7 @@ mod tests { .execute(connection) .unwrap(); - range_max::register_impl::, _, _, _>(connection).unwrap(); + range_max_utils::register_impl::, _, _, _>(connection).unwrap(); let result = range_max_example .select(range_max(value1, value2, value3)) .get_result::>(connection) diff --git a/diesel/src/sqlite/mod.rs b/diesel/src/sqlite/mod.rs index 6a9fbbe9fc58..45cabe6f86c4 100644 --- a/diesel/src/sqlite/mod.rs +++ b/diesel/src/sqlite/mod.rs @@ -21,9 +21,9 @@ pub use self::query_builder::SqliteQueryBuilder; /// Trait for the implementation of a SQLite aggregate function /// -/// This trait is to be used in conjunction with the `sql_function!` +/// This trait is to be used in conjunction with the `define_sql_function!` /// macro for defining a custom SQLite aggregate function. See -/// the documentation [there](super::prelude::sql_function!) for details. +/// the documentation [there](super::prelude::define_sql_function!) for details. pub trait SqliteAggregateFunction: Default { /// The result type of the SQLite aggregate function type Output; diff --git a/diesel/src/sqlite/types/date_and_time/chrono.rs b/diesel/src/sqlite/types/date_and_time/chrono.rs index d6aa1bcad41a..a8df1a0099e8 100644 --- a/diesel/src/sqlite/types/date_and_time/chrono.rs +++ b/diesel/src/sqlite/types/date_and_time/chrono.rs @@ -250,9 +250,9 @@ mod tests { use crate::sql_types::{Text, Time, Timestamp, TimestamptzSqlite}; use crate::test_helpers::connection; - sql_function!(fn datetime(x: Text) -> Timestamp); - sql_function!(fn time(x: Text) -> Time); - sql_function!(fn date(x: Text) -> Date); + define_sql_function!(fn datetime(x: Text) -> Timestamp); + define_sql_function!(fn time(x: Text) -> Time); + define_sql_function!(fn date(x: Text) -> Date); #[test] fn unix_epoch_encodes_correctly() { diff --git a/diesel/src/sqlite/types/date_and_time/time.rs b/diesel/src/sqlite/types/date_and_time/time.rs index 3995f39c459e..ae2475f65bcc 100644 --- a/diesel/src/sqlite/types/date_and_time/time.rs +++ b/diesel/src/sqlite/types/date_and_time/time.rs @@ -275,9 +275,9 @@ mod tests { use crate::sql_types::{Text, Time, Timestamp, TimestamptzSqlite}; use crate::test_helpers::connection; - sql_function!(fn datetime(x: Text) -> Timestamp); - sql_function!(fn time(x: Text) -> Time); - sql_function!(fn date(x: Text) -> Date); + define_sql_function!(fn datetime(x: Text) -> Timestamp); + define_sql_function!(fn time(x: Text) -> Time); + define_sql_function!(fn date(x: Text) -> Date); #[test] fn unix_epoch_encodes_correctly() { diff --git a/diesel_cli/src/infer_schema_internals/information_schema.rs b/diesel_cli/src/infer_schema_internals/information_schema.rs index 6c762de91db7..44d8775ac900 100644 --- a/diesel_cli/src/infer_schema_internals/information_schema.rs +++ b/diesel_cli/src/infer_schema_internals/information_schema.rs @@ -31,7 +31,7 @@ impl DefaultSchema for Pg { } #[cfg(feature = "mysql")] -sql_function!(fn database() -> VarChar); +define_sql_function!(fn database() -> VarChar); #[cfg(feature = "mysql")] impl DefaultSchema for Mysql { diff --git a/diesel_cli/src/infer_schema_internals/mysql.rs b/diesel_cli/src/infer_schema_internals/mysql.rs index f549c66657b9..0a46e460aad5 100644 --- a/diesel_cli/src/infer_schema_internals/mysql.rs +++ b/diesel_cli/src/infer_schema_internals/mysql.rs @@ -10,7 +10,7 @@ use super::information_schema::DefaultSchema; use super::table_data::TableName; use crate::print_schema::ColumnSorting; -diesel::sql_function! { +diesel::define_sql_function! { #[sql_name = "NULLIF"] fn null_if_text(lhs: sql_types::Text, rhs: sql_types::Text) -> sql_types::Nullable } diff --git a/diesel_cli/src/infer_schema_internals/pg.rs b/diesel_cli/src/infer_schema_internals/pg.rs index 779fa12c8c3d..e991129aa592 100644 --- a/diesel_cli/src/infer_schema_internals/pg.rs +++ b/diesel_cli/src/infer_schema_internals/pg.rs @@ -70,7 +70,7 @@ fn regclass(table: &TableName) -> Regclass> { )) } -diesel::sql_function!(fn col_description(table: sql_types::Oid, column_number: sql_types::BigInt) -> sql_types::Nullable); +diesel::define_sql_function!(fn col_description(table: sql_types::Oid, column_number: sql_types::BigInt) -> sql_types::Nullable); pub fn get_table_data( conn: &mut PgConnection, @@ -139,7 +139,7 @@ where } } -sql_function!(fn obj_description(oid: sql_types::Oid, catalog: sql_types::Text) -> Nullable); +define_sql_function!(fn obj_description(oid: sql_types::Oid, catalog: sql_types::Text) -> Nullable); pub fn get_table_comment( conn: &mut PgConnection, @@ -166,7 +166,7 @@ mod information_schema { } } -sql_function! { +define_sql_function! { #[aggregate] fn array_agg(input: diesel::sql_types::Text) -> diesel::sql_types::Array; } diff --git a/diesel_compile_tests/tests/fail/aggregate_expression_requires_column_from_same_table.stderr b/diesel_compile_tests/tests/fail/aggregate_expression_requires_column_from_same_table.stderr index 1d0a7f863b7e..5a4d9ceff83c 100644 --- a/diesel_compile_tests/tests/fail/aggregate_expression_requires_column_from_same_table.stderr +++ b/diesel_compile_tests/tests/fail/aggregate_expression_requires_column_from_same_table.stderr @@ -13,8 +13,8 @@ error[E0277]: Cannot select `posts::columns::id` from `users::table` >> >> >> - = note: required for `diesel::expression::functions::aggregate_folding::sum::sum` to implement `SelectableExpression` - = note: required for `SelectStatement>` to implement `SelectDsl>` + = note: required for `diesel::expression::functions::aggregate_folding::sum_utils::sum` to implement `SelectableExpression` + = note: required for `SelectStatement>` to implement `SelectDsl>` error[E0271]: type mismatch resolving `>::Count == Once` --> tests/fail/aggregate_expression_requires_column_from_same_table.rs:20:31 @@ -28,9 +28,9 @@ note: required for `posts::columns::id` to implement `AppearsOnTable Integer, | ^^ = note: 1 redundant requirement hidden - = note: required for `diesel::expression::functions::aggregate_folding::sum::sum` to implement `AppearsOnTable` - = note: required for `diesel::expression::functions::aggregate_folding::sum::sum` to implement `SelectableExpression` - = note: required for `SelectStatement>` to implement `SelectDsl>` + = note: required for `diesel::expression::functions::aggregate_folding::sum_utils::sum` to implement `AppearsOnTable` + = note: required for `diesel::expression::functions::aggregate_folding::sum_utils::sum` to implement `SelectableExpression` + = note: required for `SelectStatement>` to implement `SelectDsl>` error[E0277]: the trait bound `users::table: TableNotEqual` is not satisfied --> tests/fail/aggregate_expression_requires_column_from_same_table.rs:20:31 @@ -55,9 +55,9 @@ note: required for `posts::columns::id` to implement `AppearsOnTable Integer, | ^^ = note: 1 redundant requirement hidden - = note: required for `diesel::expression::functions::aggregate_folding::sum::sum` to implement `AppearsOnTable` - = note: required for `diesel::expression::functions::aggregate_folding::sum::sum` to implement `SelectableExpression` - = note: required for `SelectStatement>` to implement `SelectDsl>` + = note: required for `diesel::expression::functions::aggregate_folding::sum_utils::sum` to implement `AppearsOnTable` + = note: required for `diesel::expression::functions::aggregate_folding::sum_utils::sum` to implement `SelectableExpression` + = note: required for `SelectStatement>` to implement `SelectDsl>` error[E0277]: Cannot select `posts::columns::id` from `users::table` --> tests/fail/aggregate_expression_requires_column_from_same_table.rs:21:31 @@ -74,8 +74,8 @@ error[E0277]: Cannot select `posts::columns::id` from `users::table` >> >> >> - = note: required for `diesel::expression::functions::aggregate_folding::avg::avg` to implement `SelectableExpression` - = note: required for `SelectStatement>` to implement `SelectDsl>` + = note: required for `diesel::expression::functions::aggregate_folding::avg_utils::avg` to implement `SelectableExpression` + = note: required for `SelectStatement>` to implement `SelectDsl>` error[E0271]: type mismatch resolving `
>::Count == Once` --> tests/fail/aggregate_expression_requires_column_from_same_table.rs:21:31 @@ -89,9 +89,9 @@ note: required for `posts::columns::id` to implement `AppearsOnTable Integer, | ^^ = note: 1 redundant requirement hidden - = note: required for `diesel::expression::functions::aggregate_folding::avg::avg` to implement `AppearsOnTable` - = note: required for `diesel::expression::functions::aggregate_folding::avg::avg` to implement `SelectableExpression` - = note: required for `SelectStatement>` to implement `SelectDsl>` + = note: required for `diesel::expression::functions::aggregate_folding::avg_utils::avg` to implement `AppearsOnTable` + = note: required for `diesel::expression::functions::aggregate_folding::avg_utils::avg` to implement `SelectableExpression` + = note: required for `SelectStatement>` to implement `SelectDsl>` error[E0277]: the trait bound `users::table: TableNotEqual` is not satisfied --> tests/fail/aggregate_expression_requires_column_from_same_table.rs:21:31 @@ -116,9 +116,9 @@ note: required for `posts::columns::id` to implement `AppearsOnTable Integer, | ^^ = note: 1 redundant requirement hidden - = note: required for `diesel::expression::functions::aggregate_folding::avg::avg` to implement `AppearsOnTable` - = note: required for `diesel::expression::functions::aggregate_folding::avg::avg` to implement `SelectableExpression` - = note: required for `SelectStatement>` to implement `SelectDsl>` + = note: required for `diesel::expression::functions::aggregate_folding::avg_utils::avg` to implement `AppearsOnTable` + = note: required for `diesel::expression::functions::aggregate_folding::avg_utils::avg` to implement `SelectableExpression` + = note: required for `SelectStatement>` to implement `SelectDsl>` error[E0277]: Cannot select `posts::columns::id` from `users::table` --> tests/fail/aggregate_expression_requires_column_from_same_table.rs:22:31 @@ -135,8 +135,8 @@ error[E0277]: Cannot select `posts::columns::id` from `users::table` >> >> >> - = note: required for `diesel::expression::functions::aggregate_ordering::max::max` to implement `SelectableExpression` - = note: required for `SelectStatement>` to implement `SelectDsl>` + = note: required for `diesel::expression::functions::aggregate_ordering::max_utils::max` to implement `SelectableExpression` + = note: required for `SelectStatement>` to implement `SelectDsl>` error[E0271]: type mismatch resolving `
>::Count == Once` --> tests/fail/aggregate_expression_requires_column_from_same_table.rs:22:31 @@ -150,9 +150,9 @@ note: required for `posts::columns::id` to implement `AppearsOnTable Integer, | ^^ = note: 1 redundant requirement hidden - = note: required for `diesel::expression::functions::aggregate_ordering::max::max` to implement `AppearsOnTable` - = note: required for `diesel::expression::functions::aggregate_ordering::max::max` to implement `SelectableExpression` - = note: required for `SelectStatement>` to implement `SelectDsl>` + = note: required for `diesel::expression::functions::aggregate_ordering::max_utils::max` to implement `AppearsOnTable` + = note: required for `diesel::expression::functions::aggregate_ordering::max_utils::max` to implement `SelectableExpression` + = note: required for `SelectStatement>` to implement `SelectDsl>` error[E0277]: the trait bound `users::table: TableNotEqual` is not satisfied --> tests/fail/aggregate_expression_requires_column_from_same_table.rs:22:31 @@ -177,9 +177,9 @@ note: required for `posts::columns::id` to implement `AppearsOnTable Integer, | ^^ = note: 1 redundant requirement hidden - = note: required for `diesel::expression::functions::aggregate_ordering::max::max` to implement `AppearsOnTable` - = note: required for `diesel::expression::functions::aggregate_ordering::max::max` to implement `SelectableExpression` - = note: required for `SelectStatement>` to implement `SelectDsl>` + = note: required for `diesel::expression::functions::aggregate_ordering::max_utils::max` to implement `AppearsOnTable` + = note: required for `diesel::expression::functions::aggregate_ordering::max_utils::max` to implement `SelectableExpression` + = note: required for `SelectStatement>` to implement `SelectDsl>` error[E0277]: Cannot select `posts::columns::id` from `users::table` --> tests/fail/aggregate_expression_requires_column_from_same_table.rs:23:31 @@ -196,8 +196,8 @@ error[E0277]: Cannot select `posts::columns::id` from `users::table` >> >> >> - = note: required for `diesel::expression::functions::aggregate_ordering::min::min` to implement `SelectableExpression` - = note: required for `SelectStatement>` to implement `SelectDsl>` + = note: required for `diesel::expression::functions::aggregate_ordering::min_utils::min` to implement `SelectableExpression` + = note: required for `SelectStatement>` to implement `SelectDsl>` error[E0271]: type mismatch resolving `
>::Count == Once` --> tests/fail/aggregate_expression_requires_column_from_same_table.rs:23:31 @@ -211,9 +211,9 @@ note: required for `posts::columns::id` to implement `AppearsOnTable Integer, | ^^ = note: 1 redundant requirement hidden - = note: required for `diesel::expression::functions::aggregate_ordering::min::min` to implement `AppearsOnTable` - = note: required for `diesel::expression::functions::aggregate_ordering::min::min` to implement `SelectableExpression` - = note: required for `SelectStatement>` to implement `SelectDsl>` + = note: required for `diesel::expression::functions::aggregate_ordering::min_utils::min` to implement `AppearsOnTable` + = note: required for `diesel::expression::functions::aggregate_ordering::min_utils::min` to implement `SelectableExpression` + = note: required for `SelectStatement>` to implement `SelectDsl>` error[E0277]: the trait bound `users::table: TableNotEqual` is not satisfied --> tests/fail/aggregate_expression_requires_column_from_same_table.rs:23:31 @@ -238,6 +238,6 @@ note: required for `posts::columns::id` to implement `AppearsOnTable Integer, | ^^ = note: 1 redundant requirement hidden - = note: required for `diesel::expression::functions::aggregate_ordering::min::min` to implement `AppearsOnTable` - = note: required for `diesel::expression::functions::aggregate_ordering::min::min` to implement `SelectableExpression` - = note: required for `SelectStatement>` to implement `SelectDsl>` + = note: required for `diesel::expression::functions::aggregate_ordering::min_utils::min` to implement `AppearsOnTable` + = note: required for `diesel::expression::functions::aggregate_ordering::min_utils::min` to implement `SelectableExpression` + = note: required for `SelectStatement>` to implement `SelectDsl>` diff --git a/diesel_compile_tests/tests/fail/cannot_mix_aggregate_and_non_aggregate_selects.rs b/diesel_compile_tests/tests/fail/cannot_mix_aggregate_and_non_aggregate_selects.rs index d44fe0069691..60f7ac63fd9b 100644 --- a/diesel_compile_tests/tests/fail/cannot_mix_aggregate_and_non_aggregate_selects.rs +++ b/diesel_compile_tests/tests/fail/cannot_mix_aggregate_and_non_aggregate_selects.rs @@ -11,7 +11,7 @@ table! { } } -sql_function!(fn f(x: Nullable, y: Nullable) -> Nullable); +define_sql_function!(fn f(x: Nullable, y: Nullable) -> Nullable); fn main() { use self::users::dsl::*; diff --git a/diesel_compile_tests/tests/fail/cannot_mix_aggregate_and_non_aggregate_selects.stderr b/diesel_compile_tests/tests/fail/cannot_mix_aggregate_and_non_aggregate_selects.stderr index dc7b430a10bd..d2851e2b80a2 100644 --- a/diesel_compile_tests/tests/fail/cannot_mix_aggregate_and_non_aggregate_selects.stderr +++ b/diesel_compile_tests/tests/fail/cannot_mix_aggregate_and_non_aggregate_selects.stderr @@ -20,7 +20,7 @@ error[E0277]: the trait bound `diesel::expression::is_aggregate::No: MixedAggreg > > = note: required for `Add, nullable_int_col>>` to implement `ValidGrouping<()>` - = note: required for `SelectStatement>` to implement `SelectDsl, columns::nullable_int_col>>>` + = note: required for `SelectStatement>` to implement `SelectDsl, columns::nullable_int_col>>>` error[E0277]: the trait bound `diesel::expression::is_aggregate::No: MixedAggregates` is not satisfied --> tests/fail/cannot_mix_aggregate_and_non_aggregate_selects.rs:24:24 @@ -34,9 +34,9 @@ error[E0277]: the trait bound `diesel::expression::is_aggregate::No: MixedAggreg note: required for `__Derived, nullable_int_col>>` to implement `ValidGrouping<()>` --> tests/fail/cannot_mix_aggregate_and_non_aggregate_selects.rs:14:1 | -14 | sql_function!(fn f(x: Nullable, y: Nullable) -> Nullable); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro +14 | define_sql_function!(fn f(x: Nullable, y: Nullable) -> Nullable); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro = note: 1 redundant requirement hidden = note: required for `f, nullable_int_col>>` to implement `ValidGrouping<()>` - = note: required for `SelectStatement>` to implement `SelectDsl, columns::nullable_int_col>>>` - = note: this error originates in the macro `sql_function` which comes from the expansion of the derive macro `ValidGrouping` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: required for `SelectStatement>` to implement `SelectDsl, columns::nullable_int_col>>>` + = note: this error originates in the macro `define_sql_function` which comes from the expansion of the derive macro `ValidGrouping` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/diesel_compile_tests/tests/fail/cannot_pass_aggregate_to_where.stderr b/diesel_compile_tests/tests/fail/cannot_pass_aggregate_to_where.stderr index a239411f82b3..a40da00906b3 100644 --- a/diesel_compile_tests/tests/fail/cannot_pass_aggregate_to_where.stderr +++ b/diesel_compile_tests/tests/fail/cannot_pass_aggregate_to_where.stderr @@ -8,4 +8,4 @@ error[E0277]: the trait bound `diesel::expression::is_aggregate::Yes: MixedAggre > > = note: required for `Grouped, Bound>>` to implement `NonAggregate` - = note: required for `SelectStatement>` to implement `FilterDsl, diesel::expression::bound::Bound>>>` + = note: required for `SelectStatement>` to implement `FilterDsl, diesel::expression::bound::Bound>>>` diff --git a/diesel_compile_tests/tests/fail/custom_returning_requires_nonaggregate.stderr b/diesel_compile_tests/tests/fail/custom_returning_requires_nonaggregate.stderr index 11d060ce99f8..28a3c85e0224 100644 --- a/diesel_compile_tests/tests/fail/custom_returning_requires_nonaggregate.stderr +++ b/diesel_compile_tests/tests/fail/custom_returning_requires_nonaggregate.stderr @@ -30,8 +30,8 @@ error[E0277]: the trait bound `diesel::expression::is_aggregate::No: MixedAggreg = help: the following other types implement trait `MixedAggregates`: > > - = note: required for `(columns::name, diesel::expression::count::count::count)` to implement `ValidGrouping<()>` - = note: required for `(columns::name, diesel::expression::count::count::count)` to implement `NonAggregate` + = note: required for `(columns::name, diesel::expression::count::count_utils::count)` to implement `ValidGrouping<()>` + = note: required for `(columns::name, diesel::expression::count::count_utils::count)` to implement `NonAggregate` = note: required for `InsertStatement,), ...>, ..., ...>` to implement `Query` note: required by a bound in `InsertStatement::::returning` --> $DIESEL/src/query_builder/insert_statement/mod.rs diff --git a/diesel_compile_tests/tests/fail/filter_requires_bool_nonaggregate_expression.stderr b/diesel_compile_tests/tests/fail/filter_requires_bool_nonaggregate_expression.stderr index 9d994f20ddfb..9eea82b6da9b 100644 --- a/diesel_compile_tests/tests/fail/filter_requires_bool_nonaggregate_expression.stderr +++ b/diesel_compile_tests/tests/fail/filter_requires_bool_nonaggregate_expression.stderr @@ -31,4 +31,4 @@ error[E0277]: the trait bound `diesel::expression::is_aggregate::Yes: MixedAggre > > = note: required for `Grouped, Bound, i64>>>` to implement `NonAggregate` - = note: required for `SelectStatement>` to implement `FilterDsl, diesel::expression::bound::Bound, i64>>>>` + = note: required for `SelectStatement>` to implement `FilterDsl, diesel::expression::bound::Bound, i64>>>>` diff --git a/diesel_compile_tests/tests/fail/ordering_functions_require_ord.stderr b/diesel_compile_tests/tests/fail/ordering_functions_require_ord.stderr index a99306aa0e7f..1739baf8ff3f 100644 --- a/diesel_compile_tests/tests/fail/ordering_functions_require_ord.stderr +++ b/diesel_compile_tests/tests/fail/ordering_functions_require_ord.stderr @@ -38,8 +38,8 @@ error[E0277]: the trait bound `diesel::sql_types::Bool: SqlOrd` is not satisfied Interval and $N others = note: required for `diesel::sql_types::Bool` to implement `diesel::expression::functions::aggregate_ordering::private::SqlOrdAggregate` - = note: required for `diesel::expression::functions::aggregate_ordering::max::max` to implement `diesel::Expression` - = note: required for `stuff::table` to implement `SelectDsl>` + = note: required for `diesel::expression::functions::aggregate_ordering::max_utils::max` to implement `diesel::Expression` + = note: required for `stuff::table` to implement `SelectDsl>` error[E0277]: the trait bound `diesel::sql_types::Bool: SqlOrd` is not satisfied --> tests/fail/ordering_functions_require_ord.rs:14:38 @@ -81,5 +81,5 @@ error[E0277]: the trait bound `diesel::sql_types::Bool: SqlOrd` is not satisfied Interval and $N others = note: required for `diesel::sql_types::Bool` to implement `diesel::expression::functions::aggregate_ordering::private::SqlOrdAggregate` - = note: required for `diesel::expression::functions::aggregate_ordering::min::min` to implement `diesel::Expression` - = note: required for `stuff::table` to implement `SelectDsl>` + = note: required for `diesel::expression::functions::aggregate_ordering::min_utils::min` to implement `diesel::Expression` + = note: required for `stuff::table` to implement `SelectDsl>` diff --git a/diesel_compile_tests/tests/fail/pg_on_conflict_requires_valid_conflict_target.rs b/diesel_compile_tests/tests/fail/pg_on_conflict_requires_valid_conflict_target.rs index 6f4816a2695b..ae7635184543 100644 --- a/diesel_compile_tests/tests/fail/pg_on_conflict_requires_valid_conflict_target.rs +++ b/diesel_compile_tests/tests/fail/pg_on_conflict_requires_valid_conflict_target.rs @@ -20,7 +20,7 @@ table! { #[diesel(table_name = users)] pub struct NewUser(#[diesel(column_name = name)] &'static str); -sql_function!(fn lower(x: diesel::sql_types::Text) -> diesel::sql_types::Text); +define_sql_function!(fn lower(x: diesel::sql_types::Text) -> diesel::sql_types::Text); fn main() { use self::users::dsl::*; diff --git a/diesel_compile_tests/tests/fail/pg_on_conflict_requires_valid_conflict_target.stderr b/diesel_compile_tests/tests/fail/pg_on_conflict_requires_valid_conflict_target.stderr index 154aa6f65b76..5f69a0a33324 100644 --- a/diesel_compile_tests/tests/fail/pg_on_conflict_requires_valid_conflict_target.stderr +++ b/diesel_compile_tests/tests/fail/pg_on_conflict_requires_valid_conflict_target.stderr @@ -42,11 +42,11 @@ note: required by a bound in `upsert::on_conflict_extension::>::on_conflict` = note: this error originates in the macro `table` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0277]: the trait bound `lower::lower: Column` is not satisfied +error[E0277]: the trait bound `lower_utils::lower: Column` is not satisfied --> tests/fail/pg_on_conflict_requires_valid_conflict_target.rs:42:22 | 42 | .on_conflict(lower(posts::title)); - | ----------- ^^^^^^^^^^^^^^^^^^^ the trait `Column` is not implemented for `lower::lower` + | ----------- ^^^^^^^^^^^^^^^^^^^ the trait `Column` is not implemented for `lower_utils::lower` | | | required by a bound introduced by this call | @@ -60,7 +60,7 @@ error[E0277]: the trait bound `lower::lower: Column` is n pg::metadata_lookup::pg_type::columns::typnamespace pg::metadata_lookup::pg_type::columns::typarray and $N others - = note: required for `diesel::query_builder::upsert::on_conflict_target::ConflictTarget>` to implement `diesel::query_builder::upsert::on_conflict_target::OnConflictTarget` + = note: required for `diesel::query_builder::upsert::on_conflict_target::ConflictTarget>` to implement `diesel::query_builder::upsert::on_conflict_target::OnConflictTarget` note: required by a bound in `upsert::on_conflict_extension::>::on_conflict` --> $DIESEL/src/upsert/on_conflict_extension.rs | diff --git a/diesel_compile_tests/tests/fail/pg_specific_binary_expressions_only_usable_with_pg.stderr b/diesel_compile_tests/tests/fail/pg_specific_binary_expressions_only_usable_with_pg.stderr index 0feaa5ff3a08..5732b585944d 100644 --- a/diesel_compile_tests/tests/fail/pg_specific_binary_expressions_only_usable_with_pg.stderr +++ b/diesel_compile_tests/tests/fail/pg_specific_binary_expressions_only_usable_with_pg.stderr @@ -1,16 +1,16 @@ -error[E0277]: the trait bound `diesel::pg::expression::operators::ConcatBinary>>: QueryFragment` is not satisfied +error[E0277]: the trait bound `Sqlite: diesel::expression::operators::LikeIsAllowedForType` is not satisfied --> tests/fail/pg_specific_binary_expressions_only_usable_with_pg.rs:21:32 | 21 | .get_result::>(&mut connection).unwrap(); - | ---------- ^^^^^^^^^^^^^^^ the trait `QueryFragment` is not implemented for `diesel::pg::expression::operators::ConcatBinary>>` + | ---------- ^^^^^^^^^^^^^^^ the trait `diesel::expression::operators::LikeIsAllowedForType` is not implemented for `Sqlite` | | | required by a bound introduced by this call | - = help: the trait `QueryFragment` is implemented for `diesel::pg::expression::operators::ConcatBinary` - = note: required for `Grouped>>>` to implement `QueryFragment` - = note: 3 redundant requirements hidden - = note: required for `SelectStatement, SelectClause>>>, ..., ...>` to implement `QueryFragment` - = note: required for `SelectStatement, SelectClause>>>, ..., ...>` to implement `LoadQuery<'_, diesel::SqliteConnection, Vec>` + = help: the trait `diesel::expression::operators::LikeIsAllowedForType` is implemented for `Pg` + = note: required for `diesel::expression::operators::Like>>` to implement `QueryFragment` + = note: 6 redundant requirements hidden + = note: required for `SelectStatement, SelectClause>>>>, ..., ...>` to implement `QueryFragment` + = note: required for `SelectStatement, SelectClause>>>>, ..., ...>` to implement `LoadQuery<'_, diesel::SqliteConnection, Vec>` note: required by a bound in `get_result` --> $DIESEL/src/query_dsl/mod.rs | @@ -20,107 +20,19 @@ note: required by a bound in `get_result` | Self: LoadQuery<'query, Conn, U>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::get_result` -error[E0277]: the trait bound `diesel::pg::expression::operators::LikeBinary>>: QueryFragment` is not satisfied - --> tests/fail/pg_specific_binary_expressions_only_usable_with_pg.rs:21:32 - | -21 | .get_result::>(&mut connection).unwrap(); - | ---------- ^^^^^^^^^^^^^^^ the trait `QueryFragment` is not implemented for `diesel::pg::expression::operators::LikeBinary>>` - | | - | required by a bound introduced by this call - | - = help: the trait `QueryFragment` is implemented for `diesel::pg::expression::operators::LikeBinary` - = note: required for `Grouped>>>` to implement `QueryFragment` - = note: 5 redundant requirements hidden - = note: required for `SelectStatement, SelectClause>>>, ..., ...>` to implement `QueryFragment` - = note: required for `SelectStatement, SelectClause>>>, ..., ...>` to implement `LoadQuery<'_, diesel::SqliteConnection, Vec>` -note: required by a bound in `get_result` - --> $DIESEL/src/query_dsl/mod.rs - | - | fn get_result<'query, U>(self, conn: &mut Conn) -> QueryResult - | ---------- required by a bound in this associated function - | where - | Self: LoadQuery<'query, Conn, U>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::get_result` - -error[E0277]: the trait bound `diesel::pg::expression::operators::NotLikeBinary>>: QueryFragment` is not satisfied - --> tests/fail/pg_specific_binary_expressions_only_usable_with_pg.rs:21:32 - | -21 | .get_result::>(&mut connection).unwrap(); - | ---------- ^^^^^^^^^^^^^^^ the trait `QueryFragment` is not implemented for `diesel::pg::expression::operators::NotLikeBinary>>` - | | - | required by a bound introduced by this call - | - = help: the trait `QueryFragment` is implemented for `diesel::pg::expression::operators::NotLikeBinary` - = note: required for `Grouped>>>` to implement `QueryFragment` - = note: 5 redundant requirements hidden - = note: required for `SelectStatement, SelectClause>>>, ..., ...>` to implement `QueryFragment` - = note: required for `SelectStatement, SelectClause>>>, ..., ...>` to implement `LoadQuery<'_, diesel::SqliteConnection, Vec>` -note: required by a bound in `get_result` - --> $DIESEL/src/query_dsl/mod.rs - | - | fn get_result<'query, U>(self, conn: &mut Conn) -> QueryResult - | ---------- required by a bound in this associated function - | where - | Self: LoadQuery<'query, Conn, U>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::get_result` - -error[E0277]: the trait bound `diesel::pg::expression::operators::ConcatBinary>>: QueryFragment` is not satisfied - --> tests/fail/pg_specific_binary_expressions_only_usable_with_pg.rs:29:32 - | -29 | .get_result::>(&mut connection).unwrap(); - | ---------- ^^^^^^^^^^^^^^^ the trait `QueryFragment` is not implemented for `diesel::pg::expression::operators::ConcatBinary>>` - | | - | required by a bound introduced by this call - | - = help: the trait `QueryFragment` is implemented for `diesel::pg::expression::operators::ConcatBinary` - = note: required for `Grouped>>>` to implement `QueryFragment` - = note: 3 redundant requirements hidden - = note: required for `SelectStatement, SelectClause>>>, ..., ...>` to implement `QueryFragment` - = note: required for `SelectStatement, SelectClause>>>, ..., ...>` to implement `LoadQuery<'_, diesel::MysqlConnection, Vec>` -note: required by a bound in `get_result` - --> $DIESEL/src/query_dsl/mod.rs - | - | fn get_result<'query, U>(self, conn: &mut Conn) -> QueryResult - | ---------- required by a bound in this associated function - | where - | Self: LoadQuery<'query, Conn, U>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::get_result` - -error[E0277]: the trait bound `diesel::pg::expression::operators::LikeBinary>>: QueryFragment` is not satisfied - --> tests/fail/pg_specific_binary_expressions_only_usable_with_pg.rs:29:32 - | -29 | .get_result::>(&mut connection).unwrap(); - | ---------- ^^^^^^^^^^^^^^^ the trait `QueryFragment` is not implemented for `diesel::pg::expression::operators::LikeBinary>>` - | | - | required by a bound introduced by this call - | - = help: the trait `QueryFragment` is implemented for `diesel::pg::expression::operators::LikeBinary` - = note: required for `Grouped>>>` to implement `QueryFragment` - = note: 5 redundant requirements hidden - = note: required for `SelectStatement, SelectClause>>>, ..., ...>` to implement `QueryFragment` - = note: required for `SelectStatement, SelectClause>>>, ..., ...>` to implement `LoadQuery<'_, diesel::MysqlConnection, Vec>` -note: required by a bound in `get_result` - --> $DIESEL/src/query_dsl/mod.rs - | - | fn get_result<'query, U>(self, conn: &mut Conn) -> QueryResult - | ---------- required by a bound in this associated function - | where - | Self: LoadQuery<'query, Conn, U>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::get_result` - -error[E0277]: the trait bound `diesel::pg::expression::operators::NotLikeBinary>>: QueryFragment` is not satisfied +error[E0277]: the trait bound `Mysql: diesel::expression::operators::LikeIsAllowedForType` is not satisfied --> tests/fail/pg_specific_binary_expressions_only_usable_with_pg.rs:29:32 | 29 | .get_result::>(&mut connection).unwrap(); - | ---------- ^^^^^^^^^^^^^^^ the trait `QueryFragment` is not implemented for `diesel::pg::expression::operators::NotLikeBinary>>` + | ---------- ^^^^^^^^^^^^^^^ the trait `diesel::expression::operators::LikeIsAllowedForType` is not implemented for `Mysql` | | | required by a bound introduced by this call | - = help: the trait `QueryFragment` is implemented for `diesel::pg::expression::operators::NotLikeBinary` - = note: required for `Grouped>>>` to implement `QueryFragment` - = note: 5 redundant requirements hidden - = note: required for `SelectStatement, SelectClause>>>, ..., ...>` to implement `QueryFragment` - = note: required for `SelectStatement, SelectClause>>>, ..., ...>` to implement `LoadQuery<'_, diesel::MysqlConnection, Vec>` + = help: the trait `diesel::expression::operators::LikeIsAllowedForType` is implemented for `Pg` + = note: required for `diesel::expression::operators::Like>>` to implement `QueryFragment` + = note: 6 redundant requirements hidden + = note: required for `SelectStatement, SelectClause>>>>, ..., ...>` to implement `QueryFragment` + = note: required for `SelectStatement, SelectClause>>>>, ..., ...>` to implement `LoadQuery<'_, diesel::MysqlConnection, Vec>` note: required by a bound in `get_result` --> $DIESEL/src/query_dsl/mod.rs | diff --git a/diesel_compile_tests/tests/fail/pg_specific_expressions_cant_be_used_in_a_sqlite_query.rs b/diesel_compile_tests/tests/fail/pg_specific_expressions_cant_be_used_in_a_sqlite_query.rs index 1d7945e845f9..b1f107af0597 100644 --- a/diesel_compile_tests/tests/fail/pg_specific_expressions_cant_be_used_in_a_sqlite_query.rs +++ b/diesel_compile_tests/tests/fail/pg_specific_expressions_cant_be_used_in_a_sqlite_query.rs @@ -12,7 +12,7 @@ table! { } } -sql_function!(fn lower(x: VarChar) -> VarChar); +define_sql_function!(fn lower(x: VarChar) -> VarChar); #[derive(Insertable)] #[diesel(table_name = users)] @@ -23,13 +23,20 @@ fn main() { use self::users::dsl::*; let mut connection = SqliteConnection::establish(":memory:").unwrap(); - users.select(id).filter(name.eq(any(Vec::::new()))) + users + .select(id) + .filter(name.eq(any(Vec::::new()))) .load::(&mut connection); - users.select(id).filter(name.is_not_distinct_from("Sean")) + users + .select(id) + .filter(name.is_not_distinct_from("Sean")) .load::(&mut connection); - users.select(id).filter(now.eq(now.at_time_zone("UTC"))) + users + .select(id) + .filter(now.eq(now.at_time_zone("UTC"))) .load::(&mut connection); - insert_into(users).values(&NewUser("Sean")) + insert_into(users) + .values(&NewUser("Sean")) .on_conflict(on_constraint("name")) .execute(&mut connection); } diff --git a/diesel_compile_tests/tests/fail/pg_specific_expressions_cant_be_used_in_a_sqlite_query.stderr b/diesel_compile_tests/tests/fail/pg_specific_expressions_cant_be_used_in_a_sqlite_query.stderr index 67d4a81ca7e6..39d3375ab318 100644 --- a/diesel_compile_tests/tests/fail/pg_specific_expressions_cant_be_used_in_a_sqlite_query.stderr +++ b/diesel_compile_tests/tests/fail/pg_specific_expressions_cant_be_used_in_a_sqlite_query.stderr @@ -1,15 +1,15 @@ warning: use of deprecated function `diesel::dsl::any`: Use `ExpressionMethods::eq_any` instead - --> tests/fail/pg_specific_expressions_cant_be_used_in_a_sqlite_query.rs:26:37 + --> tests/fail/pg_specific_expressions_cant_be_used_in_a_sqlite_query.rs:28:25 | -26 | users.select(id).filter(name.eq(any(Vec::::new()))) - | ^^^ +28 | .filter(name.eq(any(Vec::::new()))) + | ^^^ | = note: `#[warn(deprecated)]` on by default error[E0277]: the trait bound `diesel::pg::expression::array_comparison::Any, Vec>>: QueryFragment` is not satisfied - --> tests/fail/pg_specific_expressions_cant_be_used_in_a_sqlite_query.rs:27:22 + --> tests/fail/pg_specific_expressions_cant_be_used_in_a_sqlite_query.rs:29:22 | -27 | .load::(&mut connection); +29 | .load::(&mut connection); | ---- ^^^^^^^^^^^^^^^ the trait `QueryFragment` is not implemented for `diesel::pg::expression::array_comparison::Any, Vec>>` | | | required by a bound introduced by this call @@ -29,9 +29,9 @@ note: required by a bound in `diesel::RunQueryDsl::load` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::load` error[E0277]: the trait bound `diesel::pg::expression::operators::IsNotDistinctFrom>: QueryFragment` is not satisfied - --> tests/fail/pg_specific_expressions_cant_be_used_in_a_sqlite_query.rs:29:22 + --> tests/fail/pg_specific_expressions_cant_be_used_in_a_sqlite_query.rs:33:22 | -29 | .load::(&mut connection); +33 | .load::(&mut connection); | ---- ^^^^^^^^^^^^^^^ the trait `QueryFragment` is not implemented for `diesel::pg::expression::operators::IsNotDistinctFrom>` | | | required by a bound introduced by this call @@ -51,9 +51,9 @@ note: required by a bound in `diesel::RunQueryDsl::load` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::load` error[E0277]: the trait bound `diesel::pg::expression::date_and_time::AtTimeZone>: QueryFragment` is not satisfied - --> tests/fail/pg_specific_expressions_cant_be_used_in_a_sqlite_query.rs:31:22 + --> tests/fail/pg_specific_expressions_cant_be_used_in_a_sqlite_query.rs:37:22 | -31 | .load::(&mut connection); +37 | .load::(&mut connection); | ---- ^^^^^^^^^^^^^^^ the trait `QueryFragment` is not implemented for `diesel::pg::expression::date_and_time::AtTimeZone>` | | | required by a bound introduced by this call @@ -73,11 +73,12 @@ note: required by a bound in `diesel::RunQueryDsl::load` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::load` error[E0599]: the method `execute` exists for struct `IncompleteOnConflict,), ...>>, ...>`, but its trait bounds were not satisfied - --> tests/fail/pg_specific_expressions_cant_be_used_in_a_sqlite_query.rs:34:10 + --> tests/fail/pg_specific_expressions_cant_be_used_in_a_sqlite_query.rs:41:10 | -32 | / insert_into(users).values(&NewUser("Sean")) -33 | | .on_conflict(on_constraint("name")) -34 | | .execute(&mut connection); +38 | / insert_into(users) +39 | | .values(&NewUser("Sean")) +40 | | .on_conflict(on_constraint("name")) +41 | | .execute(&mut connection); | | -^^^^^^^ method cannot be called due to unsatisfied trait bounds | |_________| | diff --git a/diesel_compile_tests/tests/fail/right_side_of_left_join_requires_nullable.rs b/diesel_compile_tests/tests/fail/right_side_of_left_join_requires_nullable.rs index c62f19081a47..e6759ecd079a 100644 --- a/diesel_compile_tests/tests/fail/right_side_of_left_join_requires_nullable.rs +++ b/diesel_compile_tests/tests/fail/right_side_of_left_join_requires_nullable.rs @@ -30,7 +30,7 @@ table! { joinable!(posts -> users (user_id)); joinable!(pets -> users (user_id)); allow_tables_to_appear_in_same_query!(posts, users, pets); -sql_function!(fn lower(x: Text) -> Text); +define_sql_function!(fn lower(x: Text) -> Text); fn main() {} diff --git a/diesel_compile_tests/tests/fail/right_side_of_left_join_requires_nullable.stderr b/diesel_compile_tests/tests/fail/right_side_of_left_join_requires_nullable.stderr index 1e47a5e0021d..0d8941f56475 100644 --- a/diesel_compile_tests/tests/fail/right_side_of_left_join_requires_nullable.stderr +++ b/diesel_compile_tests/tests/fail/right_side_of_left_join_requires_nullable.stderr @@ -49,8 +49,8 @@ note: required for `posts::columns::title` to implement `SelectableExpression Text, | ^^^^^ = note: 2 redundant requirements hidden - = note: required for `lower::lower` to implement `SelectableExpression, diesel::expression::grouped::Grouped, NullableExpression>>>>` - = note: required for `SelectStatement, Grouped, ...>>>>>` to implement `SelectDsl>` + = note: required for `lower_utils::lower` to implement `SelectableExpression, diesel::expression::grouped::Grouped, NullableExpression>>>>` + = note: required for `SelectStatement, Grouped, ...>>>>>` to implement `SelectDsl>` error[E0277]: Cannot select `posts::columns::title` from `users::table` --> tests/fail/right_side_of_left_join_requires_nullable.rs:47:18 @@ -73,8 +73,8 @@ note: required for `posts::columns::title` to implement `SelectableExpression Text, | ^^^^^ = note: 2 redundant requirements hidden - = note: required for `lower::lower` to implement `SelectableExpression, diesel::expression::grouped::Grouped, NullableExpression>>>>` - = note: required for `SelectStatement, Grouped, ...>>>>>` to implement `SelectDsl>` + = note: required for `lower_utils::lower` to implement `SelectableExpression, diesel::expression::grouped::Grouped, NullableExpression>>>>` + = note: required for `SelectStatement, Grouped, ...>>>>>` to implement `SelectDsl>` error[E0271]: type mismatch resolving ` as Expression>::SqlType == Text` --> tests/fail/right_side_of_left_join_requires_nullable.rs:49:31 @@ -90,9 +90,9 @@ error[E0271]: type mismatch resolving ` as Expression>::SqlType note: required by a bound in `lower` --> tests/fail/right_side_of_left_join_requires_nullable.rs:33:1 | -33 | sql_function!(fn lower(x: Text) -> Text); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `lower` - = note: this error originates in the macro `sql_function` (in Nightly builds, run with -Z macro-backtrace for more info) +33 | define_sql_function!(fn lower(x: Text) -> Text); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `lower` + = note: this error originates in the macro `define_sql_function` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0271]: type mismatch resolving ` as Expression>::SqlType == Text` --> tests/fail/right_side_of_left_join_requires_nullable.rs:49:25 @@ -155,8 +155,8 @@ note: required for `posts::columns::title` to implement `SelectableExpression Text, | ^^^^^ = note: 4 redundant requirements hidden - = note: required for `lower::lower` to implement `SelectableExpression, diesel::expression::grouped::Grouped, NullableExpression>>>, pets::table, LeftOuter>, diesel::expression::grouped::Grouped, NullableExpression>>>>` - = note: required for `SelectStatement, Grouped<...>>, ..., ...>, ...>>>` to implement `SelectDsl>` + = note: required for `lower_utils::lower` to implement `SelectableExpression, diesel::expression::grouped::Grouped, NullableExpression>>>, pets::table, LeftOuter>, diesel::expression::grouped::Grouped, NullableExpression>>>>` + = note: required for `SelectStatement, Grouped<...>>, ..., ...>, ...>>>` to implement `SelectDsl>` error[E0277]: Cannot select `posts::columns::title` from `users::table` --> tests/fail/right_side_of_left_join_requires_nullable.rs:64:18 @@ -179,8 +179,8 @@ note: required for `posts::columns::title` to implement `SelectableExpression Text, | ^^^^^ = note: 4 redundant requirements hidden - = note: required for `lower::lower` to implement `SelectableExpression, diesel::expression::grouped::Grouped, NullableExpression>>>, pets::table, LeftOuter>, diesel::expression::grouped::Grouped, NullableExpression>>>>` - = note: required for `SelectStatement, Grouped<...>>, ..., ...>, ...>>>` to implement `SelectDsl>` + = note: required for `lower_utils::lower` to implement `SelectableExpression, diesel::expression::grouped::Grouped, NullableExpression>>>, pets::table, LeftOuter>, diesel::expression::grouped::Grouped, NullableExpression>>>>` + = note: required for `SelectStatement, Grouped<...>>, ..., ...>, ...>>>` to implement `SelectDsl>` error[E0271]: type mismatch resolving ` as Expression>::SqlType == Text` --> tests/fail/right_side_of_left_join_requires_nullable.rs:66:31 @@ -196,9 +196,9 @@ error[E0271]: type mismatch resolving ` as Expression>::SqlType note: required by a bound in `lower` --> tests/fail/right_side_of_left_join_requires_nullable.rs:33:1 | -33 | sql_function!(fn lower(x: Text) -> Text); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `lower` - = note: this error originates in the macro `sql_function` (in Nightly builds, run with -Z macro-backtrace for more info) +33 | define_sql_function!(fn lower(x: Text) -> Text); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `lower` + = note: this error originates in the macro `define_sql_function` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0271]: type mismatch resolving ` as Expression>::SqlType == Text` --> tests/fail/right_side_of_left_join_requires_nullable.rs:66:25 @@ -261,8 +261,8 @@ note: required for `posts::columns::title` to implement `SelectableExpression Text, | ^^^^^ = note: 4 redundant requirements hidden - = note: required for `lower::lower` to implement `SelectableExpression, diesel::expression::grouped::Grouped, NullableExpression>>>, pets::table, Inner>, diesel::expression::grouped::Grouped, NullableExpression>>>>` - = note: required for `SelectStatement, Grouped<...>>, ..., ...>, ...>>>` to implement `SelectDsl>` + = note: required for `lower_utils::lower` to implement `SelectableExpression, diesel::expression::grouped::Grouped, NullableExpression>>>, pets::table, Inner>, diesel::expression::grouped::Grouped, NullableExpression>>>>` + = note: required for `SelectStatement, Grouped<...>>, ..., ...>, ...>>>` to implement `SelectDsl>` error[E0277]: Cannot select `posts::columns::title` from `users::table` --> tests/fail/right_side_of_left_join_requires_nullable.rs:81:18 @@ -285,8 +285,8 @@ note: required for `posts::columns::title` to implement `SelectableExpression Text, | ^^^^^ = note: 4 redundant requirements hidden - = note: required for `lower::lower` to implement `SelectableExpression, diesel::expression::grouped::Grouped, NullableExpression>>>, pets::table, Inner>, diesel::expression::grouped::Grouped, NullableExpression>>>>` - = note: required for `SelectStatement, Grouped<...>>, ..., ...>, ...>>>` to implement `SelectDsl>` + = note: required for `lower_utils::lower` to implement `SelectableExpression, diesel::expression::grouped::Grouped, NullableExpression>>>, pets::table, Inner>, diesel::expression::grouped::Grouped, NullableExpression>>>>` + = note: required for `SelectStatement, Grouped<...>>, ..., ...>, ...>>>` to implement `SelectDsl>` error[E0271]: type mismatch resolving ` as Expression>::SqlType == Text` --> tests/fail/right_side_of_left_join_requires_nullable.rs:83:31 @@ -302,9 +302,9 @@ error[E0271]: type mismatch resolving ` as Expression>::SqlType note: required by a bound in `lower` --> tests/fail/right_side_of_left_join_requires_nullable.rs:33:1 | -33 | sql_function!(fn lower(x: Text) -> Text); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `lower` - = note: this error originates in the macro `sql_function` (in Nightly builds, run with -Z macro-backtrace for more info) +33 | define_sql_function!(fn lower(x: Text) -> Text); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `lower` + = note: this error originates in the macro `define_sql_function` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0271]: type mismatch resolving ` as Expression>::SqlType == Text` --> tests/fail/right_side_of_left_join_requires_nullable.rs:83:25 @@ -367,8 +367,8 @@ note: required for `posts::columns::title` to implement `SelectableExpression Text, | ^^^^^ = note: 2 redundant requirements hidden - = note: required for `lower::lower` to implement `SelectableExpression, diesel::expression::grouped::Grouped, NullableExpression>>>>>, LeftOuter>, diesel::expression::grouped::Grouped, NullableExpression>>>>` - = note: required for `SelectStatement>>, ...>, ...>>>` to implement `SelectDsl>` + = note: required for `lower_utils::lower` to implement `SelectableExpression, diesel::expression::grouped::Grouped, NullableExpression>>>>>, LeftOuter>, diesel::expression::grouped::Grouped, NullableExpression>>>>` + = note: required for `SelectStatement>>, ...>, ...>>>` to implement `SelectDsl>` error[E0277]: Cannot select `posts::columns::title` from `pets::table` --> tests/fail/right_side_of_left_join_requires_nullable.rs:96:18 @@ -391,8 +391,8 @@ note: required for `posts::columns::title` to implement `SelectableExpression Text, | ^^^^^ = note: 2 redundant requirements hidden - = note: required for `lower::lower` to implement `SelectableExpression, diesel::expression::grouped::Grouped, NullableExpression>>>>>, LeftOuter>, diesel::expression::grouped::Grouped, NullableExpression>>>>` - = note: required for `SelectStatement>>, ...>, ...>>>` to implement `SelectDsl>` + = note: required for `lower_utils::lower` to implement `SelectableExpression, diesel::expression::grouped::Grouped, NullableExpression>>>>>, LeftOuter>, diesel::expression::grouped::Grouped, NullableExpression>>>>` + = note: required for `SelectStatement>>, ...>, ...>>>` to implement `SelectDsl>` error[E0271]: type mismatch resolving ` as Expression>::SqlType == Text` --> tests/fail/right_side_of_left_join_requires_nullable.rs:98:31 @@ -408,9 +408,9 @@ error[E0271]: type mismatch resolving ` as Expression>::SqlType note: required by a bound in `lower` --> tests/fail/right_side_of_left_join_requires_nullable.rs:33:1 | -33 | sql_function!(fn lower(x: Text) -> Text); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `lower` - = note: this error originates in the macro `sql_function` (in Nightly builds, run with -Z macro-backtrace for more info) +33 | define_sql_function!(fn lower(x: Text) -> Text); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `lower` + = note: this error originates in the macro `define_sql_function` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0271]: type mismatch resolving ` as Expression>::SqlType == Text` --> tests/fail/right_side_of_left_join_requires_nullable.rs:98:25 @@ -473,8 +473,8 @@ note: required for `posts::columns::title` to implement `SelectableExpression Text, | ^^^^^ = note: 5 redundant requirements hidden - = note: required for `lower::lower` to implement `SelectableExpression, diesel::expression::grouped::Grouped, NullableExpression>>>>>, Inner>, diesel::expression::grouped::Grouped, NullableExpression>>>>` - = note: required for `SelectStatement>>, ...>, ...>>>` to implement `SelectDsl>` + = note: required for `lower_utils::lower` to implement `SelectableExpression, diesel::expression::grouped::Grouped, NullableExpression>>>>>, Inner>, diesel::expression::grouped::Grouped, NullableExpression>>>>` + = note: required for `SelectStatement>>, ...>, ...>>>` to implement `SelectDsl>` error[E0277]: Cannot select `posts::columns::title` from `users::table` --> tests/fail/right_side_of_left_join_requires_nullable.rs:111:18 @@ -497,8 +497,8 @@ note: required for `posts::columns::title` to implement `SelectableExpression Text, | ^^^^^ = note: 5 redundant requirements hidden - = note: required for `lower::lower` to implement `SelectableExpression, diesel::expression::grouped::Grouped, NullableExpression>>>>>, Inner>, diesel::expression::grouped::Grouped, NullableExpression>>>>` - = note: required for `SelectStatement>>, ...>, ...>>>` to implement `SelectDsl>` + = note: required for `lower_utils::lower` to implement `SelectableExpression, diesel::expression::grouped::Grouped, NullableExpression>>>>>, Inner>, diesel::expression::grouped::Grouped, NullableExpression>>>>` + = note: required for `SelectStatement>>, ...>, ...>>>` to implement `SelectDsl>` error[E0271]: type mismatch resolving ` as Expression>::SqlType == Text` --> tests/fail/right_side_of_left_join_requires_nullable.rs:113:31 @@ -514,9 +514,9 @@ error[E0271]: type mismatch resolving ` as Expression>::SqlType note: required by a bound in `lower` --> tests/fail/right_side_of_left_join_requires_nullable.rs:33:1 | -33 | sql_function!(fn lower(x: Text) -> Text); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `lower` - = note: this error originates in the macro `sql_function` (in Nightly builds, run with -Z macro-backtrace for more info) +33 | define_sql_function!(fn lower(x: Text) -> Text); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `lower` + = note: this error originates in the macro `define_sql_function` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0271]: type mismatch resolving ` as Expression>::SqlType == Text` --> tests/fail/right_side_of_left_join_requires_nullable.rs:113:25 diff --git a/diesel_compile_tests/tests/fail/selectable.stderr b/diesel_compile_tests/tests/fail/selectable.stderr index 1bbbbcc69c47..db8bcef3d6c8 100644 --- a/diesel_compile_tests/tests/fail/selectable.stderr +++ b/diesel_compile_tests/tests/fail/selectable.stderr @@ -234,7 +234,7 @@ error[E0277]: the trait bound `diesel::expression::is_aggregate::No: MixedAggreg = help: the following other types implement trait `MixedAggregates`: > > - = note: required for `(users::columns::name, diesel::expression::count::count::count)` to implement `ValidGrouping<()>` + = note: required for `(users::columns::name, diesel::expression::count::count_utils::count)` to implement `ValidGrouping<()>` = note: 2 redundant requirements hidden = note: required for `diesel::expression::select_by::SelectBy` to implement `ValidGrouping<()>` = note: required for `SelectStatement, Grouped, Nullable>>>>>` to implement `SelectDsl>` diff --git a/diesel_compile_tests/tests/fail/user_defined_functions_follow_same_selection_rules.rs b/diesel_compile_tests/tests/fail/user_defined_functions_follow_same_selection_rules.rs index 88a40720aee3..430854976cf1 100644 --- a/diesel_compile_tests/tests/fail/user_defined_functions_follow_same_selection_rules.rs +++ b/diesel_compile_tests/tests/fail/user_defined_functions_follow_same_selection_rules.rs @@ -1,7 +1,7 @@ extern crate diesel; -use diesel::*; use diesel::sql_types::*; +use diesel::*; table! { users { @@ -23,17 +23,18 @@ struct User { name: String, } -sql_function!(fn foo(x: Integer) -> Integer); -sql_function!(fn bar(x: VarChar) -> VarChar); +define_sql_function!(fn foo(x: Integer) -> Integer); +define_sql_function!(fn bar(x: VarChar) -> VarChar); fn main() { - use self::users::name; use self::posts::title; + use self::users::name; let mut conn = PgConnection::establish("").unwrap(); let _ = users::table.filter(name.eq(foo(1))); - let _ = users::table.filter(name.eq(bar(title))) + let _ = users::table + .filter(name.eq(bar(title))) .load::(&mut conn); } diff --git a/diesel_compile_tests/tests/fail/user_defined_functions_follow_same_selection_rules.stderr b/diesel_compile_tests/tests/fail/user_defined_functions_follow_same_selection_rules.stderr index 3b50e58d9fbc..eca81fbfdb82 100644 --- a/diesel_compile_tests/tests/fail/user_defined_functions_follow_same_selection_rules.stderr +++ b/diesel_compile_tests/tests/fail/user_defined_functions_follow_same_selection_rules.stderr @@ -4,12 +4,12 @@ error[E0271]: type mismatch resolving `> as Expression>: 35 | let _ = users::table.filter(name.eq(foo(1))); | ^^ expected `Integer`, found `Text` | - = note: required for `foo::foo>` to implement `AsExpression` + = note: required for `foo_utils::foo>` to implement `AsExpression` error[E0271]: type mismatch resolving `
>::Count == Once` - --> tests/fail/user_defined_functions_follow_same_selection_rules.rs:38:23 + --> tests/fail/user_defined_functions_follow_same_selection_rules.rs:39:23 | -38 | .load::(&mut conn); +39 | .load::(&mut conn); | ---- ^^^^^^^^^ expected `Once`, found `Never` | | | required by a bound introduced by this call @@ -20,7 +20,7 @@ note: required for `posts::columns::title` to implement `AppearsOnTable VarChar, | ^^^^^ = note: 3 redundant requirements hidden - = note: required for `diesel::expression::grouped::Grouped>>` to implement `AppearsOnTable` + = note: required for `diesel::expression::grouped::Grouped>>` to implement `AppearsOnTable` = note: required for `WhereClause>>>` to implement `diesel::query_builder::where_clause::ValidWhereClause>` = note: required for `SelectStatement, DefaultSelectClause>, NoDistinctClause, WhereClause<...>>` to implement `Query` = note: required for `SelectStatement, DefaultSelectClause>, NoDistinctClause, WhereClause<...>>` to implement `LoadQuery<'_, _, User>` @@ -34,9 +34,9 @@ note: required by a bound in `diesel::RunQueryDsl::load` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::load` error[E0277]: the trait bound `users::table: TableNotEqual` is not satisfied - --> tests/fail/user_defined_functions_follow_same_selection_rules.rs:38:23 + --> tests/fail/user_defined_functions_follow_same_selection_rules.rs:39:23 | -38 | .load::(&mut conn); +39 | .load::(&mut conn); | ---- ^^^^^^^^^ the trait `TableNotEqual` is not implemented for `users::table` | | | required by a bound introduced by this call @@ -58,7 +58,7 @@ note: required for `posts::columns::title` to implement `AppearsOnTable VarChar, | ^^^^^ = note: 3 redundant requirements hidden - = note: required for `diesel::expression::grouped::Grouped>>` to implement `AppearsOnTable` + = note: required for `diesel::expression::grouped::Grouped>>` to implement `AppearsOnTable` = note: required for `WhereClause>>>` to implement `diesel::query_builder::where_clause::ValidWhereClause>` = note: required for `SelectStatement, DefaultSelectClause>, NoDistinctClause, WhereClause<...>>` to implement `Query` = note: required for `SelectStatement, DefaultSelectClause>, NoDistinctClause, WhereClause<...>>` to implement `LoadQuery<'_, _, User>` diff --git a/diesel_derives/src/lib.rs b/diesel_derives/src/lib.rs index 7503c2d49f43..df8f04d3bb17 100644 --- a/diesel_derives/src/lib.rs +++ b/diesel_derives/src/lib.rs @@ -1013,46 +1013,17 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// function. For example, this invocation: /// /// ```ignore -/// sql_function!(fn lower(x: Text) -> Text); +/// define_sql_function!(fn lower(x: Text) -> Text); /// ``` /// /// will generate this code: /// /// ```ignore -/// pub fn lower(x: X) -> lower::HelperType { +/// pub fn lower(x: X) -> lower { /// ... /// } /// -/// pub(crate) mod lower { -/// pub type HelperType = ...; -/// } -/// ``` -/// -/// If you are using this macro for part of a library, where the function is -/// part of your public API, it is highly recommended that you re-export this -/// helper type with the same name as your function. This is the standard -/// structure: -/// -/// ```ignore -/// pub mod functions { -/// use super::types::*; -/// use diesel::sql_types::*; -/// -/// sql_function! { -/// /// Represents the Pg `LENGTH` function used with `tsvector`s. -/// fn length(x: TsVector) -> Integer; -/// } -/// } -/// -/// pub mod helper_types { -/// /// The return type of `length(expr)` -/// pub type Length = functions::length::HelperType; -/// } -/// -/// pub mod dsl { -/// pub use functions::*; -/// pub use helper_types::*; -/// } +/// pub type lower = ...; /// ``` /// /// Most attributes given to this macro will be put on the generated function @@ -1068,7 +1039,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # /// use diesel::sql_types::Text; /// -/// sql_function! { +/// define_sql_function! { /// /// Represents the `canon_crate_name` SQL function, created in /// /// migration .... /// fn canon_crate_name(a: Text) -> Text; @@ -1106,7 +1077,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # /// use diesel::sql_types::Foldable; /// -/// sql_function! { +/// define_sql_function! { /// #[aggregate] /// #[sql_name = "SUM"] /// fn sum(expr: ST) -> ST::Sum; @@ -1121,7 +1092,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # SQL Functions without Arguments /// /// A common example is ordering a query using the `RANDOM()` sql function, -/// which can be implemented using `sql_function!` like this: +/// which can be implemented using `define_sql_function!` like this: /// /// ```rust /// # extern crate diesel; @@ -1129,7 +1100,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # /// # table! { crates { id -> Integer, name -> VarChar, } } /// # -/// sql_function!(fn random() -> Text); +/// define_sql_function!(fn random() -> Text); /// /// # fn main() { /// # use self::crates::dsl::*; @@ -1142,8 +1113,8 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// On most backends, the implementation of the function is defined in a /// migration using `CREATE FUNCTION`. On SQLite, the function is implemented in /// Rust instead. You must call `register_impl` or -/// `register_nondeterministic_impl` with every connection before you can use -/// the function. +/// `register_nondeterministic_impl` (in the generated function's `_internals` +/// module) with every connection before you can use the function. /// /// These functions will only be generated if the `sqlite` feature is enabled, /// and the function is not generic. @@ -1163,13 +1134,13 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # } /// # /// use diesel::sql_types::{Integer, Double}; -/// sql_function!(fn add_mul(x: Integer, y: Integer, z: Double) -> Double); +/// define_sql_function!(fn add_mul(x: Integer, y: Integer, z: Double) -> Double); /// /// # #[cfg(feature = "sqlite")] /// # fn run_test() -> Result<(), Box> { /// let connection = &mut SqliteConnection::establish(":memory:")?; /// -/// add_mul::register_impl(connection, |x: i32, y: i32, z: f64| { +/// add_mul_utils::register_impl(connection, |x: i32, y: i32, z: f64| { /// (x + y) as f64 * z /// })?; /// @@ -1191,8 +1162,8 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// ## Custom Aggregate Functions /// /// Custom aggregate functions can be created in SQLite by adding an `#[aggregate]` -/// attribute inside `sql_function`. `register_impl` needs to be called on -/// the generated function with a type implementing the +/// attribute inside `define_sql_function`. `register_impl` (in the generated function's `_utils` +/// module) needs to be called with a type implementing the /// [SqliteAggregateFunction](../diesel/sqlite/trait.SqliteAggregateFunction.html) /// trait as a type parameter as shown in the examples below. /// @@ -1212,7 +1183,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # #[cfg(feature = "sqlite")] /// use diesel::sqlite::SqliteAggregateFunction; /// -/// sql_function! { +/// define_sql_function! { /// #[aggregate] /// fn my_sum(x: Integer) -> Integer; /// } @@ -1250,7 +1221,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # .execute(connection) /// # .unwrap(); /// -/// my_sum::register_impl::(connection)?; +/// my_sum_utils::register_impl::(connection)?; /// /// let total_score = players.select(my_sum(score)) /// .get_result::(connection)?; @@ -1280,7 +1251,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # #[cfg(feature = "sqlite")] /// use diesel::sqlite::SqliteAggregateFunction; /// -/// sql_function! { +/// define_sql_function! { /// #[aggregate] /// fn range_max(x0: Float, x1: Float) -> Nullable; /// } @@ -1330,7 +1301,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # .execute(connection) /// # .unwrap(); /// -/// range_max::register_impl::, _, _>(connection)?; +/// range_max_utils::register_impl::, _, _>(connection)?; /// /// let result = student_avgs.select(range_max(s1_avg, s2_avg)) /// .get_result::>(connection)?; @@ -1344,8 +1315,41 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// } /// ``` #[proc_macro] +pub fn define_sql_function(input: TokenStream) -> TokenStream { + sql_function::expand(parse_macro_input!(input), false).into() +} + +/// A legacy version of [`define_sql_function!`]. +/// +/// The difference is that it makes the helper type available in a module named the exact same as +/// the function: +/// +/// ```ignore +/// sql_function!(fn lower(x: Text) -> Text); +/// ``` +/// +/// will generate this code: +/// +/// ```ignore +/// pub fn lower(x: X) -> lower::HelperType { +/// ... +/// } +/// +/// pub(crate) mod lower { +/// pub type HelperType = ...; +/// } +/// ``` +/// +/// This turned out to be an issue for the support of the `auto_type` feature, which is why +/// [`define_sql_function!`] was introduced (and why this is deprecated). +/// +/// SQL functions declared with this version of the macro will not be usable with `#[auto_type]` +/// or `Selectable` `select_expression` type inference. +#[deprecated(since = "2.2.0", note = "Use [`define_sql_function`] instead")] +#[proc_macro] +#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))] pub fn sql_function_proc(input: TokenStream) -> TokenStream { - sql_function::expand(parse_macro_input!(input)).into() + sql_function::expand(parse_macro_input!(input), true).into() } /// This is an internal diesel macro that @@ -1545,7 +1549,7 @@ pub fn table_proc(input: TokenStream) -> TokenStream { } } -/// This derives implements [`diesel::Connection`] and related traits for an enum of +/// This derives implements `diesel::Connection` and related traits for an enum of /// connections to different databases. /// /// By applying this derive to such an enum, you can use the enum as a connection type in @@ -1554,12 +1558,12 @@ pub fn table_proc(input: TokenStream) -> TokenStream { /// `diesel::Connection` and a number of related traits. Connection types form Diesel itself /// as well as third party connection types are supported by this derive. /// -/// The implementation of [`diesel::Connection::establish`] tries to establish +/// The implementation of `diesel::Connection::establish` tries to establish /// a new connection with the given connection string in the order the connections /// are specified in the enum. If one connection fails, it tries the next one and so on. /// That means that as soon as more than one connection type accepts a certain connection /// string the first matching type in your enum will always establish the connection. This -/// is especially important if one of the connection types is [`diesel::SqliteConnection`] +/// is especially important if one of the connection types is `diesel::SqliteConnection` /// as this connection type accepts arbitrary paths. It should normally place as last entry /// in your enum. If you want control of which connection type is created, just construct the /// corresponding enum manually by first establishing the connection via the inner type and then @@ -1770,6 +1774,20 @@ pub fn derive_multiconnection(input: TokenStream) -> TokenStream { /// # Ok(()) /// # } /// ``` +/// # Limitations +/// +/// While this attribute tries to support as much of diesels built-in DSL as possible it's unfortunally not +/// possible to support everything. Notable unsupported types are: +/// +/// * Update statements +/// * Insert from select statements +/// * Select statements without from clause +/// * Query constructed by `diesel::sql_query` +/// * Expressions using `diesel::dsl::sql` +/// +/// For this cases a manual type annotation is required. See the "Annotating Types" section below +/// for details. +/// /// /// # Advanced usage /// diff --git a/diesel_derives/src/sql_function.rs b/diesel_derives/src/sql_function.rs index 9a9ed90fe59b..1f76d9d9adfd 100644 --- a/diesel_derives/src/sql_function.rs +++ b/diesel_derives/src/sql_function.rs @@ -8,7 +8,7 @@ use syn::{ PathArguments, Token, Type, }; -pub(crate) fn expand(input: SqlFunctionDecl) -> TokenStream { +pub(crate) fn expand(input: SqlFunctionDecl, legacy_helper_type_and_module: bool) -> TokenStream { let SqlFunctionDecl { mut attributes, fn_token, @@ -94,6 +94,8 @@ pub(crate) fn expand(input: SqlFunctionDecl) -> TokenStream { numeric_derive = Some(quote!(#[derive(diesel::sql_types::DieselNumericOps)])); } + let helper_type_doc = format!("The return type of [`{fn_name}()`](super::fn_name)"); + let args_iter = args.iter(); let mut tokens = quote! { use diesel::{self, QueryResult}; @@ -109,6 +111,7 @@ pub(crate) fn expand(input: SqlFunctionDecl) -> TokenStream { #(pub(in super) #type_args: ::std::marker::PhantomData<#type_args>,)* } + #[doc = #helper_type_doc] pub type HelperType #ty_generics = #fn_name < #(#type_args,)* #(<#arg_name as AsExpression<#arg_type>>::Expression,)* @@ -391,23 +394,44 @@ pub(crate) fn expand(input: SqlFunctionDecl) -> TokenStream { let args_iter = args.iter(); + let (outside_of_module_helper_type, return_type_path, internals_module_name) = + if legacy_helper_type_and_module { + (None, quote! { #fn_name::HelperType }, fn_name.clone()) + } else { + let internals_module_name = Ident::new(&format!("{fn_name}_utils"), fn_name.span()); + ( + Some(quote! { + #[allow(non_camel_case_types, non_snake_case)] + #[doc = #helper_type_doc] + pub type #fn_name #ty_generics = #internals_module_name::#fn_name < + #(#type_args,)* + #(<#arg_name as ::diesel::expression::AsExpression<#arg_type>>::Expression,)* + >; + }), + quote! { #fn_name }, + internals_module_name, + ) + }; + quote! { #(#attributes)* #[allow(non_camel_case_types)] pub #fn_token #fn_name #impl_generics (#(#args_iter,)*) - -> #fn_name::HelperType #ty_generics + -> #return_type_path #ty_generics #where_clause #(#arg_name: ::diesel::expression::AsExpression<#arg_type>,)* { - #fn_name::#fn_name { + #internals_module_name::#fn_name { #(#arg_struct_assign,)* #(#type_args: ::std::marker::PhantomData,)* } } + #outside_of_module_helper_type + #[doc(hidden)] #[allow(non_camel_case_types, non_snake_case, unused_imports)] - pub(crate) mod #fn_name { + pub(crate) mod #internals_module_name { #tokens } } diff --git a/diesel_derives/tests/auto_type.rs b/diesel_derives/tests/auto_type.rs new file mode 100644 index 000000000000..edaa2d3ab294 --- /dev/null +++ b/diesel_derives/tests/auto_type.rs @@ -0,0 +1,366 @@ +#![allow(dead_code)] // this is a compile pass test +use diesel::dsl::*; +use diesel::helper_types::*; +use diesel::prelude::*; + +table! { + users { + id -> Integer, + name -> Text, + time -> Timestamp, + } +} + +table! { + posts { + id -> Integer, + user_id -> Integer, + } +} + +table! { + posts2 { + id -> Integer, + user_id -> Integer, + } +} + +table! { + posts3 { + id -> Integer, + user_id -> Integer, + } +} + +#[cfg(feature = "postgres")] +table! { + pg_extras(id) { + id -> Integer, + json -> Json, + jsonb -> Jsonb, + net -> Inet, + array -> Array, + blob -> Binary, + timestamp -> Timestamp, + range -> Range, + } +} + +joinable!(posts -> users(user_id)); +joinable!(posts2 -> users(user_id)); +joinable!(posts3 -> users(user_id)); +allow_tables_to_appear_in_same_query!(users, posts, posts2, posts3); + +#[auto_type] +fn test_all_query_dsl() -> _ { + users::table + .distinct() + .filter(users::id.eq(42_i32)) + .find(42_i32) + .or_filter(users::id.eq(42_i32)) + .limit(23_i64) + .offset(12_i64) + .order(users::id) + .order_by(users::id) + .then_order_by(users::id) + .select(users::id) + .group_by(users::id) + .having(users::id.eq(32_i32)) + .inner_join(posts::table) + .left_join(posts2::table) + .inner_join(posts3::table.on(users::id.eq(posts3::user_id))) + //.into_boxed() +} + +#[auto_type] +fn single_value() -> _ { + users::table.select(users::id).find(42_i32).single_value() +} + +#[cfg(feature = "postgres")] +#[auto_type] +fn test_distinct_on() -> _ { + users::table.distinct_on(users::id) +} + +#[auto_type] +fn test_lock_dsl1() -> _ { + users::table.for_key_share().no_wait().skip_locked() +} + +#[auto_type] +fn test_lock_dsl2() -> _ { + users::table.for_no_key_update() +} + +#[auto_type] +fn test_lock_dsl3() -> _ { + users::table.for_share() +} + +#[auto_type] +fn test_lock_dsl4() -> _ { + users::table.for_update() +} + +// #[auto_type] +// fn test_count_query() -> _ { +// users::table.find(1_i32).count() +// } + +#[auto_type] +fn test_expression_methods() -> _ { + let v = 42_i32; + let v2: &'static [i32] = &[42]; + users::id + .eq(v) + .and(users::id.ne(v)) + .and(users::id.eq_any(v2)) + .and(users::id.ne_all(v2)) + .and(users::id.gt(v)) + .and(users::id.lt(v)) + .and(users::id.is_not_null()) + .and(users::id.is_null()) + .and(users::id.le(v)) + .and(users::id.ge(v)) + .and(users::id.between(v, v)) + .and(users::id.not_between(v, v)) +} + +#[auto_type] +fn test_boolean_expression_methods() -> _ { + let v = 42_i32; + users::id.eq(v).and(users::id.eq(v)).or(users::id.eq(v)) +} + +#[auto_type] +fn test_nullable_expression_methods() -> _ { + users::id.nullable().assume_not_null() +} + +#[auto_type] +fn test_text_expression_methods() -> _ { + let a: &'static str = "foo"; + users::name + .like(a) + .and(users::name.not_like(a)) + .and(users::name.concat(a).eq(a)) +} + +#[auto_type] +fn test_delete() -> _ { + delete(users::table) +} + +#[auto_type] +fn test_delete_2() -> _ { + delete(users::table.find(1_i32)) +} + +#[auto_type] +fn test_delete_3() -> _ { + delete(users::table).filter(users::id.eq(1_i32)) +} + +// #[auto_type] +// fn test_update() -> _ { +// update(users::table).set(users::id.eq(42_i32)) +// } + +#[auto_type] +fn test_insert1() -> _ { + insert_into(users::table).values(users::id.eq(42_i32)) +} + +/* +#[auto_type] +fn test_insert2() -> _ { + users::table.insert_into(users::table).into_columns(users::all_columns) +}*/ + +#[auto_type] +fn test_insert_or_ignore() -> _ { + insert_or_ignore_into(users::table).values(users::id.eq(42_i32)) +} + +#[auto_type] +fn test_insert_or_replace() -> _ { + replace_into(users::table).values(users::id.eq(42_i32)) +} + +/* +#[auto_type] +fn test_bare_select() -> _ { + select(1_i32.into_sql::()) +}*/ + +#[cfg(feature = "postgres")] +#[auto_type] +fn test_pg_expression_methods() -> _ { + let v = 42_i32; + users::id + .is_not_distinct_from(v) + .and(users::id.is_distinct_from(v)) +} + +#[cfg(feature = "postgres")] +#[auto_type] +fn test_pg_text_expression_methods() -> _ { + let a: &'static str = "foo"; + users::name + .ilike(a) + .and(users::name.not_ilike(a)) + .and(users::name.similar_to(a)) + .and(users::name.not_similar_to(a)) +} + +#[cfg(feature = "postgres")] +#[auto_type] +fn test_pg_net_expression_methods() -> _ { + // cannot be supported on diesel 2.x as the contains operator for net + // is different than the "normal" contains operator + // We could probably rename this function to `contains_net` to make it work + //pg_extras::net.contains(pg_extras::net) + pg_extras::net + .contains_or_eq(pg_extras::net) + // cannot be supported on diesel 2.x due to similar reasons + // as `contains` + //.and(pg_extras::net.is_contained_by(pg_extras::net)) + .and(pg_extras::net.is_contained_by_or_eq(pg_extras::net)) + .and(pg_extras::net.overlaps_with(pg_extras::net)) + // `.and()` and `or()` for inet cannot be supported as that name collides + // with `BoolExpressionMethods` + //.and(pg_extras::net.and(pg_extras::net).contains_or_eq(pg_extras::net)) + //.and(pg_extras::net.or(pg_extras::net).contains(pg_extras::net)) + .and(pg_extras::net.diff(pg_extras::net).eq(42_i64)) +} + +#[cfg(feature = "postgres")] +#[auto_type] +fn test_pg_array_expression_methods() -> _ { + let v = 42_i32; + pg_extras::array + .overlaps_with(pg_extras::array) + .and(pg_extras::array.contains(pg_extras::array)) + .and(pg_extras::array.is_contained_by(pg_extras::array)) + .and(pg_extras::array.index(v).eq(v)) + .and( + pg_extras::array + .concat(pg_extras::array) + .eq(pg_extras::array), + ) +} + +#[cfg(feature = "postgres")] +#[auto_type] +fn test_pg_jsonb_expression_methods() -> _ { + let s: &'static str = ""; + let v: &'static [&'static str] = &[]; + + pg_extras::jsonb + .concat(pg_extras::jsonb) + .eq(pg_extras::jsonb) + .and(pg_extras::jsonb.has_any_key(v)) + .and(pg_extras::jsonb.has_all_keys(v)) + .and(pg_extras::jsonb.has_key(s)) + .and(pg_extras::jsonb.contains(pg_extras::jsonb)) + .and(pg_extras::jsonb.remove(1_i32).eq(pg_extras::jsonb)) + .and(pg_extras::jsonb.remove_by_path(v).eq(pg_extras::jsonb)) + .and(pg_extras::jsonb.is_contained_by(pg_extras::jsonb)) +} + +// `.contains()` cannot be supported here as +// the type level constraints are slightly different +// for `Range<>` than for the other types that provide a `contains()` +// function. We could likely support it by +// renaming the function to `.range_contains()` (or something similar) +/* +#[cfg(feature = "postgres")] +#[auto_type] +fn test_pg_range_expression_methods() -> _ { + pg_extras::range.contains(42_i32) +}*/ + +#[cfg(feature = "postgres")] +#[auto_type] +fn test_pg_binary_expression_methods() -> _ { + let b: &'static [u8] = &[]; + pg_extras::blob + .concat(pg_extras::blob) + .like(pg_extras::blob) + .and(pg_extras::blob.not_like(b)) +} + +#[cfg(feature = "postgres")] +#[auto_type] +fn test_pg_any_json_expression_methods() -> _ { + let s: &'static str = ""; + let s2: &'static [&'static str] = &[]; + + pg_extras::jsonb + .retrieve_as_object(s) + .retrieve_as_text(s) + .eq(s) + .and( + pg_extras::jsonb + .retrieve_by_path_as_object(s2) + .retrieve_by_path_as_text(s2) + .eq(s), + ) +} + +#[cfg(feature = "postgres")] +#[auto_type] +fn test_pg_timestamp_expression_methods() -> _ { + let s: &'static str = ""; + pg_extras::timestamp.at_time_zone(s) +} + +#[cfg(feature = "sqlite")] +#[auto_type] +fn test_sqlite_expression_methods() -> _ { + users::id.is(42_i32).or(users::id.is_not(42_i32)) +} + +#[auto_type] +fn test_aggregate_functions() -> _ { + users::table.select(( + avg(users::id), + count(users::id), + count_distinct(users::id), + count_star(), + max(users::id), + min(users::id), + sum(users::id), + )) +} + +#[auto_type] +fn test_normal_functions() -> _ { + users::table.select(( + date(users::time), + exists(posts::table.select(posts::id)), + not(users::id.eq(1_i32)), + case_when(users::id.eq(1_i32), users::id), + case_when(users::id.eq(1_i32), users::id).when(users::id.eq(42_i32), users::id), + case_when(users::id.eq(1_i32), users::id) + .when(users::id.eq(42_i32), users::id) + .otherwise(users::id), + case_when(users::id.eq(1_i32), users::id).otherwise(users::id), + )) +} + +// #[auto_type] +// fn test_sql_fragment() -> _ { +// sql("foo") +// } + +// #[auto_type] +// fn test_sql_query_1() -> _ { +// sql_query("bar") +// } + +// #[auto_type] +// fn test_sql_query_2() -> _ { +// sql_query("bar").bind::(1) +// } diff --git a/diesel_derives/tests/tests.rs b/diesel_derives/tests/tests.rs index ab3afd70f351..a1ffbdc8a80c 100644 --- a/diesel_derives/tests/tests.rs +++ b/diesel_derives/tests/tests.rs @@ -9,6 +9,7 @@ mod schema; mod as_changeset; mod as_expression; mod associations; +mod auto_type; mod identifiable; mod insertable; mod multiconnection; diff --git a/diesel_tests/tests/annotations.rs b/diesel_tests/tests/annotations.rs index 7eb2caebc67b..841b4761f4da 100644 --- a/diesel_tests/tests/annotations.rs +++ b/diesel_tests/tests/annotations.rs @@ -286,7 +286,7 @@ fn derive_insertable_with_option_for_not_null_field_with_default() { assert_eq!(Some(&User::new(123, "Bob")), bob); } -sql_function!(fn nextval(a: Text) -> Integer); +define_sql_function!(fn nextval(a: Text) -> Integer); #[test] #[cfg(feature = "postgres")] @@ -294,7 +294,7 @@ fn derive_insertable_with_field_that_cannot_convert_expression_to_nullable() { #[derive(Insertable)] #[diesel(table_name = users)] struct NewUser { - id: nextval::HelperType<&'static str>, + id: nextval<&'static str>, name: &'static str, } diff --git a/diesel_tests/tests/expressions/mod.rs b/diesel_tests/tests/expressions/mod.rs index eabcb47795e9..3f074c123e2d 100644 --- a/diesel_tests/tests/expressions/mod.rs +++ b/diesel_tests/tests/expressions/mod.rs @@ -219,7 +219,7 @@ fn test_min() { assert_eq!(Ok(None::), source.first(connection)); } -sql_function!(fn coalesce(x: sql_types::Nullable, y: sql_types::VarChar) -> sql_types::VarChar); +define_sql_function!(fn coalesce(x: sql_types::Nullable, y: sql_types::VarChar) -> sql_types::VarChar); #[test] fn function_with_multiple_arguments() { @@ -445,7 +445,7 @@ fn test_arrays_a() { #[cfg(feature = "postgres")] use diesel::sql_types::{Array, Int4}; #[cfg(feature = "postgres")] -sql_function!(fn unnest(a: Array) -> Int4); +define_sql_function!(fn unnest(a: Array) -> Int4); #[test] #[cfg(feature = "postgres")] diff --git a/diesel_tests/tests/filter.rs b/diesel_tests/tests/filter.rs index 3d99733ebb86..a962b143a45f 100644 --- a/diesel_tests/tests/filter.rs +++ b/diesel_tests/tests/filter.rs @@ -412,7 +412,7 @@ fn not_affects_arguments_passed_when_they_contain_higher_operator_precedence() { } use diesel::sql_types::VarChar; -sql_function!(fn lower(x: VarChar) -> VarChar); +define_sql_function!(fn lower(x: VarChar) -> VarChar); #[test] fn filter_by_boxed_predicate() { diff --git a/diesel_tests/tests/joins.rs b/diesel_tests/tests/joins.rs index 24b85bab8b72..47bf6d38551c 100644 --- a/diesel_tests/tests/joins.rs +++ b/diesel_tests/tests/joins.rs @@ -358,7 +358,7 @@ fn select_then_join() { } use diesel::sql_types::Text; -sql_function!(fn lower(x: Text) -> Text); +define_sql_function!(fn lower(x: Text) -> Text); #[test] fn selecting_complex_expression_from_right_side_of_left_join() { diff --git a/diesel_tests/tests/macros.rs b/diesel_tests/tests/macros.rs index e5727b8d47aa..7a7a21563078 100644 --- a/diesel_tests/tests/macros.rs +++ b/diesel_tests/tests/macros.rs @@ -7,7 +7,7 @@ use crate::schema::*; use diesel::sql_types::{BigInt, VarChar}; use diesel::*; -sql_function!(fn my_lower(x: VarChar) -> VarChar); +define_sql_function!(fn my_lower(x: VarChar) -> VarChar); #[test] fn test_sql_function() { @@ -40,8 +40,8 @@ fn test_sql_function() { ); } -sql_function!(fn setval(x: VarChar, y: BigInt)); -sql_function!(fn currval(x: VarChar) -> BigInt); +define_sql_function!(fn setval(x: VarChar, y: BigInt)); +define_sql_function!(fn currval(x: VarChar) -> BigInt); #[test] fn sql_function_without_return_type() { diff --git a/diesel_tests/tests/schema/mod.rs b/diesel_tests/tests/schema/mod.rs index 7aad34912c19..8584e1b67971 100644 --- a/diesel_tests/tests/schema/mod.rs +++ b/diesel_tests/tests/schema/mod.rs @@ -318,7 +318,7 @@ pub fn drop_table_cascade(connection: &mut TestConnection, table: &str) { .unwrap(); } -sql_function!(fn nextval(a: sql_types::VarChar) -> sql_types::BigInt); +define_sql_function!(fn nextval(a: sql_types::VarChar) -> sql_types::BigInt); pub fn connection_with_sean_and_tess_in_users_table() -> TestConnection { let mut connection = connection(); diff --git a/examples/postgres/composite_types/README.md b/examples/postgres/composite_types/README.md index 52e6d3d1a8f1..8057440c477e 100644 --- a/examples/postgres/composite_types/README.md +++ b/examples/postgres/composite_types/README.md @@ -32,10 +32,10 @@ composite_type_db=# SELECT * FROM coordinates; The typical working flow when using Diesel is to automatically generate [schema.rs](./src/schema.rs) which provides us with the type information of the columns which are present in our coordinates table. Also, an SQL function, [distance_from_origin()](./migrations/2023-10-23-111951_composite2rust_coordinates/up.sql), -is defined. We need to explain this to the Rust compiler using the [sql_function!](https://docs.rs/diesel/latest/diesel/expression/functions/macro.sql_function.html) +is defined. We need to explain this to the Rust compiler using the [define_sql_function!](https://docs.rs/diesel/latest/diesel/expression/functions/macro.define_sql_function.html) macro like this: ```rust -sql_function!(fn distance_from_origin(re: Integer,im: Integer) -> Float); +define_sql_function!(fn distance_from_origin(re: Integer,im: Integer) -> Float); ``` Keep in mind that we specify [only postgreSQL types](https://docs.rs/diesel/latest/diesel/sql_types/index.html) as the input parameters and return value(s) of this function. If the columns @@ -48,7 +48,7 @@ let results: Vec<(i32, f32)> = coordinates ``` So we expect a vector of a 2-tuple, or ordered pair of the Rust types ```i32``` and ```f32```. Mind that the float type is not present in the table but is -specified in by the SQL function in the database and also in the macro `sql_function!` +specified in by the SQL function in the database and also in the macro `define_sql_function!` definition above. Of course we can expand this to very long tuples, but that will become error prone as we have to specify the sequence of type correctly every function call. Try out the [first example](./examples/composite2rust_coordinates) with: @@ -126,8 +126,8 @@ cargo run --example composite2rust_colors On the Rust side, we define the interpretation of both functions differently, the first one using a tuple similar to the coordinates example, the second one using a _locally_ defined Rust type for interpreting a tuple: notice the **Pg**-prefix of `PgGrayType`. ```rust -sql_function!(fn color2grey(r: Integer, g: Integer,b: Integer) -> Record<(Float,Text)>); -sql_function!(fn color2gray(r: Integer, g: Integer,b: Integer) -> PgGrayType); +define_sql_function!(fn color2grey(r: Integer, g: Integer,b: Integer) -> Record<(Float,Text)>); +define_sql_function!(fn color2gray(r: Integer, g: Integer,b: Integer) -> PgGrayType); ``` As this only creates a type with anonymous fields, which can be addressed by their field number **object.0**, **object.1** etc., it would be more convenient to attach names to the fields. Therefore we need to define a type with our intended field names, which we can use _globally_ (or at least outside the database related code space): ```rust diff --git a/examples/postgres/composite_types/examples/composite2rust_colors.rs b/examples/postgres/composite_types/examples/composite2rust_colors.rs index 1c87b368966b..9be65ec7522e 100644 --- a/examples/postgres/composite_types/examples/composite2rust_colors.rs +++ b/examples/postgres/composite_types/examples/composite2rust_colors.rs @@ -7,12 +7,12 @@ use diesel_postgres_composite_type::schema::colors::{ }; // Define the signature of the SQL function we want to call: +use diesel::define_sql_function; use diesel::pg::Pg; use diesel::pg::PgValue; -use diesel::sql_function; use diesel::sql_types::{Float, Integer, Record, Text}; -sql_function!(fn color2grey(r: Integer, g: Integer,b: Integer) -> Record<(Float,Text)>); -sql_function!(fn color2gray(r: Integer, g: Integer,b: Integer) -> PgGrayType); +define_sql_function!(fn color2grey(r: Integer, g: Integer,b: Integer) -> Record<(Float,Text)>); +define_sql_function!(fn color2gray(r: Integer, g: Integer,b: Integer) -> PgGrayType); // Needed to select, construct the query and submit it. use diesel::deserialize::{self, FromSql, FromSqlRow}; @@ -66,7 +66,7 @@ fn main() { ); } // Experiment 3: Similar, using the type also in the above listed - // sql_function!(...) definition. + // define_sql_function!(...) definition. let results: Vec<(i32, GrayType)> = colors .select((color_id, color2gray(red, green, blue))) .load(connection) diff --git a/examples/postgres/composite_types/examples/composite2rust_coordinates.rs b/examples/postgres/composite_types/examples/composite2rust_coordinates.rs index a785bdd6ed29..18e5ebc7a014 100644 --- a/examples/postgres/composite_types/examples/composite2rust_coordinates.rs +++ b/examples/postgres/composite_types/examples/composite2rust_coordinates.rs @@ -7,11 +7,11 @@ use diesel_postgres_composite_type::schema::coordinates::{ }; // Define the signature of the SQL function we want to call: -use diesel::sql_function; +use diesel::define_sql_function; use diesel::sql_types::Integer; -sql_function!(fn distance_from_origin(re: Integer,im: Integer) -> Float); -sql_function!(fn shortest_distance() -> Record<(Integer,Float)>); -sql_function!(fn longest_distance() -> Record<(Integer,Float)>); +define_sql_function!(fn distance_from_origin(re: Integer,im: Integer) -> Float); +define_sql_function!(fn shortest_distance() -> Record<(Integer,Float)>); +define_sql_function!(fn longest_distance() -> Record<(Integer,Float)>); // Needed to select, construct the query and submit it. use diesel::select; diff --git a/guide_drafts/migration_guide.md b/guide_drafts/migration_guide.md index 591c0354777d..2134ac41faa4 100644 --- a/guide_drafts/migration_guide.md +++ b/guide_drafts/migration_guide.md @@ -32,7 +32,7 @@ by the following changes: * [Changed `FromSql` implementations](#2-0-0-from-sql) `no_arg_sql_function!` macro is now pending deprecation. -Users of the macro are advised to consider `sql_function!` macro. +Users of the macro are advised to consider `define_sql_function!` macro. * [Deprecated usage of `no_arg_sql_function!` macro](#2-0-0-no_arg_sql_function) @@ -188,9 +188,9 @@ impl FromSql for YourType { ## `no_arg_sql_function` -The `no_arg_sql_function` was deprecated without direct replacement. At the same time the -`sql_function!` macro gained support for sql functions without argument. This support generates slightly -different code. Instead of representing the sql function as zero sized struct, `sql_function!` will generate an ordinary function call without arguments. This requires changing any usage of the generated dsl. This change +The `no_arg_sql_function` was deprecated without direct replacement. However the +`define_sql_function!` macro gained support for sql functions without argument. This support generates slightly +different code. Instead of representing the sql function as zero sized struct, `define_sql_function!` will generate an ordinary function call without arguments. This requires changing any usage of the generated dsl. This change affects all of the usages of the `no_arg_sql_function!` in third party crates. ```diff @@ -198,7 +198,7 @@ affects all of the usages of the `no_arg_sql_function!` in third party crates. - - diesel::select(now) -+ sql_function!{ ++ define_sql_function!{ + /// Represents the SQL NOW() function + fn now() -> sql_types::Timestamp; + }