Skip to content

Rewrite LIKE with wildcards using CONCAT function. #2944

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

Closed
wants to merge 2 commits into from

Conversation

gregturn
Copy link
Contributor

@gregturn gregturn commented May 9, 2023

Since queries like select e from Employee e where e.name like %:name% as well as select * from Employee AS e where e.name like %:name% both result in the wildcards being pulled out and migrated to the bindings, I have tuned that action to instead replace them with a CONCAT function.

CONCAT appears to be supported on all major relational databases as well as on all JPA providers.

This means we can eliminate the race condition that arises when you use the same binding more than once, and only one of them has a wildcard.

And because this doesn't impact any public-facing APIs nor does it involve the query parser, I believe this PR is a candidate for backporting to 3.0.x as well as 2.7.x.

I took the liberty of introducing a warning in the log files that can alert users to this, tipping them off that it may be to their advantage to rewrite their custom query using the same pattern, in case this feature is no longer supported in the future. If you think this is unneeded, we can remove it. However, I think it's fair to nudge people to in fact rewrite their queries and make them more standard.

gregturn added a commit that referenced this pull request May 9, 2023
We support wrapping parameters (named or positional) with optional wildcards when doing LIKE patterns. This is out-of-band and requires moving the wildcards into the bindings. To stop doing this and causing race conditions, we can instead rewrite the queries using the CONCAT function. This function is standard across relational database (native queries) as well as JPA providers (Hibernate and EclipseLink).

Resolves #2939.
Related: #2760.
Original Pull Request: #2944.
@gregturn gregturn force-pushed the issue/gh-2939-take2 branch from 964b3f8 to 19832e0 Compare May 9, 2023 20:52
We support wrapping parameters (named or positional) with optional wildcards when doing LIKE patterns. This is out-of-band and requires moving the wildcards into the bindings. To stop doing this and causing race conditions, we can instead rewrite the queries using the CONCAT function. This function is standard across relational database (native queries) as well as JPA providers (Hibernate and EclipseLink).

Resolves #2939.
Related: #2760.
Original Pull Request: #2940.
Superceding Pull Request: #2944
Copy link
Contributor

@schauder schauder left a comment

Choose a reason for hiding this comment

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

My understanding of our style guide for commit messages is for the references to issues:

  • Don't end with a dot.
  • Don't include a colon.
  • refer to related issues with See

Other than these minor issues this seems fine to me.
Another long standing issue finally fixed. 💛


concatWrapper.append(")");

LOGGER.warn(
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm against logging this. It is a normal feature of SD JPA and we don't have a reason to believe it does not work.

If there are actually databases that don't support concat and need a workaround we can add a warning like this when we learn about them (and don't find a proper solution)

Copy link
Member

Choose a reason for hiding this comment

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

We should consider this a valid feature and do not log a warning. Our docs explicitly mention:

and u.lastname like %:lastname%")

@@ -102,6 +102,40 @@ void customQueryWithNullMatch() {
assertThat(Employees).extracting(EmployeeWithName::getName).isEmpty();
}

@Test
Copy link
Contributor

Choose a reason for hiding this comment

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

Tests should have a comment referencing the issue
// GH-2939 in this case.

@mp911de
Copy link
Member

mp911de commented May 10, 2023

style guide for commit messages is for the references to issues:

Guess everyone is doing it differently, though. Everything is fine as long as we start ticket references with #.

@gregturn
Copy link
Contributor Author

I guess that was a habit from Spring HATEOAS/Spring Data REST regarding formatting. I really like the resolves/closes tactics, because it closes the ticket when merged to main. But I can try to better follow this styling.

gregturn added a commit that referenced this pull request May 10, 2023
We support wrapping parameters (named or positional) with optional wildcards when doing LIKE patterns. This is out-of-band and requires moving the wildcards into the bindings. To stop doing this and causing race conditions, we can instead rewrite the queries using the CONCAT function. This function is standard across relational database (native queries) as well as JPA providers (Hibernate and EclipseLink).

See #2939
See #2760
Original Pull Request: #2940
Superceding Pull Request: #2944
@gregturn gregturn closed this May 10, 2023
@gregturn gregturn deleted the issue/gh-2939-take2 branch May 10, 2023 14:01
gregturn added a commit that referenced this pull request May 15, 2023
We support wrapping parameters (named or positional) with optional wildcards when doing LIKE patterns. This is out-of-band and requires moving the wildcards into the bindings. To stop doing this and causing race conditions, we can instead rewrite the queries using the CONCAT function. This function is standard across relational database (native queries) as well as JPA providers (Hibernate and EclipseLink).

See #2939
See #2760
Original Pull Request: #2940
Superceding Pull Request: #2944
gregturn added a commit that referenced this pull request May 15, 2023
We support wrapping parameters (named or positional) with optional wildcards when doing LIKE patterns. This is out-of-band and requires moving the wildcards into the bindings. To stop doing this and causing race conditions, we can instead rewrite the queries using the CONCAT function. This function is standard across relational database (native queries) as well as JPA providers (Hibernate and EclipseLink).

See #2939
See #2760
Original Pull Request: #2940
Superceding Pull Request: #2944
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants