From 5ece64ebd653b23ff804ce0c77f798fd2b614f3c Mon Sep 17 00:00:00 2001 From: Thomas BESSOU Date: Fri, 1 Sep 2023 18:32:46 +0200 Subject: [PATCH 01/12] propose sql_function_v2 --- diesel_derives/src/lib.rs | 55 ++++++++++++++++++++++++------ diesel_derives/src/sql_function.rs | 44 +++++++++++++++++++----- 2 files changed, 80 insertions(+), 19 deletions(-) diff --git a/diesel_derives/src/lib.rs b/diesel_derives/src/lib.rs index 7f4d95fdf72d..4b642dd55444 100644 --- a/diesel_derives/src/lib.rs +++ b/diesel_derives/src/lib.rs @@ -1011,7 +1011,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// function. For example, this invocation: /// /// ```ignore -/// sql_function!(fn lower(x: Text) -> Text); +/// sql_function_v2!(fn lower(x: Text) -> Text); /// ``` /// /// will generate this code: @@ -1036,7 +1036,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// use super::types::*; /// use diesel::sql_types::*; /// -/// sql_function! { +/// sql_function_v2! { /// /// Represents the Pg `LENGTH` function used with `tsvector`s. /// fn length(x: TsVector) -> Integer; /// } @@ -1066,7 +1066,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # /// use diesel::sql_types::Text; /// -/// sql_function! { +/// sql_function_v2! { /// /// Represents the `canon_crate_name` SQL function, created in /// /// migration .... /// fn canon_crate_name(a: Text) -> Text; @@ -1104,7 +1104,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # /// use diesel::sql_types::Foldable; /// -/// sql_function! { +/// sql_function_v2! { /// #[aggregate] /// #[sql_name = "SUM"] /// fn sum(expr: ST) -> ST::Sum; @@ -1119,7 +1119,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 `sql_function_v2!` like this: /// /// ```rust /// # extern crate diesel; @@ -1127,7 +1127,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # /// # table! { crates { id -> Integer, name -> VarChar, } } /// # -/// sql_function!(fn random() -> Text); +/// sql_function_v2!(fn random() -> Text); /// /// # fn main() { /// # use self::crates::dsl::*; @@ -1161,7 +1161,7 @@ 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); +/// sql_function_v2!(fn add_mul(x: Integer, y: Integer, z: Double) -> Double); /// /// # #[cfg(feature = "sqlite")] /// # fn run_test() -> Result<(), Box> { @@ -1189,7 +1189,7 @@ 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 +/// attribute inside `sql_function_v2`. `register_impl` needs to be called on /// the generated function with a type implementing the /// [SqliteAggregateFunction](../diesel/sqlite/trait.SqliteAggregateFunction.html) /// trait as a type parameter as shown in the examples below. @@ -1210,7 +1210,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # #[cfg(feature = "sqlite")] /// use diesel::sqlite::SqliteAggregateFunction; /// -/// sql_function! { +/// sql_function_v2! { /// #[aggregate] /// fn my_sum(x: Integer) -> Integer; /// } @@ -1278,7 +1278,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # #[cfg(feature = "sqlite")] /// use diesel::sqlite::SqliteAggregateFunction; /// -/// sql_function! { +/// sql_function_v2! { /// #[aggregate] /// fn range_max(x0: Float, x1: Float) -> Nullable; /// } @@ -1342,8 +1342,41 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// } /// ``` #[proc_macro] +pub fn sql_function_v2(input: TokenStream) -> TokenStream { + sql_function::expand(parse_macro_input!(input), false).into() +} + +/// A legacy version of [`sql_function_v2`]. +/// +/// 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 +/// [`sql_function_v2`] 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 = "Use [`sql_function_v2`] instead"] +#[proc_macro] 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 diff --git a/diesel_derives/src/sql_function.rs b/diesel_derives/src/sql_function.rs index 20e2f2013a43..40f58a6c49a5 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,15 @@ pub(crate) fn expand(input: SqlFunctionDecl) -> TokenStream { numeric_derive = Some(quote!(#[derive(diesel::sql_types::DieselNumericOps)])); } + let inside_module_helper_type = legacy_helper_type_and_module.then(|| { + quote! { + pub type HelperType #ty_generics = #fn_name < + #(#type_args,)* + #(<#arg_name as AsExpression<#arg_type>>::Expression,)* + >; + } + }); + let args_iter = args.iter(); let mut tokens = quote! { use diesel::{self, QueryResult}; @@ -109,10 +118,7 @@ pub(crate) fn expand(input: SqlFunctionDecl) -> TokenStream { #(pub(in super) #type_args: ::std::marker::PhantomData<#type_args>,)* } - pub type HelperType #ty_generics = #fn_name < - #(#type_args,)* - #(<#arg_name as AsExpression<#arg_type>>::Expression,)* - >; + #inside_module_helper_type impl #impl_generics Expression for #fn_name #ty_generics #where_clause @@ -391,23 +397,45 @@ 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 }, fn_name.clone()) + } else { + let internals_module_name = Ident::new(&format!("{fn_name}_internals"), fn_name.span()); + let doc = format!("The return type of [`{fn_name}()`]"); + ( + Some(quote! { + #[allow(non_camel_case_types, non_snake_case)] + #[doc = #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 } } From 6c635de724b42843d7bae3a843e77afbee4f92eb Mon Sep 17 00:00:00 2001 From: Thomas BESSOU Date: Fri, 1 Sep 2023 19:06:24 +0200 Subject: [PATCH 02/12] update uses inside Diesel to sql_function_v2 that should be almost always backwards compatible because the module was only pub(crate) anyway. It is not strictly backwards compatible because https://github.com/diesel-rs/diesel/issues/3745#issuecomment-1678796740 --- diesel/src/expression/count.rs | 4 ++-- .../expression/functions/aggregate_folding.rs | 6 ++--- .../functions/aggregate_ordering.rs | 6 ++--- .../src/expression/functions/date_and_time.rs | 4 ++-- .../src/expression/functions/helper_types.rs | 8 +++---- diesel/src/expression/functions/mod.rs | 4 ++-- diesel/src/expression/mod.rs | 4 ++-- diesel/src/lib.rs | 4 ++-- diesel/src/pg/connection/mod.rs | 2 +- diesel/src/pg/expression/functions.rs | 24 +++++++++---------- diesel/src/pg/metadata_lookup.rs | 2 +- diesel/src/sqlite/connection/mod.rs | 12 +++++----- diesel/src/sqlite/mod.rs | 4 ++-- .../src/sqlite/types/date_and_time/chrono.rs | 6 ++--- diesel/src/sqlite/types/date_and_time/time.rs | 6 ++--- .../information_schema.rs | 2 +- .../src/infer_schema_internals/mysql.rs | 2 +- diesel_cli/src/infer_schema_internals/pg.rs | 6 ++--- ...mix_aggregate_and_non_aggregate_selects.rs | 2 +- ...aggregate_and_non_aggregate_selects.stderr | 4 ++-- ...conflict_requires_valid_conflict_target.rs | 2 +- ...ressions_cant_be_used_in_a_sqlite_query.rs | 17 +++++++++---- ...ght_side_of_left_join_requires_nullable.rs | 2 +- ...side_of_left_join_requires_nullable.stderr | 20 ++++++++-------- ...d_functions_follow_same_selection_rules.rs | 11 +++++---- diesel_derives/src/lib.rs | 4 ++-- diesel_tests/tests/annotations.rs | 4 ++-- diesel_tests/tests/expressions/mod.rs | 4 ++-- diesel_tests/tests/filter.rs | 2 +- diesel_tests/tests/joins.rs | 2 +- diesel_tests/tests/macros.rs | 6 ++--- diesel_tests/tests/schema/mod.rs | 2 +- guide_drafts/migration_guide.md | 10 ++++---- 33 files changed, 103 insertions(+), 95 deletions(-) diff --git a/diesel/src/expression/count.rs b/diesel/src/expression/count.rs index 0a8ea4d2dbc4..eed36a887cc0 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::sql_function_v2; 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! { +sql_function_v2! { /// 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/functions/aggregate_folding.rs b/diesel/src/expression/functions/aggregate_folding.rs index fb8b9b2bd464..96c884ade9a2 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::sql_function_v2; use crate::sql_types::Foldable; -sql_function! { +sql_function_v2! { /// 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! { +sql_function_v2! { /// 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..1e09ea2b4fcd 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::sql_function_v2; -sql_function! { +sql_function_v2! { /// 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! { +sql_function_v2! { /// 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..40a76648d569 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::sql_function_v2; 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! { +sql_function_v2! { /// 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..44201b2e3b32 100644 --- a/diesel/src/expression/functions/mod.rs +++ b/diesel/src/expression/functions/mod.rs @@ -1,7 +1,7 @@ //! Helper macros to define custom sql functions #[doc(inline)] -pub use diesel_derives::sql_function_proc as sql_function; +pub use diesel_derives::{sql_function_proc as sql_function, sql_function_v2}; #[macro_export] #[doc(hidden)] @@ -73,7 +73,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 `sql_function_v2!` 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/mod.rs b/diesel/src/expression/mod.rs index 94ce18eb5386..496e57d35a43 100644 --- a/diesel/src/expression/mod.rs +++ b/diesel/src/expression/mod.rs @@ -70,7 +70,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; @@ -79,7 +79,7 @@ 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; diff --git a/diesel/src/lib.rs b/diesel/src/lib.rs index dff8dfbba3cf..1d1ff670c087 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 `sql_function_v2!` macro][`sql_function_v2!`]. //! //! [`std::ops`]: //doc.rust-lang.org/stable/std/ops/index.html //! @@ -639,7 +639,7 @@ pub mod prelude { }; #[doc(inline)] - pub use crate::expression::functions::sql_function; + pub use crate::expression::functions::{sql_function, sql_function_v2}; #[doc(inline)] pub use crate::expression::SelectableHelper; diff --git a/diesel/src/pg/connection/mod.rs b/diesel/src/pg/connection/mod.rs index 5e0e766f0d34..454c9fb5c446 100644 --- a/diesel/src/pg/connection/mod.rs +++ b/diesel/src/pg/connection/mod.rs @@ -489,7 +489,7 @@ mod tests { assert_eq!(2, connection.statement_cache.len()); } - sql_function!(fn lower(x: VarChar) -> VarChar); + sql_function_v2!(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/functions.rs b/diesel/src/pg/expression/functions.rs index 254856268564..f91b20b0c4f9 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::sql_function_v2; use crate::sql_types::*; -sql_function! { +sql_function_v2! { /// Creates an abbreviated display format as text. #[cfg(feature = "postgres_backend")] fn abbrev(addr: T) -> Text; } -sql_function! { +sql_function_v2! { /// Computes the broadcast address for the address's network. #[cfg(feature = "postgres_backend")] fn broadcast(addr: T) -> Inet; } -sql_function! { +sql_function_v2! { /// Returns the address's family: 4 for IPv4, 6 for IPv6. #[cfg(feature = "postgres_backend")] fn family(addr: T) -> Integer; } -sql_function! { +sql_function_v2! { /// Returns the IP address as text, ignoring the netmask. #[cfg(feature = "postgres_backend")] fn host(addr: T) -> Text; } -sql_function! { +sql_function_v2! { /// Computes the host mask for the address's network. #[cfg(feature = "postgres_backend")] fn hostmask(addr: T) -> Inet; } -sql_function! { +sql_function_v2! { /// 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! { +sql_function_v2! { /// 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! { +sql_function_v2! { /// Returns the netmask length in bits. #[cfg(feature = "postgres_backend")] fn masklen(addr: T) -> Integer; } -sql_function! { +sql_function_v2! { /// Computes the network mask for the address's network. #[cfg(feature = "postgres_backend")] fn netmask(addr: T) -> Inet; } -sql_function! { +sql_function_v2! { /// 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! { +sql_function_v2! { /// 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/metadata_lookup.rs b/diesel/src/pg/metadata_lookup.rs index f5385d0f35cf..94e2b754505c 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; } +sql_function_v2! { fn pg_my_temp_schema() -> Oid; } diff --git a/diesel/src/sqlite/connection/mod.rs b/diesel/src/sqlite/connection/mod.rs index 77f1990229ff..0bd8992e8340 100644 --- a/diesel/src/sqlite/connection/mod.rs +++ b/diesel/src/sqlite/connection/mod.rs @@ -486,7 +486,7 @@ mod tests { } use crate::sql_types::Text; - sql_function!(fn fun_case(x: Text) -> Text); + sql_function_v2!(fn fun_case(x: Text) -> Text); #[test] fn register_custom_function() { @@ -511,7 +511,7 @@ mod tests { assert_eq!("fOoBaR", mapped_string); } - sql_function!(fn my_add(x: Integer, y: Integer) -> Integer); + sql_function_v2!(fn my_add(x: Integer, y: Integer) -> Integer); #[test] fn register_multiarg_function() { @@ -522,7 +522,7 @@ mod tests { assert_eq!(Ok(3), added); } - sql_function!(fn answer() -> Integer); + sql_function_v2!(fn answer() -> Integer); #[test] fn register_noarg_function() { @@ -542,7 +542,7 @@ mod tests { assert_eq!(Ok(42), answer); } - sql_function!(fn add_counter(x: Integer) -> Integer); + sql_function_v2!(fn add_counter(x: Integer) -> Integer); #[test] fn register_nondeterministic_function() { @@ -561,7 +561,7 @@ mod tests { use crate::sqlite::SqliteAggregateFunction; - sql_function! { + sql_function_v2! { #[aggregate] fn my_sum(expr: Integer) -> Integer; } @@ -631,7 +631,7 @@ mod tests { assert_eq!(Ok(0), result); } - sql_function! { + sql_function_v2! { #[aggregate] fn range_max(expr1: Integer, expr2: Integer, expr3: Integer) -> Nullable; } diff --git a/diesel/src/sqlite/mod.rs b/diesel/src/sqlite/mod.rs index d4533a780d24..c50f9625680d 100644 --- a/diesel/src/sqlite/mod.rs +++ b/diesel/src/sqlite/mod.rs @@ -20,9 +20,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 `sql_function_v2!` /// macro for defining a custom SQLite aggregate function. See -/// the documentation [there](super::prelude::sql_function!) for details. +/// the documentation [there](super::prelude::sql_function_v2!) 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 5b57bea681fe..5efa6619d69e 100644 --- a/diesel/src/sqlite/types/date_and_time/chrono.rs +++ b/diesel/src/sqlite/types/date_and_time/chrono.rs @@ -249,9 +249,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); + sql_function_v2!(fn datetime(x: Text) -> Timestamp); + sql_function_v2!(fn time(x: Text) -> Time); + sql_function_v2!(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 41c993f6bb92..4cae16d67788 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); + sql_function_v2!(fn datetime(x: Text) -> Timestamp); + sql_function_v2!(fn time(x: Text) -> Time); + sql_function_v2!(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 b199209b1c22..d60fe94041e9 100644 --- a/diesel_cli/src/infer_schema_internals/information_schema.rs +++ b/diesel_cli/src/infer_schema_internals/information_schema.rs @@ -32,7 +32,7 @@ impl DefaultSchema for Pg { } #[cfg(feature = "mysql")] -sql_function!(fn database() -> VarChar); +sql_function_v2!(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 6a07a0443c1e..62f01a5be718 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::sql_function_v2! { #[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 79a69133ae4a..8ecd930da726 100644 --- a/diesel_cli/src/infer_schema_internals/pg.rs +++ b/diesel_cli/src/infer_schema_internals/pg.rs @@ -71,7 +71,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::sql_function_v2!(fn col_description(table: sql_types::Oid, column_number: sql_types::BigInt) -> sql_types::Nullable); pub fn get_table_data( conn: &mut PgConnection, @@ -140,7 +140,7 @@ where } } -sql_function!(fn obj_description(oid: sql_types::Oid, catalog: sql_types::Text) -> Nullable); +sql_function_v2!(fn obj_description(oid: sql_types::Oid, catalog: sql_types::Text) -> Nullable); pub fn get_table_comment( conn: &mut PgConnection, @@ -167,7 +167,7 @@ mod information_schema { } } -sql_function! { +sql_function_v2! { #[aggregate] fn array_agg(input: diesel::sql_types::Text) -> diesel::sql_types::Array; } 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..ac42c700c7d3 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); +sql_function_v2!(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 688813cb7268..dd946bdd8dd7 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 @@ -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); +14 | sql_function_v2!(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: this error originates in the macro `sql_function_v2` 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/pg_on_conflict_requires_valid_conflict_target.rs b/diesel_compile_tests/tests/fail/pg_on_conflict_requires_valid_conflict_target.rs index 6f4816a2695b..88043f33ade9 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); +sql_function_v2!(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_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..82215c89e738 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); +sql_function_v2!(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/right_side_of_left_join_requires_nullable.rs b/diesel_compile_tests/tests/fail/right_side_of_left_join_requires_nullable.rs index b3f110fc8e58..d4630e8e225a 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 @@ -29,7 +29,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); +sql_function_v2!(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 5893745b17b0..b3d7d2c2cc0e 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 @@ -88,9 +88,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:32:1 | -32 | sql_function!(fn lower(x: Text) -> Text); +32 | sql_function_v2!(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) + = note: this error originates in the macro `sql_function_v2` (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:48:25 @@ -192,9 +192,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:32:1 | -32 | sql_function!(fn lower(x: Text) -> Text); +32 | sql_function_v2!(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) + = note: this error originates in the macro `sql_function_v2` (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:65:25 @@ -296,9 +296,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:32:1 | -32 | sql_function!(fn lower(x: Text) -> Text); +32 | sql_function_v2!(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) + = note: this error originates in the macro `sql_function_v2` (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:82:25 @@ -400,9 +400,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:32:1 | -32 | sql_function!(fn lower(x: Text) -> Text); +32 | sql_function_v2!(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) + = note: this error originates in the macro `sql_function_v2` (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:97:25 @@ -504,9 +504,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:32:1 | -32 | sql_function!(fn lower(x: Text) -> Text); +32 | sql_function_v2!(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) + = note: this error originates in the macro `sql_function_v2` (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:112:25 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..dc11cc310e8a 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); +sql_function_v2!(fn foo(x: Integer) -> Integer); +sql_function_v2!(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_derives/src/lib.rs b/diesel_derives/src/lib.rs index 4b642dd55444..a1996e6ddbf9 100644 --- a/diesel_derives/src/lib.rs +++ b/diesel_derives/src/lib.rs @@ -1017,7 +1017,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// will generate this code: /// /// ```ignore -/// pub fn lower(x: X) -> lower::HelperType { +/// pub fn lower(x: X) -> lower { /// ... /// } /// @@ -1044,7 +1044,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// /// pub mod helper_types { /// /// The return type of `length(expr)` -/// pub type Length = functions::length::HelperType; +/// pub type Length = functions::length; /// } /// /// pub mod dsl { diff --git a/diesel_tests/tests/annotations.rs b/diesel_tests/tests/annotations.rs index 7eb2caebc67b..a2d9f4a2ac93 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); +sql_function_v2!(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 58a96053bb7c..f8ccf167b7d0 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); +sql_function_v2!(fn coalesce(x: sql_types::Nullable, y: sql_types::VarChar) -> sql_types::VarChar); #[test] fn function_with_multiple_arguments() { @@ -444,7 +444,7 @@ fn test_arrays_a() { #[cfg(feature = "postgres")] use diesel::sql_types::{Array, Int4}; #[cfg(feature = "postgres")] -sql_function!(fn unnest(a: Array) -> Int4); +sql_function_v2!(fn unnest(a: Array) -> Int4); #[test] #[cfg(feature = "postgres")] diff --git a/diesel_tests/tests/filter.rs b/diesel_tests/tests/filter.rs index 1e0067be16e1..28c903340564 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); +sql_function_v2!(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 bc4a447c480d..66a63b846753 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); +sql_function_v2!(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..673d48d8c3bb 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); +sql_function_v2!(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); +sql_function_v2!(fn setval(x: VarChar, y: BigInt)); +sql_function_v2!(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..76c22ce9b8ed 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); +sql_function_v2!(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/guide_drafts/migration_guide.md b/guide_drafts/migration_guide.md index 591c0354777d..b2db9c63a5c2 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 `sql_function_v2!` 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 +`sql_function_v2!` 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_v2!` 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!{ ++ sql_function_v2!{ + /// Represents the SQL NOW() function + fn now() -> sql_types::Timestamp; + } From 32e1484969e232a06ae6567981382a5519a12c8f Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Fri, 8 Sep 2023 14:07:22 +0200 Subject: [PATCH 03/12] Fix most type-defs for `#[auto_type]` by cleaning up all the type defs --- diesel/src/expression/case_when.rs | 2 +- diesel/src/expression/exists.rs | 4 +- .../src/expression/functions/helper_types.rs | 48 ++- diesel/src/expression/helper_types.rs | 17 +- diesel/src/expression/mod.rs | 38 +- diesel/src/expression/not.rs | 4 +- diesel/src/expression/operators.rs | 104 ++++- diesel/src/lib.rs | 37 +- diesel/src/pg/backend.rs | 3 + .../src/pg/expression/expression_methods.rs | 53 +-- diesel/src/pg/expression/helper_types.rs | 116 ++++-- diesel/src/pg/expression/operators.rs | 14 +- .../src/query_builder/insert_statement/mod.rs | 12 + .../src/query_builder/update_statement/mod.rs | 17 + diesel/src/query_dsl/limit_dsl.rs | 2 +- diesel/src/query_dsl/offset_dsl.rs | 2 +- diesel_compile_tests/Cargo.lock | 2 +- ...aggregate_and_non_aggregate_selects.stderr | 4 +- ...ary_expressions_only_usable_with_pg.stderr | 116 +----- diesel_derives/src/lib.rs | 24 +- diesel_derives/tests/auto_type.rs | 365 ++++++++++++++++++ diesel_derives/tests/tests.rs | 1 + 22 files changed, 783 insertions(+), 202 deletions(-) create mode 100644 diesel_derives/tests/auto_type.rs diff --git a/diesel/src/expression/case_when.rs b/diesel/src/expression/case_when.rs index e5c4df80279a..ae9925f66ee3 100644 --- a/diesel/src/expression/case_when.rs +++ b/diesel/src/expression/case_when.rs @@ -67,7 +67,7 @@ use super::{AsExpression, TypedExpressionType}; /// assert_eq!(&[(1, Some(1)), (2, Some(2))], users_with_name.as_slice()); /// # } /// ``` -pub fn case_when(condition: C, if_true: T) -> helper_types::case_when +pub fn case_when(condition: C, if_true: T) -> helper_types::CaseWhen where C: Expression, ::SqlType: BoolOrNullableBool, diff --git a/diesel/src/expression/exists.rs b/diesel/src/expression/exists.rs index 82779bfbc049..dd8f9a94795d 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/helper_types.rs b/diesel/src/expression/functions/helper_types.rs index ff757c350447..a9fde5c28f31 100644 --- a/diesel/src/expression/functions/helper_types.rs +++ b/diesel/src/expression/functions/helper_types.rs @@ -5,19 +5,55 @@ use crate::expression::grouped::Grouped; use crate::expression::operators; /// The return type of [`not(expr)`](crate::dsl::not()) -pub type not = operators::Not>; +pub type Not = operators::Not>; + +#[doc(hidden)] +// cannot put deprecated on this because rustc then +// also reports the function as deprecated +#[cfg(any(feature = "with-deprecated", not(feature = "without-deprecated")))] +pub type not = 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::HelperType, Expr>; + +#[doc(hidden)] +// cannot put deprecated on this because rustc then +// also reports the function as deprecated +#[cfg(any(feature = "with-deprecated", not(feature = "without-deprecated")))] +pub type max = Max; /// 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::HelperType, Expr>; + +#[doc(hidden)] +// cannot put deprecated on this because rustc then +// also reports the function as deprecated +#[cfg(any(feature = "with-deprecated", not(feature = "without-deprecated")))] +pub type min = Min; /// 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::HelperType, Expr>; + +#[doc(hidden)] +// cannot put deprecated on this because rustc then +// also reports the function as deprecated +#[cfg(any(feature = "with-deprecated", not(feature = "without-deprecated")))] +pub type sum = Sum; /// 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::HelperType, Expr>; + +#[doc(hidden)] +// cannot put deprecated on this because rustc then +// also reports the function as deprecated +#[cfg(any(feature = "with-deprecated", not(feature = "without-deprecated")))] +pub type avg = Avg; /// The return type of [`exists(expr)`](crate::dsl::exists()) -pub type exists = crate::expression::exists::Exists; +pub type Exists = crate::expression::exists::Exists; + +#[doc(hidden)] +// cannot put deprecated on this because rustc then +// also reports the function as deprecated +#[cfg(any(feature = "with-deprecated", not(feature = "without-deprecated")))] +pub type exists = Exists; diff --git a/diesel/src/expression/helper_types.rs b/diesel/src/expression/helper_types.rs index 5104b93a0c05..08c6004b7b34 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,11 @@ pub type Like = Grouped = Grouped>>>; /// The return type of [`case_when()`](expression::case_when::case_when) -#[allow(non_camel_case_types)] -pub type case_when::SqlType> = expression::case_when::CaseWhen< +pub type CaseWhen::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..84f85d1b3ffa 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::{CaseWhen, Otherwise, When}; + #[doc(inline)] pub use super::not::not; #[doc(inline)] pub use super::sql_literal::sql; @@ -73,21 +75,47 @@ 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::HelperType, Expr>; + + #[doc(hidden)] + // cannot put deprecated on this because rustc then + // also reports the function as deprecated + #[cfg(any(feature = "with-deprecated", not(feature = "without-deprecated")))] + pub type count = Count; /// The return type of [`count_star()`](crate::dsl::count_star()) - pub type count_star = super::count::CountStar; + pub type CountStar = super::count::CountStar; + + #[doc(hidden)] + // cannot put deprecated on this because rustc then + // also reports the function as deprecated + #[cfg(any(feature = "with-deprecated", not(feature = "without-deprecated")))] + pub type count_star = CountStar; /// The return type of [`count_distinct()`](crate::dsl::count_distinct()) - pub type count_distinct = super::count::CountDistinct, Expr>; + pub type CountDistinct = super::count::CountDistinct, Expr>; + + #[doc(hidden)] + // cannot put deprecated on this because rustc then + // also reports the function as deprecated + #[cfg(any(feature = "with-deprecated", not(feature = "without-deprecated")))] + pub type count_distinct = CountDistinct; /// 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::HelperType; + + #[doc(hidden)] + // cannot put deprecated on this because rustc then + // also reports the function as deprecated + #[cfg(any(feature = "with-deprecated", not(feature = "without-deprecated")))] + pub type date = 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..a225d8ec669b 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 ef8f22404528..ac60f8bd62aa 100644 --- a/diesel/src/lib.rs +++ b/diesel/src/lib.rs @@ -408,10 +408,10 @@ 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 = @@ -623,6 +623,39 @@ 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`] + pub type Delete = crate::query_builder::DeleteStatement< + ::Table, + ::WhereClause, + >; + + /// Represents the return type of [`diesel::insert_into`] + pub type InsertInto = crate::query_builder::IncompleteInsertStatement; + + /// Represents the return type of [`diesel::insert_or_ignore_into`] + pub type InsertOrIgnoreInto = crate::query_builder::IncompleteInsertOrIgnoreStatement; + + /// Represents the return type of [`diesel::replace_into`] + pub type ReplaceInto = 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 { 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/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/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/query_builder/insert_statement/mod.rs b/diesel/src/query_builder/insert_statement/mod.rs index 2d29a2a7b096..02613ea839bd 100644 --- a/diesel/src/query_builder/insert_statement/mod.rs +++ b/diesel/src/query_builder/insert_statement/mod.rs @@ -19,6 +19,8 @@ use crate::result::QueryResult; use crate::{insertable::*, QuerySource}; use std::marker::PhantomData; +pub(crate) use self::private::InsertAutoTypeHelper; + #[cfg(feature = "sqlite")] mod insert_with_default_for_sqlite; @@ -534,4 +536,14 @@ mod private { Ok(()) } } + + 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 c0a49941794c..fcc860165abd 100644 --- a/diesel/src/query_builder/update_statement/mod.rs +++ b/diesel/src/query_builder/update_statement/mod.rs @@ -17,6 +17,8 @@ use crate::result::Error::QueryBuilderError; use crate::result::QueryResult; use crate::{query_builder::*, QuerySource}; +pub(crate) use self::private::UpdateAutoTypeHelper; + impl UpdateStatement { pub(crate) fn new(target: UpdateTarget) -> Self { UpdateStatement { @@ -290,3 +292,18 @@ impl UpdateStatement { /// Indicates that you have not yet called `.set` on an update statement #[derive(Debug, Clone, Copy)] pub struct SetNotCalled; + +mod private { + 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..d6d617bc6a2e 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..b843b8b46484 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_compile_tests/Cargo.lock b/diesel_compile_tests/Cargo.lock index 618c9225cabe..218a72d183b8 100644 --- a/diesel_compile_tests/Cargo.lock +++ b/diesel_compile_tests/Cargo.lock @@ -99,7 +99,7 @@ dependencies = [ [[package]] name = "diesel" -version = "2.1.0" +version = "2.1.1" dependencies = [ "bigdecimal", "bitflags 2.2.1", 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..b27b147658d5 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 @@ -7,8 +7,8 @@ error[E0277]: the trait bound `diesel::expression::is_aggregate::No: MixedAggreg = help: the following other types implement trait `MixedAggregates`: > > - = note: required for `(columns::id, CountStar)` to implement `ValidGrouping<()>` - = note: required for `SelectStatement>` to implement `SelectDsl<(columns::id, CountStar)>` + = note: required for `(columns::id, diesel::expression::count::CountStar)` to implement `ValidGrouping<()>` + = note: required for `SelectStatement>` to implement `SelectDsl<(columns::id, diesel::expression::count::CountStar)>` error[E0277]: the trait bound `diesel::expression::is_aggregate::No: MixedAggregates` is not satisfied --> tests/fail/cannot_mix_aggregate_and_non_aggregate_selects.rs:22:24 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_derives/src/lib.rs b/diesel_derives/src/lib.rs index 7f4d95fdf72d..0a81dcd62a2d 100644 --- a/diesel_derives/src/lib.rs +++ b/diesel_derives/src/lib.rs @@ -1543,7 +1543,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 @@ -1552,12 +1552,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 @@ -1677,6 +1677,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 /// @@ -1751,7 +1765,7 @@ pub fn derive_multiconnection(input: TokenStream) -> TokenStream { /// // If we didn't specify the type for this query fragment, the macro would infer it as /// // `user_has_post_with_id_greater_than`, which would be incorrect because there is /// // no generic parameter. -/// let filter: user_has_post_with_id_greater_than = +/// let filter: UserHasPostWithIdGreaterThan = /// user_has_post_with_id_greater_than(id_greater_than); /// // The macro inferring that it has to pass generic parameters is still the convention /// // because it's the most general case, as well as the common case within Diesel itself, @@ -1792,4 +1806,4 @@ pub fn auto_type( } const AUTO_TYPE_DEFAULT_METHOD_TYPE_CASE: dsl_auto_type::Case = dsl_auto_type::Case::UpperCamel; -const AUTO_TYPE_DEFAULT_FUNCTION_TYPE_CASE: dsl_auto_type::Case = dsl_auto_type::Case::DoNotChange; +const AUTO_TYPE_DEFAULT_FUNCTION_TYPE_CASE: dsl_auto_type::Case = dsl_auto_type::Case::UpperCamel; diff --git a/diesel_derives/tests/auto_type.rs b/diesel_derives/tests/auto_type.rs new file mode 100644 index 000000000000..6977d4e0a803 --- /dev/null +++ b/diesel_derives/tests/auto_type.rs @@ -0,0 +1,365 @@ +#![allow(dead_code)] // this is a compile pass test +use diesel::dsl::*; +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; From 721f02641b7e2a6c0659c1729c02bd3b0ead6b78 Mon Sep 17 00:00:00 2001 From: Thomas BESSOU Date: Fri, 12 Jan 2024 14:18:31 +0100 Subject: [PATCH 04/12] fix ambiguous links --- diesel_derives/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/diesel_derives/src/lib.rs b/diesel_derives/src/lib.rs index a1996e6ddbf9..229c6572c424 100644 --- a/diesel_derives/src/lib.rs +++ b/diesel_derives/src/lib.rs @@ -1346,7 +1346,7 @@ pub fn sql_function_v2(input: TokenStream) -> TokenStream { sql_function::expand(parse_macro_input!(input), false).into() } -/// A legacy version of [`sql_function_v2`]. +/// A legacy version of [`sql_function_v2!`]. /// /// The difference is that it makes the helper type available in a module named the exact same as /// the function: @@ -1368,7 +1368,7 @@ pub fn sql_function_v2(input: TokenStream) -> TokenStream { /// ``` /// /// This turned out to be an issue for the support of the `auto_type` feature, which is why -/// [`sql_function_v2`] was introduced (and why this is deprecated). +/// [`sql_function_v2!`] 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. From f96c0dd736d6d465f74b3a3e930692991502bb37 Mon Sep 17 00:00:00 2001 From: Thomas BESSOU Date: Fri, 12 Jan 2024 14:33:21 +0100 Subject: [PATCH 05/12] doc correction in sql_function_v2 --- diesel_derives/src/lib.rs | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/diesel_derives/src/lib.rs b/diesel_derives/src/lib.rs index 229c6572c424..d3f263966681 100644 --- a/diesel_derives/src/lib.rs +++ b/diesel_derives/src/lib.rs @@ -1021,36 +1021,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// ... /// } /// -/// 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_v2! { -/// /// 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; -/// } -/// -/// 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 From c437eb0e496f70c8725ce04e9ba6f48bde3ec6b1 Mon Sep 17 00:00:00 2001 From: Thomas BESSOU Date: Fri, 12 Jan 2024 15:03:46 +0100 Subject: [PATCH 06/12] always generate the helper type in the module so that users have the flexibility of exporting the helper type without exporting the function if they want --- diesel_derives/src/sql_function.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/diesel_derives/src/sql_function.rs b/diesel_derives/src/sql_function.rs index fe7a94f27085..ee93407ed855 100644 --- a/diesel_derives/src/sql_function.rs +++ b/diesel_derives/src/sql_function.rs @@ -94,14 +94,7 @@ pub(crate) fn expand(input: SqlFunctionDecl, legacy_helper_type_and_module: bool numeric_derive = Some(quote!(#[derive(diesel::sql_types::DieselNumericOps)])); } - let inside_module_helper_type = legacy_helper_type_and_module.then(|| { - quote! { - pub type HelperType #ty_generics = #fn_name < - #(#type_args,)* - #(<#arg_name as AsExpression<#arg_type>>::Expression,)* - >; - } - }); + let helper_type_doc = format!("The return type of [`{fn_name}()`](super::fn_name)"); let args_iter = args.iter(); let mut tokens = quote! { @@ -118,7 +111,11 @@ pub(crate) fn expand(input: SqlFunctionDecl, legacy_helper_type_and_module: bool #(pub(in super) #type_args: ::std::marker::PhantomData<#type_args>,)* } - #inside_module_helper_type + #[doc = #helper_type_doc] + pub type HelperType #ty_generics = #fn_name < + #(#type_args,)* + #(<#arg_name as AsExpression<#arg_type>>::Expression,)* + >; impl #impl_generics Expression for #fn_name #ty_generics #where_clause @@ -402,11 +399,10 @@ pub(crate) fn expand(input: SqlFunctionDecl, legacy_helper_type_and_module: bool (None, quote! { #fn_name }, fn_name.clone()) } else { let internals_module_name = Ident::new(&format!("{fn_name}_internals"), fn_name.span()); - let doc = format!("The return type of [`{fn_name}()`]"); ( Some(quote! { #[allow(non_camel_case_types, non_snake_case)] - #[doc = #doc] + #[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,)* From 595740111c0d80118ed93606f2c9f432716dea5c Mon Sep 17 00:00:00 2001 From: Thomas BESSOU Date: Fri, 12 Jan 2024 15:12:48 +0100 Subject: [PATCH 07/12] Fix register_impl calls doc --- diesel/src/sqlite/connection/mod.rs | 16 ++++++++-------- diesel_derives/src/lib.rs | 14 +++++++------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/diesel/src/sqlite/connection/mod.rs b/diesel/src/sqlite/connection/mod.rs index d1cee42d3d0e..497cad817c45 100644 --- a/diesel/src/sqlite/connection/mod.rs +++ b/diesel/src/sqlite/connection/mod.rs @@ -639,7 +639,7 @@ mod tests { #[test] fn register_custom_function() { let connection = &mut SqliteConnection::establish(":memory:").unwrap(); - fun_case::register_impl(connection, |x: String| { + fun_case_internals::register_impl(connection, |x: String| { x.chars() .enumerate() .map(|(i, c)| { @@ -664,7 +664,7 @@ mod tests { #[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_internals::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); @@ -675,7 +675,7 @@ mod tests { #[test] fn register_noarg_function() { let connection = &mut SqliteConnection::establish(":memory:").unwrap(); - answer::register_impl(connection, || 42).unwrap(); + answer_internals::register_impl(connection, || 42).unwrap(); let answer = crate::select(answer()).get_result::(connection); assert_eq!(Ok(42), answer); @@ -684,7 +684,7 @@ mod tests { #[test] fn register_nondeterministic_noarg_function() { let connection = &mut SqliteConnection::establish(":memory:").unwrap(); - answer::register_nondeterministic_impl(connection, || 42).unwrap(); + answer_internals::register_nondeterministic_impl(connection, || 42).unwrap(); let answer = crate::select(answer()).get_result::(connection); assert_eq!(Ok(42), answer); @@ -696,7 +696,7 @@ mod tests { 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_internals::register_nondeterministic_impl(connection, move |x: i32| { y += 1; x + y }) @@ -752,7 +752,7 @@ mod tests { .execute(connection) .unwrap(); - my_sum::register_impl::(connection).unwrap(); + my_sum_internals::register_impl::(connection).unwrap(); let result = my_sum_example .select(my_sum(value)) @@ -771,7 +771,7 @@ mod tests { .execute(connection) .unwrap(); - my_sum::register_impl::(connection).unwrap(); + my_sum_internals::register_impl::(connection).unwrap(); let result = my_sum_example .select(my_sum(value)) @@ -843,7 +843,7 @@ mod tests { .execute(connection) .unwrap(); - range_max::register_impl::, _, _, _>(connection).unwrap(); + range_max_internals::register_impl::, _, _, _>(connection).unwrap(); let result = range_max_example .select(range_max(value1, value2, value3)) .get_result::>(connection) diff --git a/diesel_derives/src/lib.rs b/diesel_derives/src/lib.rs index 3caa8581c0ec..85dd45bd8de8 100644 --- a/diesel_derives/src/lib.rs +++ b/diesel_derives/src/lib.rs @@ -1113,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. @@ -1140,7 +1140,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # fn run_test() -> Result<(), Box> { /// let connection = &mut SqliteConnection::establish(":memory:")?; /// -/// add_mul::register_impl(connection, |x: i32, y: i32, z: f64| { +/// add_mul_internals::register_impl(connection, |x: i32, y: i32, z: f64| { /// (x + y) as f64 * z /// })?; /// @@ -1162,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_v2`. `register_impl` needs to be called on -/// the generated function with a type implementing the +/// attribute inside `sql_function_v2`. `register_impl` (in the generated function's `_internals` +/// 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. /// @@ -1221,7 +1221,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # .execute(connection) /// # .unwrap(); /// -/// my_sum::register_impl::(connection)?; +/// my_sum_internals::register_impl::(connection)?; /// /// let total_score = players.select(my_sum(score)) /// .get_result::(connection)?; @@ -1301,7 +1301,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # .execute(connection) /// # .unwrap(); /// -/// range_max::register_impl::, _, _>(connection)?; +/// range_max_internals::register_impl::, _, _>(connection)?; /// /// let result = student_avgs.select(range_max(s1_avg, s2_avg)) /// .get_result::>(connection)?; From a3858e9143eae05c04aaac61708b4c9ba147944a Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Fri, 8 Mar 2024 11:35:09 +0100 Subject: [PATCH 08/12] Rename the `sql_function_v2!` macro to `define_sql_function` --- diesel/src/expression/case_when.rs | 2 +- diesel/src/expression/count.rs | 4 +- diesel/src/expression/exists.rs | 2 +- .../expression/functions/aggregate_folding.rs | 6 +- .../functions/aggregate_ordering.rs | 6 +- .../src/expression/functions/date_and_time.rs | 4 +- diesel/src/expression/functions/mod.rs | 8 ++- diesel/src/expression/helper_types.rs | 3 +- diesel/src/expression/mod.rs | 2 +- diesel/src/expression/not.rs | 2 +- diesel/src/lib.rs | 18 +++-- diesel/src/pg/connection/mod.rs | 2 +- diesel/src/pg/expression/functions.rs | 24 +++---- diesel/src/pg/metadata_lookup.rs | 2 +- .../src/query_builder/insert_statement/mod.rs | 2 + .../src/query_builder/update_statement/mod.rs | 2 + diesel/src/sqlite/connection/mod.rs | 12 ++-- diesel/src/sqlite/mod.rs | 4 +- .../src/sqlite/types/date_and_time/chrono.rs | 6 +- diesel/src/sqlite/types/date_and_time/time.rs | 6 +- .../information_schema.rs | 2 +- .../src/infer_schema_internals/mysql.rs | 2 +- diesel_cli/src/infer_schema_internals/pg.rs | 6 +- ...ion_requires_column_from_same_table.stderr | 64 ++++++++--------- ...mix_aggregate_and_non_aggregate_selects.rs | 2 +- ...aggregate_and_non_aggregate_selects.stderr | 14 ++-- .../cannot_pass_aggregate_to_where.stderr | 2 +- ...tom_returning_requires_nonaggregate.stderr | 4 +- ...quires_bool_nonaggregate_expression.stderr | 2 +- .../ordering_functions_require_ord.stderr | 8 +-- ...conflict_requires_valid_conflict_target.rs | 2 +- ...lict_requires_valid_conflict_target.stderr | 6 +- ...ressions_cant_be_used_in_a_sqlite_query.rs | 2 +- ...ions_cant_be_used_in_a_sqlite_query.stderr | 27 +++---- ...ght_side_of_left_join_requires_nullable.rs | 2 +- ...side_of_left_join_requires_nullable.stderr | 70 +++++++++---------- .../tests/fail/selectable.stderr | 2 +- ...d_functions_follow_same_selection_rules.rs | 4 +- ...nctions_follow_same_selection_rules.stderr | 14 ++-- diesel_derives/src/lib.rs | 38 +++++----- diesel_derives/src/sql_function.rs | 2 +- diesel_derives/tests/auto_type.rs | 1 + diesel_tests/tests/annotations.rs | 2 +- diesel_tests/tests/expressions/mod.rs | 4 +- diesel_tests/tests/filter.rs | 2 +- diesel_tests/tests/joins.rs | 2 +- diesel_tests/tests/macros.rs | 6 +- diesel_tests/tests/schema/mod.rs | 2 +- guide_drafts/migration_guide.md | 8 +-- 49 files changed, 218 insertions(+), 201 deletions(-) diff --git a/diesel/src/expression/case_when.rs b/diesel/src/expression/case_when.rs index ae9925f66ee3..e5c4df80279a 100644 --- a/diesel/src/expression/case_when.rs +++ b/diesel/src/expression/case_when.rs @@ -67,7 +67,7 @@ use super::{AsExpression, TypedExpressionType}; /// assert_eq!(&[(1, Some(1)), (2, Some(2))], users_with_name.as_slice()); /// # } /// ``` -pub fn case_when(condition: C, if_true: T) -> helper_types::CaseWhen +pub fn case_when(condition: C, if_true: T) -> helper_types::case_when where C: Expression, ::SqlType: BoolOrNullableBool, diff --git a/diesel/src/expression/count.rs b/diesel/src/expression/count.rs index eed36a887cc0..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_v2; +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_v2! { +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 dd8f9a94795d..ff6a8d5d65cf 100644 --- a/diesel/src/expression/exists.rs +++ b/diesel/src/expression/exists.rs @@ -32,7 +32,7 @@ use crate::sql_types::Bool; /// assert_eq!(Ok(false), jim_exists); /// # } /// ``` -pub fn exists(query: T) -> helper_types::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 96c884ade9a2..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_v2; +use crate::expression::functions::define_sql_function; use crate::sql_types::Foldable; -sql_function_v2! { +define_sql_function! { /// Represents a SQL `SUM` function. This function can only take types which are /// Foldable. /// @@ -21,7 +21,7 @@ sql_function_v2! { fn sum(expr: ST) -> ST::Sum; } -sql_function_v2! { +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 1e09ea2b4fcd..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_v2; +use crate::expression::functions::define_sql_function; -sql_function_v2! { +define_sql_function! { /// Represents a SQL `MAX` function. This function can only take types which are /// ordered. /// @@ -20,7 +20,7 @@ sql_function_v2! { fn max(expr: ST) -> ST::Ret; } -sql_function_v2! { +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 40a76648d569..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_v2; +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_v2! { +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/mod.rs b/diesel/src/expression/functions/mod.rs index 44201b2e3b32..db8f79e7a730 100644 --- a/diesel/src/expression/functions/mod.rs +++ b/diesel/src/expression/functions/mod.rs @@ -1,7 +1,11 @@ //! Helper macros to define custom sql functions #[doc(inline)] -pub use diesel_derives::{sql_function_proc as sql_function, sql_function_v2}; +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] #[doc(hidden)] @@ -73,7 +77,7 @@ macro_rules! no_arg_sql_function_body { /// function. #[deprecated( since = "2.0.0", - note = "Use `sql_function_v2!` 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 08c6004b7b34..4ca14ad6daa7 100644 --- a/diesel/src/expression/helper_types.rs +++ b/diesel/src/expression/helper_types.rs @@ -134,7 +134,8 @@ pub type Like = Grouped = Grouped>>>; /// The return type of [`case_when()`](expression::case_when::case_when) -pub type CaseWhen::SqlType> = expression::case_when::CaseWhen< +#[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, >; diff --git a/diesel/src/expression/mod.rs b/diesel/src/expression/mod.rs index 767db4e9741a..be3c47d2a466 100644 --- a/diesel/src/expression/mod.rs +++ b/diesel/src/expression/mod.rs @@ -65,7 +65,7 @@ pub(crate) mod dsl { #[doc(inline)] pub use super::functions::date_and_time::*; #[doc(inline)] - pub use super::helper_types::{CaseWhen, Otherwise, When}; + pub use super::helper_types::{case_when, Otherwise, When}; #[doc(inline)] pub use super::not::not; #[doc(inline)] diff --git a/diesel/src/expression/not.rs b/diesel/src/expression/not.rs index a225d8ec669b..8280dc218c3f 100644 --- a/diesel/src/expression/not.rs +++ b/diesel/src/expression/not.rs @@ -23,7 +23,7 @@ use crate::sql_types::BoolOrNullableBool; /// assert_eq!(Ok(2), users_not_with_name.first(connection)); /// # } /// ``` -pub fn not(expr: T) -> helper_types::Not +pub fn not(expr: T) -> helper_types::not where T: Expression, ::SqlType: BoolOrNullableBool, diff --git a/diesel/src/lib.rs b/diesel/src/lib.rs index f1396166d4b0..682ebd73683d 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_v2!` macro][`sql_function_v2!`]. +//! with [the `define_sql_function!` macro][`define_sql_function!`]. //! //! [`std::ops`]: //doc.rust-lang.org/stable/std/ops/index.html //! @@ -625,19 +625,23 @@ pub mod helper_types { >::RowIter<'conn>; /// Represents the return type of [`diesel::delete`] - pub type Delete = crate::query_builder::DeleteStatement< + #[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`] - pub type InsertInto = crate::query_builder::IncompleteInsertStatement; + #[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`] - pub type InsertOrIgnoreInto = crate::query_builder::IncompleteInsertOrIgnoreStatement; + #[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`] - pub type ReplaceInto = crate::query_builder::IncompleteReplaceStatement; + #[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) @@ -673,7 +677,9 @@ pub mod prelude { }; #[doc(inline)] - pub use crate::expression::functions::{sql_function, sql_function_v2}; + 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)] pub use crate::expression::SelectableHelper; diff --git a/diesel/src/pg/connection/mod.rs b/diesel/src/pg/connection/mod.rs index b8b3a9424fe5..a774292b1fe6 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_v2!(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/functions.rs b/diesel/src/pg/expression/functions.rs index f91b20b0c4f9..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_v2; +use crate::expression::functions::define_sql_function; use crate::sql_types::*; -sql_function_v2! { +define_sql_function! { /// Creates an abbreviated display format as text. #[cfg(feature = "postgres_backend")] fn abbrev(addr: T) -> Text; } -sql_function_v2! { +define_sql_function! { /// Computes the broadcast address for the address's network. #[cfg(feature = "postgres_backend")] fn broadcast(addr: T) -> Inet; } -sql_function_v2! { +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_v2! { +define_sql_function! { /// Returns the IP address as text, ignoring the netmask. #[cfg(feature = "postgres_backend")] fn host(addr: T) -> Text; } -sql_function_v2! { +define_sql_function! { /// Computes the host mask for the address's network. #[cfg(feature = "postgres_backend")] fn hostmask(addr: T) -> Inet; } -sql_function_v2! { +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_v2! { +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_v2! { +define_sql_function! { /// Returns the netmask length in bits. #[cfg(feature = "postgres_backend")] fn masklen(addr: T) -> Integer; } -sql_function_v2! { +define_sql_function! { /// Computes the network mask for the address's network. #[cfg(feature = "postgres_backend")] fn netmask(addr: T) -> Inet; } -sql_function_v2! { +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_v2! { +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/metadata_lookup.rs b/diesel/src/pg/metadata_lookup.rs index 16aaf2f65076..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_v2! { fn pg_my_temp_schema() -> Oid; } +define_sql_function! { fn pg_my_temp_schema() -> Oid; } diff --git a/diesel/src/query_builder/insert_statement/mod.rs b/diesel/src/query_builder/insert_statement/mod.rs index 02613ea839bd..f317b03f9001 100644 --- a/diesel/src/query_builder/insert_statement/mod.rs +++ b/diesel/src/query_builder/insert_statement/mod.rs @@ -537,6 +537,8 @@ 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 InsertAutoTypeHelper { type Table; type Op; diff --git a/diesel/src/query_builder/update_statement/mod.rs b/diesel/src/query_builder/update_statement/mod.rs index fcc860165abd..2384826d8ae8 100644 --- a/diesel/src/query_builder/update_statement/mod.rs +++ b/diesel/src/query_builder/update_statement/mod.rs @@ -294,6 +294,8 @@ impl UpdateStatement { 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; diff --git a/diesel/src/sqlite/connection/mod.rs b/diesel/src/sqlite/connection/mod.rs index 497cad817c45..e2b058d844c5 100644 --- a/diesel/src/sqlite/connection/mod.rs +++ b/diesel/src/sqlite/connection/mod.rs @@ -634,7 +634,7 @@ mod tests { } use crate::sql_types::Text; - sql_function_v2!(fn fun_case(x: Text) -> Text); + define_sql_function!(fn fun_case(x: Text) -> Text); #[test] fn register_custom_function() { @@ -659,7 +659,7 @@ mod tests { assert_eq!("fOoBaR", mapped_string); } - sql_function_v2!(fn my_add(x: Integer, y: Integer) -> Integer); + define_sql_function!(fn my_add(x: Integer, y: Integer) -> Integer); #[test] fn register_multiarg_function() { @@ -670,7 +670,7 @@ mod tests { assert_eq!(Ok(3), added); } - sql_function_v2!(fn answer() -> Integer); + define_sql_function!(fn answer() -> Integer); #[test] fn register_noarg_function() { @@ -690,7 +690,7 @@ mod tests { assert_eq!(Ok(42), answer); } - sql_function_v2!(fn add_counter(x: Integer) -> Integer); + define_sql_function!(fn add_counter(x: Integer) -> Integer); #[test] fn register_nondeterministic_function() { @@ -709,7 +709,7 @@ mod tests { use crate::sqlite::SqliteAggregateFunction; - sql_function_v2! { + define_sql_function! { #[aggregate] fn my_sum(expr: Integer) -> Integer; } @@ -779,7 +779,7 @@ mod tests { assert_eq!(Ok(0), result); } - sql_function_v2! { + define_sql_function! { #[aggregate] fn range_max(expr1: Integer, expr2: Integer, expr3: Integer) -> Nullable; } diff --git a/diesel/src/sqlite/mod.rs b/diesel/src/sqlite/mod.rs index 40bd37f7da26..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_v2!` +/// 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_v2!) 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 d76948d8a26c..679dd90dd767 100644 --- a/diesel/src/sqlite/types/date_and_time/chrono.rs +++ b/diesel/src/sqlite/types/date_and_time/chrono.rs @@ -249,9 +249,9 @@ mod tests { use crate::sql_types::{Text, Time, Timestamp, TimestamptzSqlite}; use crate::test_helpers::connection; - sql_function_v2!(fn datetime(x: Text) -> Timestamp); - sql_function_v2!(fn time(x: Text) -> Time); - sql_function_v2!(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 13c66c24544a..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_v2!(fn datetime(x: Text) -> Timestamp); - sql_function_v2!(fn time(x: Text) -> Time); - sql_function_v2!(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 47669edf66f1..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_v2!(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 586d71c25422..c1ec114b05f7 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_v2! { +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 94aded110dba..38f8bae1ed15 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_v2!(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_v2!(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_v2! { +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 3d968c04a64a..0f9dfcb21c34 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 @@ -12,8 +12,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 @@ -27,9 +27,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 @@ -51,9 +51,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 @@ -69,8 +69,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 @@ -84,9 +84,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 @@ -108,9 +108,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 @@ -126,8 +126,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 @@ -141,9 +141,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 @@ -165,9 +165,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 @@ -183,8 +183,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 @@ -198,9 +198,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 @@ -222,6 +222,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 ac42c700c7d3..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_v2!(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 a49abab4ea5e..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 @@ -7,8 +7,8 @@ error[E0277]: the trait bound `diesel::expression::is_aggregate::No: MixedAggreg = help: the following other types implement trait `MixedAggregates`: > > - = note: required for `(columns::id, diesel::expression::count::CountStar)` to implement `ValidGrouping<()>` - = note: required for `SelectStatement>` to implement `SelectDsl<(columns::id, diesel::expression::count::CountStar)>` + = note: required for `(columns::id, CountStar)` to implement `ValidGrouping<()>` + = note: required for `SelectStatement>` to implement `SelectDsl<(columns::id, CountStar)>` error[E0277]: the trait bound `diesel::expression::is_aggregate::No: MixedAggregates` is not satisfied --> tests/fail/cannot_mix_aggregate_and_non_aggregate_selects.rs:22:24 @@ -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_v2!(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_v2` 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 88043f33ade9..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_v2!(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_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 82215c89e738..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_v2!(fn lower(x: VarChar) -> VarChar); +define_sql_function!(fn lower(x: VarChar) -> VarChar); #[derive(Insertable)] #[diesel(table_name = users)] 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 71934d2dd4cd..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_v2!(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 d7137daa624e..975359e80bec 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 @@ -48,8 +48,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 @@ -71,8 +71,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 @@ -88,9 +88,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_v2!(fn lower(x: Text) -> Text); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `lower` - = note: this error originates in the macro `sql_function_v2` (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 @@ -152,8 +152,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 @@ -175,8 +175,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 @@ -192,9 +192,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_v2!(fn lower(x: Text) -> Text); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `lower` - = note: this error originates in the macro `sql_function_v2` (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 @@ -256,8 +256,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 @@ -279,8 +279,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 @@ -296,9 +296,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_v2!(fn lower(x: Text) -> Text); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `lower` - = note: this error originates in the macro `sql_function_v2` (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 @@ -360,8 +360,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 @@ -383,8 +383,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 @@ -400,9 +400,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_v2!(fn lower(x: Text) -> Text); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `lower` - = note: this error originates in the macro `sql_function_v2` (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 @@ -464,8 +464,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 @@ -487,8 +487,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 @@ -504,9 +504,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_v2!(fn lower(x: Text) -> Text); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `lower` - = note: this error originates in the macro `sql_function_v2` (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 1a3da42c947a..0b78df3b1620 100644 --- a/diesel_compile_tests/tests/fail/selectable.stderr +++ b/diesel_compile_tests/tests/fail/selectable.stderr @@ -230,7 +230,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 dc11cc310e8a..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 @@ -23,8 +23,8 @@ struct User { name: String, } -sql_function_v2!(fn foo(x: Integer) -> Integer); -sql_function_v2!(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::posts::title; 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 db80411b3078..6393ac83363a 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 @@ -55,7 +55,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 b505a3dbc180..c16532bec75f 100644 --- a/diesel_derives/src/lib.rs +++ b/diesel_derives/src/lib.rs @@ -1013,7 +1013,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// function. For example, this invocation: /// /// ```ignore -/// sql_function_v2!(fn lower(x: Text) -> Text); +/// define_sql_function!(fn lower(x: Text) -> Text); /// ``` /// /// will generate this code: @@ -1039,7 +1039,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # /// use diesel::sql_types::Text; /// -/// sql_function_v2! { +/// define_sql_function! { /// /// Represents the `canon_crate_name` SQL function, created in /// /// migration .... /// fn canon_crate_name(a: Text) -> Text; @@ -1077,7 +1077,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # /// use diesel::sql_types::Foldable; /// -/// sql_function_v2! { +/// define_sql_function! { /// #[aggregate] /// #[sql_name = "SUM"] /// fn sum(expr: ST) -> ST::Sum; @@ -1092,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_v2!` like this: +/// which can be implemented using `define_sql_function!` like this: /// /// ```rust /// # extern crate diesel; @@ -1100,7 +1100,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # /// # table! { crates { id -> Integer, name -> VarChar, } } /// # -/// sql_function_v2!(fn random() -> Text); +/// define_sql_function!(fn random() -> Text); /// /// # fn main() { /// # use self::crates::dsl::*; @@ -1134,13 +1134,13 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # } /// # /// use diesel::sql_types::{Integer, Double}; -/// sql_function_v2!(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_internals::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 /// })?; /// @@ -1162,7 +1162,7 @@ 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_v2`. `register_impl` (in the generated function's `_internals` +/// 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. @@ -1183,7 +1183,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # #[cfg(feature = "sqlite")] /// use diesel::sqlite::SqliteAggregateFunction; /// -/// sql_function_v2! { +/// define_sql_function! { /// #[aggregate] /// fn my_sum(x: Integer) -> Integer; /// } @@ -1221,7 +1221,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # .execute(connection) /// # .unwrap(); /// -/// my_sum_internals::register_impl::(connection)?; +/// my_sum_utils::register_impl::(connection)?; /// /// let total_score = players.select(my_sum(score)) /// .get_result::(connection)?; @@ -1251,7 +1251,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # #[cfg(feature = "sqlite")] /// use diesel::sqlite::SqliteAggregateFunction; /// -/// sql_function_v2! { +/// define_sql_function! { /// #[aggregate] /// fn range_max(x0: Float, x1: Float) -> Nullable; /// } @@ -1301,7 +1301,7 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// # .execute(connection) /// # .unwrap(); /// -/// range_max_internals::register_impl::, _, _>(connection)?; +/// range_max_utils::register_impl::, _, _>(connection)?; /// /// let result = student_avgs.select(range_max(s1_avg, s2_avg)) /// .get_result::>(connection)?; @@ -1315,11 +1315,11 @@ pub fn derive_valid_grouping(input: TokenStream) -> TokenStream { /// } /// ``` #[proc_macro] -pub fn sql_function_v2(input: TokenStream) -> TokenStream { +pub fn define_sql_function(input: TokenStream) -> TokenStream { sql_function::expand(parse_macro_input!(input), false).into() } -/// A legacy version of [`sql_function_v2!`]. +/// 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: @@ -1341,13 +1341,13 @@ pub fn sql_function_v2(input: TokenStream) -> TokenStream { /// ``` /// /// This turned out to be an issue for the support of the `auto_type` feature, which is why -/// [`sql_function_v2!`] was introduced (and why this is deprecated). +/// [`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 = "Use [`sql_function_v2`] instead"] +#[deprecated = "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), true).into() } @@ -1771,7 +1771,7 @@ pub fn derive_multiconnection(input: TokenStream) -> TokenStream { /// // If we didn't specify the type for this query fragment, the macro would infer it as /// // `user_has_post_with_id_greater_than`, which would be incorrect because there is /// // no generic parameter. -/// let filter: UserHasPostWithIdGreaterThan = +/// let filter: user_has_post_with_id_greater_than = /// user_has_post_with_id_greater_than(id_greater_than); /// // The macro inferring that it has to pass generic parameters is still the convention /// // because it's the most general case, as well as the common case within Diesel itself, @@ -1812,4 +1812,4 @@ pub fn auto_type( } const AUTO_TYPE_DEFAULT_METHOD_TYPE_CASE: dsl_auto_type::Case = dsl_auto_type::Case::UpperCamel; -const AUTO_TYPE_DEFAULT_FUNCTION_TYPE_CASE: dsl_auto_type::Case = dsl_auto_type::Case::UpperCamel; +const AUTO_TYPE_DEFAULT_FUNCTION_TYPE_CASE: dsl_auto_type::Case = dsl_auto_type::Case::DoNotChange; diff --git a/diesel_derives/src/sql_function.rs b/diesel_derives/src/sql_function.rs index ee93407ed855..d5a751935a95 100644 --- a/diesel_derives/src/sql_function.rs +++ b/diesel_derives/src/sql_function.rs @@ -398,7 +398,7 @@ pub(crate) fn expand(input: SqlFunctionDecl, legacy_helper_type_and_module: bool if legacy_helper_type_and_module { (None, quote! { #fn_name }, fn_name.clone()) } else { - let internals_module_name = Ident::new(&format!("{fn_name}_internals"), fn_name.span()); + let internals_module_name = Ident::new(&format!("{fn_name}_utils"), fn_name.span()); ( Some(quote! { #[allow(non_camel_case_types, non_snake_case)] diff --git a/diesel_derives/tests/auto_type.rs b/diesel_derives/tests/auto_type.rs index 6977d4e0a803..edaa2d3ab294 100644 --- a/diesel_derives/tests/auto_type.rs +++ b/diesel_derives/tests/auto_type.rs @@ -1,5 +1,6 @@ #![allow(dead_code)] // this is a compile pass test use diesel::dsl::*; +use diesel::helper_types::*; use diesel::prelude::*; table! { diff --git a/diesel_tests/tests/annotations.rs b/diesel_tests/tests/annotations.rs index a2d9f4a2ac93..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_v2!(fn nextval(a: Text) -> Integer); +define_sql_function!(fn nextval(a: Text) -> Integer); #[test] #[cfg(feature = "postgres")] diff --git a/diesel_tests/tests/expressions/mod.rs b/diesel_tests/tests/expressions/mod.rs index f8ccf167b7d0..893bfeb77162 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_v2!(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() { @@ -444,7 +444,7 @@ fn test_arrays_a() { #[cfg(feature = "postgres")] use diesel::sql_types::{Array, Int4}; #[cfg(feature = "postgres")] -sql_function_v2!(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 e42c07dc1a44..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_v2!(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 66a63b846753..91e939c165a5 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_v2!(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 673d48d8c3bb..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_v2!(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_v2!(fn setval(x: VarChar, y: BigInt)); -sql_function_v2!(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 76c22ce9b8ed..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_v2!(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/guide_drafts/migration_guide.md b/guide_drafts/migration_guide.md index b2db9c63a5c2..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_v2!` 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) @@ -189,8 +189,8 @@ impl FromSql for YourType { ## `no_arg_sql_function` The `no_arg_sql_function` was deprecated without direct replacement. However the -`sql_function_v2!` 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_v2!` will generate an ordinary function call without arguments. This requires changing any usage of the generated dsl. This change +`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_v2!{ ++ define_sql_function!{ + /// Represents the SQL NOW() function + fn now() -> sql_types::Timestamp; + } From dad155760a757cecf220eade8cf02bb325a8bc1e Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Fri, 8 Mar 2024 11:36:13 +0100 Subject: [PATCH 09/12] Add a change log entry for the deprecation --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15a0190fa376..d8ba5dfd53d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,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 From 3a8505b09f51e1341756bc711886281a674101e0 Mon Sep 17 00:00:00 2001 From: Thomas BESSOU Date: Fri, 8 Mar 2024 12:35:13 +0100 Subject: [PATCH 10/12] Fix return_type_path in legacy_helper_type_and_module mode --- diesel_derives/src/sql_function.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/diesel_derives/src/sql_function.rs b/diesel_derives/src/sql_function.rs index d5a751935a95..1f76d9d9adfd 100644 --- a/diesel_derives/src/sql_function.rs +++ b/diesel_derives/src/sql_function.rs @@ -396,7 +396,7 @@ pub(crate) fn expand(input: SqlFunctionDecl, legacy_helper_type_and_module: bool let (outside_of_module_helper_type, return_type_path, internals_module_name) = if legacy_helper_type_and_module { - (None, quote! { #fn_name }, fn_name.clone()) + (None, quote! { #fn_name::HelperType }, fn_name.clone()) } else { let internals_module_name = Ident::new(&format!("{fn_name}_utils"), fn_name.span()); ( From 8a22876307a9c25f064f17c09189f478ac26def9 Mon Sep 17 00:00:00 2001 From: Thomas BESSOU Date: Fri, 8 Mar 2024 12:35:54 +0100 Subject: [PATCH 11/12] Remap last few `sql_function!` calls to `define_sql_function!` in examples --- diesel/src/query_builder/ast_pass.rs | 2 +- examples/postgres/composite_types/README.md | 10 +++++----- .../composite_types/examples/composite2rust_colors.rs | 8 ++++---- .../examples/composite2rust_coordinates.rs | 8 ++++---- 4 files changed, 14 insertions(+), 14 deletions(-) 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/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; From 94d1a5ebfcccd325d615b9b6699c933fee914ce9 Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Fri, 8 Mar 2024 14:08:35 +0100 Subject: [PATCH 12/12] Address review comments --- diesel/src/lib.rs | 6 ++++-- diesel/src/query_dsl/limit_dsl.rs | 2 +- diesel/src/query_dsl/offset_dsl.rs | 2 +- diesel_derives/src/lib.rs | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/diesel/src/lib.rs b/diesel/src/lib.rs index 8d7d670cbc85..2a74471dd626 100644 --- a/diesel/src/lib.rs +++ b/diesel/src/lib.rs @@ -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 = diff --git a/diesel/src/query_dsl/limit_dsl.rs b/diesel/src/query_dsl/limit_dsl.rs index d6d617bc6a2e..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 b843b8b46484..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_derives/src/lib.rs b/diesel_derives/src/lib.rs index aa80ab08895f..df8f04d3bb17 100644 --- a/diesel_derives/src/lib.rs +++ b/diesel_derives/src/lib.rs @@ -1345,7 +1345,7 @@ pub fn define_sql_function(input: TokenStream) -> TokenStream { /// /// SQL functions declared with this version of the macro will not be usable with `#[auto_type]` /// or `Selectable` `select_expression` type inference. -#[deprecated = "Use [`define_sql_function`] instead"] +#[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 {