Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix most type-defs for #[auto_type] by cleaning up all the type defs #3783

Merged
merged 15 commits into from
Mar 8, 2024

Conversation

weiznich
Copy link
Member

@weiznich weiznich commented Sep 8, 2023

Fixes #3745

This fixes most of the broken cases for #[auto_type] by:

  • Changing all the free standing function types to use PascalCase instead of lower case names (There are only 10 functions affected by that)
  • Introducing hidden typedefs for cases where the existing type def name did not match the expected one
  • Unify the code to use the same operator implementation for different types where necessary (for example Like is now also used for Blob or there is a single Concat operator instead of having 3 separate ones.)
  • Add some new helper types/traits for Insert statements to allow them working with #[auto_type] as well.
  • Hacking around some limitation in terms of type parameter inference for limit/offset by just adding a dummy type parameter there.

This is explicitly a WIP PR as it contains quite a few undocumented items that either need documentation or need to be moved into private modules. Everything included in this PR shouldn't be a breaking change.

This PR does not address the following issues with #[auto_type]:

  • QueryDsl::into_boxed() -> This requires a lifetime and a backend type. Likely hard to ever support?
  • QueryDsl::count() -> Name collision with the count() function type
  • diesel::update() -> There is an existing incompatible Update type in diesel::dsl. I do not see an easy way to change that type into something that would work with #[auto_type]
  • diesel::select() -> There is an existing Select type in diesel::dsl that is used by QueryDsl::select()
  • diesel::sql_query() -> does not have any (non-default) type parameter, but #[auto_type] requires one
  • diesel::dsl::sql() -> requires the sql type to come from somewhere -> maybe #[auto_type] can be updated to pass a explicit specified generic type forward as well (so dsl::sql::<Integer>("") turns into dsl::Sql<Integer>?)
  • Some *ExpressionMethod trait methods for postgres, as I've run out of time before tackling them

that should be almost always backwards compatible because the module
was only pub(crate) anyway.
It is not strictly backwards compatible because diesel-rs#3745 (comment)
@@ -332,6 +332,7 @@ pub trait QueryDsl: Sized {
where
Self: methods::SelectDsl<CountStar>,
{
#[allow(deprecated)]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we choose that solution we need to think about if we really want to put a #[deprecated] onto the old type aliases as this results in warnings as soon as you have an import like that, even if that import could refer to the function as well.

@weiznich weiznich marked this pull request as ready for review September 14, 2023 06:08
@weiznich
Copy link
Member Author

@Ten0 I think this is now mostly ready for review. It solves most of the issues, what's left could probably be documented as exception?

@Ten0
Copy link
Member

Ten0 commented Sep 14, 2023

I think this is now mostly ready for review

This is on my to-do list, I need to find the time to have a look at it - not sure when, sorry.

@weiznich
Copy link
Member Author

👍 Thanks for letting me know. Take your time, its not necessary to rush anything here as that feature is not released yet.

@weiznich
Copy link
Member Author

weiznich commented Nov 7, 2023

@Ten0 I've updated this PR to include tests for the case_when functions as well. I also added the currently not supported statements to the documentation. Otherwise this should be ready to merge from my side.

@Ten0
Copy link
Member

Ten0 commented Jan 12, 2024

Sorry for the huge delay 😔

So this approach of updating the type aliases names to their PascalCase names has the downsides that:

  • As you pointed out, there are more conflicts (e.g. count vs Count).

  • While it doesn't require sql_function_v2 (which by the way is only necessary if you're using the generated function within a dsl::auto_type query fragment) it requires maintaining duplicate type aliases for backwards-compatibility.

  • When importing a function directly via a use statement, the user must provide both the function and the type alias, because those are named differently, whereas if they are named exactly the same, use will actually allow resolving both.

    A such scenario we commonly encounter is:

     mod a {
         #[dsl::auto_type]
         fn b() -> _ { /*...*/ }
     }
     
     mod c {
         use crate::a::b;
     
         #[dsl::auto_type]
         fn d() -> _ {
             b().and(/* ... */)
         }
     }

For these reasons, I think I like more the idea of not changing our (weird) current convention with regards to naming type aliases for dsl::xxx functions vs methods, and instead do the approach described at #3773 (I think the breaking change described there is unlikely enough to affect each project that it's acceptable).

(If however we do decide to apply the approach drafted at #3773 we should still apply the other fixes that are in this PR, as explained in the PR description)

@weiznich
Copy link
Member Author

There is also #3898 (and rust-lang/rust#114682) which might be relevant here, as the rustc devs might want to disallow some of that overlapping type import thing.

That written: I think my main problem with the sql_function_v2! approach is that it introduces another macro and therefore makes the public API much larger. Maybe it's an option to just add a #[auto_type_compatible] annotation to the existing macro and emit a deprecated warning for all calls that do not have that attribute?

That written: Even if we go with that other approach we need to carefully inspect this PR for the other fixes that are included here. That includes for example using .limit or many of the other QueryDsl and ExpressionMethods methods with #[auto_type]. Also we might likely want to copy over the tests.

@Ten0
Copy link
Member

Ten0 commented Jan 12, 2024

Maybe it's an option to just add a #[auto_type_compatible] annotation to the existing macro and emit a deprecated warning for all calls that do not have that attribute?

I recall having considered that but ended up proposing an implementation with _v2 instead because:

  • I was not aware of a method to emit a warning from within a macro (but this seems to have been implemented at least in proc-macro-warning)
  • It felt like a much more verbose change in such cases:
    image
  • For people who know, having both functions suggested by autocomplete seems better than having to type the attribute
  • For people who don't know, having both functions suggested by doc/autocomplete has the naming pretty clear on which one they should prefer using, which should gain the deprecation naming round trip.

makes the public API much larger

We could also decide to make the deprecated sql_function! #[doc(hidden)]?

Even if we go with that other approach we need to carefully inspect this PR for the other fixes that are included here

Definitely yes :)

…ype_max

Conflicts:
	diesel_compile_tests/tests/fail/right_side_of_left_join_requires_nullable.stderr
@weiznich
Copy link
Member Author

weiznich commented Mar 8, 2024

@Ten0 I've merged #3773 into this PR and adjusted the names as discussed on the other PR. It would be great if you could have a final look at the changes.

Copy link
Member

@Ten0 Ten0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM apart from this minor naming thing ! 🎉
(Also I'm not sure the PR description is completely accurate anymore at this point)

///
/// 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"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we may want to add a since note here - not sure when we want to release exactly

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've set it to 2.2.0. I think we will release that version in a timely manner after I finished #3951 copy support)

diesel/src/query_dsl/limit_dsl.rs Outdated Show resolved Hide resolved
diesel/src/query_dsl/offset_dsl.rs Outdated Show resolved Hide resolved
diesel/src/lib.rs Outdated Show resolved Hide resolved
@weiznich weiznich added this pull request to the merge queue Mar 8, 2024
Merged via the queue into diesel-rs:master with commit 6ef23bd Mar 8, 2024
48 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

dsl::max doesn't work with dsl::auto_type
2 participants