From de3a4c0af96e1a3dc23bd7aa8c7d8f5f4bcc03b8 Mon Sep 17 00:00:00 2001 From: Gavin King Date: Thu, 6 Jun 2024 14:19:37 +0200 Subject: [PATCH] HHH-17804 roll back change to semantics of 'null in ()' It turns out that SQL databases (IMO wrongly) treat the expression 'null in (select 1 where false)' as false instead of null. And as of JPA 3.2, we're free to interpret 'null in ()' consistently with that, which we should do. So my change made things worse rather than better. Signed-off-by: Gavin King --- .../persister/entity/AbstractEntityPersister.java | 2 +- .../main/java/org/hibernate/sql/InFragment.java | 15 +-------------- .../sql/ast/spi/AbstractSqlAstTranslator.java | 12 +----------- .../test/jpa/criteria/basic/PredicateTest.java | 7 ++++--- 4 files changed, 7 insertions(+), 29 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index f9c8406034..cac8d6a7b6 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -3206,7 +3206,7 @@ protected String getPrunedDiscriminatorPredicate( Map entityNameUses, MappingMetamodelImplementor mappingMetamodel, String alias) { - final InFragment frag = new InFragment( false ); + final InFragment frag = new InFragment(); if ( isDiscriminatorFormula() ) { frag.setFormula( alias, getDiscriminatorFormulaTemplate() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/InFragment.java b/hibernate-core/src/main/java/org/hibernate/sql/InFragment.java index 6516705164..b2f892ee43 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/InFragment.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/InFragment.java @@ -21,15 +21,10 @@ @Internal public class InFragment { - public InFragment(boolean columnCanBeNull) { - this.columnCanBeNull = columnCanBeNull; - } - public static final String NULL = "null"; public static final String NOT_NULL = "not null"; protected String columnName; - protected boolean columnCanBeNull; protected List values = new ArrayList<>(); /** @@ -71,15 +66,7 @@ public String toFragmentString() { switch ( values.size() ) { case 0: { - if ( columnCanBeNull ) { - return buf.append( "(1 = case when " ) - .append( columnName ) - .append(" is not null then 0 end)") - .toString(); - } - else { - return "0=1"; - } + return "0=1"; } case 1: { Object value = values.get( 0 ); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java index 46b310591e..8316409c50 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java @@ -7641,7 +7641,7 @@ public void visitGroupedPredicate(GroupedPredicate groupedPredicate) { public void visitInListPredicate(InListPredicate inListPredicate) { final List listExpressions = inListPredicate.getListExpressions(); if ( listExpressions.isEmpty() ) { - emptyInList( inListPredicate ); + appendSql( "1=" + ( inListPredicate.isNegated() ? "1" : "0" ) ); return; } Function itemAccessor = Function.identity(); @@ -7748,16 +7748,6 @@ else if ( !supportsRowValueConstructorSyntaxInInList() ) { } } - protected void emptyInList(InListPredicate inListPredicate) { - appendSql("("); - appendSql( inListPredicate.isNegated() ? "0" : "1" ); - appendSql(" = case when "); - inListPredicate.getTestExpression().accept( this ); - appendSql( " is not null then 0"); -// dialect.appendBooleanValueString( this, inListPredicate.isNegated() ); - appendSql(" end)"); - } - private void appendInClauseSeparator(InListPredicate inListPredicate) { appendSql( CLOSE_PARENTHESIS ); appendSql( inListPredicate.isNegated() ? " and " : " or " ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/criteria/basic/PredicateTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/criteria/basic/PredicateTest.java index 7b71e3bc2e..b40fe48021 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/criteria/basic/PredicateTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/criteria/basic/PredicateTest.java @@ -31,6 +31,7 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; /** @@ -334,7 +335,7 @@ public void testEmptyInPredicate2() { CriteriaQuery orderCriteria = builder.createQuery( Order.class ); Root orderRoot = orderCriteria.from( Order.class ); orderCriteria.select( orderRoot ); - orderCriteria.where( builder.in( orderRoot.get("creditCard") ) ); + orderCriteria.where( builder.in( orderRoot.get("id") ) ); List orders = em.createQuery( orderCriteria ).getResultList(); assertTrue( orders.isEmpty() ); @@ -350,10 +351,10 @@ public void testEmptyInPredicate3() { CriteriaQuery orderCriteria = builder.createQuery( Order.class ); Root orderRoot = orderCriteria.from( Order.class ); orderCriteria.select( orderRoot ); - orderCriteria.where( builder.in( orderRoot.get("creditCard") ).not() ); + orderCriteria.where( builder.in( orderRoot.get("id") ).not() ); List orders = em.createQuery( orderCriteria ).getResultList(); - assertTrue( orders.isEmpty() ); + assertFalse( orders.isEmpty() ); em.getTransaction().commit(); em.close(); }