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

Proposal: IN and NOT IN fragment builders for product types with arbitrary arities #2128

Merged
merged 5 commits into from
Nov 7, 2024

Conversation

satorg
Copy link
Contributor

@satorg satorg commented Nov 3, 2024

Current in, notIn, inOpt, etc fragment builders only allow 1 or 2 values per matching row.
The proposed builders take Read instead of Get and therefore allow products of any arity.
Moreover, the current 2-arity builders accept values packed as Tuple2 only. The proposed builders accept tuples as well as case classes, which can come in handy in some cases.

Why inValues and notInValues names?

In fact, neither the existing nor the proposed builders allow to build full-featured IN/NOT IN expression. Both allow just a subset of features – matching against a static set of values. Besides, we cannot have in function overloads for both kinds of builders. Therefore, if we want to keep the existing builders, we'll have to choose another names for the new ones.

Names inValues and notInValues look pretty reasonable, but I'm totally open to change them to something better.

@satorg
Copy link
Contributor Author

satorg commented Nov 3, 2024

Hmm.. CI has failed, but doesn't seem related to the PR to me 🤔

fs: F[A],
fallback: Fragment
)(implicit A: util.Write[A]): Fragment = {
if (A.length == 0) fallback
Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks this looks good! Small suggestion - I don't think we need/should handle 0-arity products.

Reason:

  • We no longer derive instances for case objects so it's really difficult to accidentally pass in a 0-arity product
  • Which means the only other possible case is if user is passing List[Unit], which never makes sense and it's better to generate a bad SQL that fails than silently fallback to TRUE/FALSE.

WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree, I don't like it either. I'll update the PR, thx!

* @return
* the `IN` subquery expression or `FALSE` if `fs` is a 0-arity product.
*/
def inValues[F[_]: Reducible: Functor, A: util.Write](f: Fragment, fs: F[A]): Fragment =
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm also wondering whether we can replace in with this. It should be source compatible

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you mean, remove the existing in/notIn whatsoever and rename the proposed inValues/notInValues to in/notIn, correct?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes that's right

@satorg
Copy link
Contributor Author

satorg commented Nov 7, 2024

Hi @jatcwang ,
I've updated the PR:

  1. removed checks for 0 arity;
  2. removed all previous versions of in/inOut/notIn/notInOpt and replaced them with corresponding methods that take Write instead of Put (all of them);
  3. fixed/updated/enhanced corresponding tests.

@jatcwang
Copy link
Collaborator

jatcwang commented Nov 7, 2024

Looks great tyvm!

@jatcwang jatcwang merged commit cc635ff into typelevel:main Nov 7, 2024
5 checks passed
@satorg satorg deleted the in-not-in-fragments branch November 7, 2024 17:07
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.

2 participants