Skip to content

Commit

Permalink
Introduce a #[declare_sql_function] attribute macro
Browse files Browse the repository at this point in the history
This commit introduces a new `#[declare_sql_function]` attribute macro
that can be applied to `extern "SQL"` blocks. This is essentially the
same as the existing `define_sql_function!` function like macro in terms
of functionality.

I see the following advantages of using an attribute macro + an `extern
"SQL"` block instead:

* This is closer to rust syntax, so rustfmt will understand that and
work correctly inside these blocks
* This allows to put several functions into the same block
* Maybe in the future this also allows to apply attributes to the whole
block instead of to each item

The downside of this change is that we then have three variants to
declare sql functions:

* `sql_function!()` (deprectated)
* `define_sql_function!()` (introduced in 2.2, we might want to
deprecate that as well?)
* The new attribute macro
  • Loading branch information
weiznich committed Dec 5, 2024
2 parents 8939fce + 8f21a45 commit 7d8df86
Show file tree
Hide file tree
Showing 107 changed files with 1,604 additions and 1,389 deletions.
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: "cargo"
directory: "/"
allow:
dependency-type: "direct"
schedule:
interval: "weekly"
reviewers:
- "diesel/reviewer"
versioning-strategy: "widen"
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,24 @@ Increasing the minimal supported Rust version will always be coupled at least wi
* Fixed `#[derive(Identifiable)]` ignoring attribute `#[diesel(serialize_as)]` on primary keys
* Added embedded struct support for `AsChangeset` via `#[diesel(embed)]`
* Support for libsqlite3-sys 0.30.0
* Add support for built-in PostgreSQL range operators and functions
* Added support for built-in PostgreSQL range operators and functions
* Added support for various built-in PostgreSQL array functions
* Support for postgres multirange type
* Added `diesel::r2d2::TestCustomizer`, which allows users to customize their `diesel::r2d2::Pool`s
in a way that makes the pools suitable for use in parallel tests.
* Added `Json` and `Jsonb` support for the SQLite backend.
* Added a `#[diesel::declare_sql_function]` attribute macro to easily define support for
multiple sql functions at once via an `extern "SQL"` block

### Fixed

* Fixed diesel thinking `a.eq_any(b)` was non-nullable even if `a` and `b` were nullable.

### Deprecated

* The `diesel::define_sql_function!` is now deprecated in favour of the `#[diesel::declare_sql_function]`
attribute macro.

## [2.2.2] 2024-07-19

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion diesel/src/associations/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ pub trait HasTable {
fn table() -> Self::Table;
}

impl<'a, T: HasTable> HasTable for &'a T {
impl<T: HasTable> HasTable for &T {
type Table = T::Table;

fn table() -> Self::Table {
Expand Down
4 changes: 4 additions & 0 deletions diesel/src/connection/instrumentation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ pub enum InstrumentationEvent<'a> {
// these constructors exist to
// keep `#[non_exhaustive]` on all the variants
// and to gate the constructors on the unstable feature
#[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
impl<'a> InstrumentationEvent<'a> {
/// Create a new `InstrumentationEvent::StartEstablishConnection` event
#[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
Expand Down Expand Up @@ -351,6 +352,7 @@ impl DerefMut for DynInstrumentation {
}

impl DynInstrumentation {
/// Create a instance of the default instrumentation provider
#[diesel_derives::__diesel_public_if(
feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
)]
Expand All @@ -361,6 +363,7 @@ impl DynInstrumentation {
}
}

/// Create a noop instrumentation provider instance
#[diesel_derives::__diesel_public_if(
feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
)]
Expand All @@ -371,6 +374,7 @@ impl DynInstrumentation {
}
}

/// register an event with the given instrumentation implementation
#[diesel_derives::__diesel_public_if(
feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
)]
Expand Down
5 changes: 4 additions & 1 deletion diesel/src/connection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,9 @@ pub(crate) mod private {
where
T: super::LoadConnection<B>,
{
type Cursor<'conn, 'query> = <T as super::LoadConnection<B>>::Cursor<'conn, 'query> where T: 'conn;
type Cursor<'conn, 'query>
= <T as super::LoadConnection<B>>::Cursor<'conn, 'query>
where
T: 'conn;
}
}
4 changes: 2 additions & 2 deletions diesel/src/connection/statement_cache/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ pub enum MaybeCached<'a, T: 'a> {
Cached(&'a mut T),
}

impl<'a, T> Deref for MaybeCached<'a, T> {
impl<T> Deref for MaybeCached<'_, T> {
type Target = T;

fn deref(&self) -> &Self::Target {
Expand All @@ -314,7 +314,7 @@ impl<'a, T> Deref for MaybeCached<'a, T> {
}
}

impl<'a, T> DerefMut for MaybeCached<'a, T> {
impl<T> DerefMut for MaybeCached<'_, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
match *self {
MaybeCached::CannotCache(ref mut x) => x,
Expand Down
8 changes: 5 additions & 3 deletions diesel/src/connection/statement_cache/strategy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ mod testing_utils {
mod tests_pg {
use crate::connection::CacheSize;
use crate::dsl::sql;
use crate::expression::functions::define_sql_function;
use crate::insertable::Insertable;
use crate::pg::Pg;
use crate::sql_types::{Integer, VarChar};
Expand All @@ -158,6 +157,11 @@ mod tests_pg {

use super::testing_utils::{count_cache_calls, RecordCacheEvents};

#[crate::declare_sql_function]
extern "SQL" {
fn lower(x: VarChar) -> VarChar;
}

table! {
users {
id -> Integer,
Expand Down Expand Up @@ -209,8 +213,6 @@ mod tests_pg {
assert_eq!(2, count_cache_calls(connection));
}

define_sql_function!(fn lower(x: VarChar) -> VarChar);

#[test]
fn queries_with_identical_types_and_binds_but_different_sql_are_cached_separately() {
let connection = &mut connection();
Expand Down
5 changes: 3 additions & 2 deletions diesel/src/expression/count.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::marker::PhantomData;

use super::functions::define_sql_function;
use super::functions::declare_sql_function;
use super::{is_aggregate, AsExpression};
use super::{Expression, ValidGrouping};
use crate::backend::Backend;
Expand All @@ -9,7 +9,8 @@ use crate::result::QueryResult;
use crate::sql_types::{BigInt, DieselNumericOps, SingleValue, SqlType};
use crate::{AppearsOnTable, SelectableExpression};

define_sql_function! {
#[declare_sql_function]
extern "SQL" {
/// Creates a SQL `COUNT` expression
///
/// As with most bare functions, this is not exported by default. You can import
Expand Down
7 changes: 3 additions & 4 deletions diesel/src/expression/functions/aggregate_folding.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::expression::functions::define_sql_function;
use crate::expression::functions::declare_sql_function;
use crate::sql_types::Foldable;

define_sql_function! {
#[declare_sql_function]
extern "SQL" {
/// Represents a SQL `SUM` function. This function can only take types which are
/// Foldable.
///
Expand All @@ -19,9 +20,7 @@ define_sql_function! {
/// ```
#[aggregate]
fn sum<ST: Foldable>(expr: ST) -> ST::Sum;
}

define_sql_function! {
/// Represents a SQL `AVG` function. This function can only take types which are
/// Foldable.
///
Expand Down
7 changes: 3 additions & 4 deletions diesel/src/expression/functions/aggregate_ordering.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use self::private::SqlOrdAggregate;
use crate::expression::functions::define_sql_function;
use crate::expression::functions::declare_sql_function;

define_sql_function! {
#[declare_sql_function]
extern "SQL" {
/// Represents a SQL `MAX` function. This function can only take types which are
/// ordered.
///
Expand All @@ -18,9 +19,7 @@ define_sql_function! {
/// # }
#[aggregate]
fn max<ST: SqlOrdAggregate>(expr: ST) -> ST::Ret;
}

define_sql_function! {
/// Represents a SQL `MIN` function. This function can only take types which are
/// ordered.
///
Expand Down
6 changes: 4 additions & 2 deletions diesel/src/expression/functions/date_and_time.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::backend::Backend;
use crate::expression::coerce::Coerce;
use crate::expression::functions::define_sql_function;
use crate::expression::functions::declare_sql_function;
use crate::expression::{AsExpression, Expression, ValidGrouping};
use crate::query_builder::*;
use crate::result::QueryResult;
Expand All @@ -27,7 +27,9 @@ impl_selectable_expression!(now);

operator_allowed!(now, Add, add);
operator_allowed!(now, Sub, sub);
define_sql_function! {

#[declare_sql_function]
extern "SQL" {
/// Represents the SQL `DATE` function. The argument should be a Timestamp
/// expression, and the return value will be an expression of type Date.
///
Expand Down
4 changes: 4 additions & 0 deletions diesel/src/expression/functions/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
//! Helper macros to define custom sql functions
#[doc(inline)]
pub use diesel_derives::declare_sql_function;

#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
#[doc(inline)]
pub use diesel_derives::define_sql_function;

Expand Down
12 changes: 6 additions & 6 deletions diesel/src/expression/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ impl<T: Expression + ?Sized> Expression for Box<T> {
type SqlType = T::SqlType;
}

impl<'a, T: Expression + ?Sized> Expression for &'a T {
impl<T: Expression + ?Sized> Expression for &T {
type SqlType = T::SqlType;
}

Expand Down Expand Up @@ -701,7 +701,7 @@ impl<T: ValidGrouping<GB> + ?Sized, GB> ValidGrouping<GB> for Box<T> {
type IsAggregate = T::IsAggregate;
}

impl<'a, T: ValidGrouping<GB> + ?Sized, GB> ValidGrouping<GB> for &'a T {
impl<T: ValidGrouping<GB> + ?Sized, GB> ValidGrouping<GB> for &T {
type IsAggregate = T::IsAggregate;
}

Expand Down Expand Up @@ -1030,16 +1030,16 @@ where
{
}

impl<'a, QS, ST, DB, GB, IsAggregate> QueryId
for dyn BoxableExpression<QS, DB, GB, IsAggregate, SqlType = ST> + 'a
impl<QS, ST, DB, GB, IsAggregate> QueryId
for dyn BoxableExpression<QS, DB, GB, IsAggregate, SqlType = ST> + '_
{
type QueryId = ();

const HAS_STATIC_QUERY_ID: bool = false;
}

impl<'a, QS, ST, DB, GB, IsAggregate> ValidGrouping<GB>
for dyn BoxableExpression<QS, DB, GB, IsAggregate, SqlType = ST> + 'a
impl<QS, ST, DB, GB, IsAggregate> ValidGrouping<GB>
for dyn BoxableExpression<QS, DB, GB, IsAggregate, SqlType = ST> + '_
{
type IsAggregate = IsAggregate;
}
Expand Down
2 changes: 1 addition & 1 deletion diesel/src/insertable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ pub trait CanInsertInSingleQuery<DB: Backend> {
fn rows_to_insert(&self) -> Option<usize>;
}

impl<'a, T, DB> CanInsertInSingleQuery<DB> for &'a T
impl<T, DB> CanInsertInSingleQuery<DB> for &T
where
T: ?Sized + CanInsertInSingleQuery<DB>,
DB: Backend,
Expand Down
2 changes: 2 additions & 0 deletions diesel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,8 @@ pub mod prelude {
pub use crate::expression::IntoSql as _;

#[doc(inline)]
pub use crate::expression::functions::declare_sql_function;
#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
pub use crate::expression::functions::define_sql_function;
#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
pub use crate::expression::functions::sql_function;
Expand Down
12 changes: 6 additions & 6 deletions diesel/src/migration/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ pub type Result<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>;
#[diesel(sql_type = Text)]
pub struct MigrationVersion<'a>(Cow<'a, str>);

impl<'a> MigrationVersion<'a> {
impl MigrationVersion<'_> {
/// Convert the current migration version into
/// an owned variant with static life time
pub fn as_owned(&self) -> MigrationVersion<'static> {
MigrationVersion(Cow::Owned(self.0.as_ref().to_owned()))
}
}

impl<'a, DB> FromSql<Text, DB> for MigrationVersion<'a>
impl<DB> FromSql<Text, DB> for MigrationVersion<'_>
where
String: FromSql<Text, DB>,
DB: Backend,
Expand All @@ -56,7 +56,7 @@ where
}
}

impl<'a> From<String> for MigrationVersion<'a> {
impl From<String> for MigrationVersion<'_> {
fn from(s: String) -> Self {
MigrationVersion(Cow::Owned(s))
}
Expand All @@ -74,7 +74,7 @@ impl<'a> From<&'a String> for MigrationVersion<'a> {
}
}

impl<'a> Display for MigrationVersion<'a> {
impl Display for MigrationVersion<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.0.as_ref())
}
Expand Down Expand Up @@ -140,7 +140,7 @@ pub trait MigrationSource<DB: Backend> {
fn migrations(&self) -> Result<Vec<Box<dyn Migration<DB>>>>;
}

impl<'a, DB: Backend> Migration<DB> for Box<dyn Migration<DB> + 'a> {
impl<DB: Backend> Migration<DB> for Box<dyn Migration<DB> + '_> {
fn run(&self, conn: &mut dyn BoxableConnection<DB>) -> Result<()> {
(**self).run(conn)
}
Expand All @@ -158,7 +158,7 @@ impl<'a, DB: Backend> Migration<DB> for Box<dyn Migration<DB> + 'a> {
}
}

impl<'a, DB: Backend> Migration<DB> for &'a dyn Migration<DB> {
impl<DB: Backend> Migration<DB> for &dyn Migration<DB> {
fn run(&self, conn: &mut dyn BoxableConnection<DB>) -> Result<()> {
(**self).run(conn)
}
Expand Down
2 changes: 1 addition & 1 deletion diesel/src/mysql/connection/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl RawConnection {
ffi::mysql_options(
result.0.as_ptr(),
ffi::mysql_option::MYSQL_SET_CHARSET_NAME,
b"utf8mb4\0".as_ptr() as *const libc::c_void,
c"utf8mb4".as_ptr() as *const libc::c_void,
)
};
assert_eq!(
Expand Down
10 changes: 7 additions & 3 deletions diesel/src/mysql/connection/stmt/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl<'a> StatementIterator<'a> {
}
}

impl<'a> Iterator for StatementIterator<'a> {
impl Iterator for StatementIterator<'_> {
type Item = QueryResult<MysqlRow>;

fn next(&mut self) -> Option<Self::Item> {
Expand Down Expand Up @@ -125,7 +125,7 @@ impl<'a> Iterator for StatementIterator<'a> {
}
}

impl<'a> ExactSizeIterator for StatementIterator<'a> {
impl ExactSizeIterator for StatementIterator<'_> {
fn len(&self) -> usize {
self.len
}
Expand Down Expand Up @@ -154,7 +154,11 @@ impl PrivateMysqlRow {
impl RowSealed for MysqlRow {}

impl<'a> Row<'a, Mysql> for MysqlRow {
type Field<'f> = MysqlField<'f> where 'a: 'f, Self: 'f;
type Field<'f>
= MysqlField<'f>
where
'a: 'f,
Self: 'f;
type InnerPartialRow = Self;

fn field_count(&self) -> usize {
Expand Down
2 changes: 1 addition & 1 deletion diesel/src/mysql/connection/stmt/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub(in crate::mysql::connection) struct MysqlFieldMetadata<'a>(
std::marker::PhantomData<&'a ()>,
);

impl<'a> MysqlFieldMetadata<'a> {
impl MysqlFieldMetadata<'_> {
pub(in crate::mysql::connection) fn field_name(&self) -> Option<&str> {
if self.0.name.is_null() {
None
Expand Down
Loading

0 comments on commit 7d8df86

Please sign in to comment.