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

DATAJDBC-1953 Introduced DialectCriteriaCondition interface #1981

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

mipo256
Copy link
Contributor

@mipo256 mipo256 commented Jan 16, 2025

This PR addresses the following issue #1953.

The core of the problem, I think, is that we had the Comparator as a Java enum, which is not extendable. I thought that, from the future perspective, as @schauder pointed out, we cannot really foresee all the possible conditions that can be used. Arrays in PostgreSQL is just a very concrete case.

So, the issue that is pointed out by the author, I think, should be solved in the following way, from the API's perspective:

Criteria.where("tags").custom(() -> "@> ARRAY['electronics']::text[]");

and that would render to the SQL that we expect:

SELECT * FROM products WHERE tags @> ARRAY['electronics']::text[]

This approach allows users to customize the condition in any possible way for any given column. This is achieved by introducing the Comparator interface, rather than the Comparator enum.

P.S: I've tried to minimize the backwards incompatibility as much as possible, but still, some migration would be needed here. Therefore, I guess, we need to assign a breaking-change tag

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jan 16, 2025
@schauder
Copy link
Contributor

Thanks for the contribution. We need a Developer Certificate of Origin (DCO) for new PRs.

For details about how and why see https://spring.io/blog/2025/01/06/hello-dco-goodbye-cla-simplifying-contributions-to-spring

@schauder schauder added status: waiting-for-feedback We need additional information before we can continue type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged labels Jan 16, 2025
@schauder schauder self-assigned this Jan 16, 2025
@schauder schauder linked an issue Jan 16, 2025 that may be closed by this pull request
@mipo256 mipo256 force-pushed the DATAJDBC-1953 branch 2 times, most recently from 74172af to 6692442 Compare January 16, 2025 18:52
@mipo256
Copy link
Contributor Author

mipo256 commented Jan 16, 2025

Hey @schauder, yeah, I am aware of this, I've added the sign off.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Jan 16, 2025
@mp911de
Copy link
Member

mp911de commented Jan 17, 2025

I don't think this is a good design direction. We should have rather some way to express predicates in a way that allows to determine bindings, mapping of values and to generate SQL text. I'll leave some thoughts in the original ticket #1953

@mipo256 mipo256 force-pushed the DATAJDBC-1953 branch 3 times, most recently from 1f54016 to 295c9f5 Compare February 7, 2025 11:36
@mipo256
Copy link
Contributor Author

mipo256 commented Feb 7, 2025

Hey @mp911de, @schauder!

I've revisited the solution according to the comment left in here: #1953 (comment)

The usage sample for the issue looks like this:

where("foo").is("bar").and("baz").satisfies(Postgres.arrayContains("first", "second"))

This would render into the following:

foo = 'bar' AND baz @> ARRAY['first','second']::text[]

I've introduced a new interface - DialectCriteriaCondition, that represents a condition that would eventually render into the part of the SQL condition that is vendor specific.

Also, the API, as it is now created, allows users to define their own DialectCriteriaCondition, in case we do not have them yet, like this:

Criteria criteria = where("foo").satisfies(() -> "~* '*.example.*'"); // renders into foo ~* '*.example.*'

@mipo256 mipo256 changed the title DATAJDBC-1953 Introduced Comparator interface DATAJDBC-1953 Introduced DialectCriteriaCondition interface Feb 7, 2025
*
* @author Mikhail Polivakha
*/
public interface DialectCriteriaCondition {
Copy link
Member

Choose a reason for hiding this comment

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

This is a bit too little, especially given the later variant of concatenating values into SQL as it opens loopholes for SQL injection.

An operator should have a method accepting a MappingContext and likely a PersistentProperty that applies to it and an abstraction like R2DBC's BindMarkers. In return, we need a tuple of bind markers associated with their value and the SQL fragment. Maybe even a slimmer variant of BindTarget (without the binding identifier) would suit fit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: feedback-provided Feedback has been provided type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Introduce abstractions to define custom criteria predicates
4 participants