Skip to content

HHH-19497 Test for composition of 'not' 'in' restrictions #10412

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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

michaelfranz
Copy link

@michaelfranz michaelfranz commented Jun 25, 2025

not in is not handled correctly for multi-column joins. This pull request fixes the problem.

Compositions of not with in on lists fail for dialects not supporting record-level construction, such as DB2Dialect.
Using not with in with such dialects can lead to dangerous outcomes, such as all records being returned from a query. This is because the query condition always evaluates to either true or false (depending on the details of the query) because multi-column joins are not handled correctly.


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license
and can be relicensed under the terms of the LGPL v2.1 license in the future at the maintainers' discretion.
For more information on licensing, please check here.


https://hibernate.atlassian.net/browse/HHH-19497

Mike Mannion added 2 commits June 25, 2025 17:57
…me, this test fails for dialects that do not support record-level construction, such as DB2Dialect.
@gavinking
Copy link
Member

@beikov would you take a look at this one please?

@gavinking gavinking requested a review from beikov June 25, 2025 16:23
getSqlTuple( expression ).getExpressions(),
comparisonOperator,
SqlTupleContainer.getSqlTuple(expression).getExpressions(),
ComparisonOperator.EQUAL,
true
);
separator = " or ";
Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the fix and test. I'm just curious why you didn't change the junction type here instead. Am I missing some subtle case where using not ( (x=x1 and y=y1) or (x=x2 and y=y2) ) is "more" correct over ( (x<>x1 or y<>y1) and (x<>x2 or y<>y2) )?

Suggested change
separator = " or ";
separator = inListPredicate.isNegated() ? " and " : " or ";

I also did some testing with null values on PostgreSQL and to me it seems that both kinds of expressions are semantically equivalent. With an increasing amount of in-list items (3+), the not approach is more compact, which is why I would even prefer that. Since you seem to be on DB2, could you please let me know if there is a performance difference between the two predicate styles i.e. are the query execution plans the same?

Copy link
Member

Choose a reason for hiding this comment

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

To be clear, I don't have a strong preference for one solution or the other. Your previous solution seemed nicer to me, because with a growing number of in-list items, the resulting SQL is simply shorter, but ultimately, I would prefer we go with the solution that is "fastest".

Now, let me ask you again. Since you seem to be on DB2, could you please let me know if there is a performance difference between the two predicate styles i.e. are the query execution plans the same?

Copy link
Author

Choose a reason for hiding this comment

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

I will happily provide some findings on execution plans in the coming days, project priorities permitting. In the meantime, I again stress that the problem is not db2-specific. It impacts any database (driver) that does not support record-level or tuple construction. Knowing db2's plan is interesting, perhaps, but it's just one case.
Ideally one would survey the most popular databases to see their execution plans and relative performance for this case; and make a decision based on what works best for most.

@michaelfranz michaelfranz force-pushed the HHH-19497-negated-in-list branch from 3c5e512 to da84610 Compare July 5, 2025 10:36
Mike Mannion added 3 commits July 5, 2025 12:47
…HHH-19497-negated-in-list

# Conflicts:
#	hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java
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.

3 participants