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
1 parent 233f814 commit 15d9201
Show file tree
Hide file tree
Showing 39 changed files with 1,343 additions and 1,181 deletions.
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
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
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
Loading

0 comments on commit 15d9201

Please sign in to comment.