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 27b9f5fa2f..6f5c38d615 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 @@ -3255,7 +3255,7 @@ public abstract class AbstractEntityPersister Map entityNameUses, MappingMetamodelImplementor mappingMetamodel, String alias) { - final InFragment frag = new InFragment(); + final InFragment frag = new InFragment( false ); 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 d41a3cfd7d..6516705164 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/InFragment.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/InFragment.java @@ -21,10 +21,15 @@ import org.hibernate.internal.util.StringHelper; @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<>(); /** @@ -62,67 +67,80 @@ public class InFragment { } public String toFragmentString() { - if ( values.size() == 0 ) { - return "1=2"; - } + final StringBuilder buf = new StringBuilder( values.size() * 5 ); - StringBuilder buf = new StringBuilder( values.size() * 5 ); - - if ( values.size() == 1 ) { - Object value = values.get( 0 ); - buf.append( columnName ); - - if ( NULL.equals( value ) ) { - buf.append( " is null" ); - } - else { - if ( NOT_NULL.equals( value ) ) { - buf.append( " is not null" ); + switch ( values.size() ) { + case 0: { + if ( columnCanBeNull ) { + return buf.append( "(1 = case when " ) + .append( columnName ) + .append(" is not null then 0 end)") + .toString(); } else { - buf.append( '=' ).append( value ); + return "0=1"; } } - return buf.toString(); - } + case 1: { + Object value = values.get( 0 ); + buf.append( columnName ); - boolean allowNull = false; - - for ( Object value : values ) { - if ( NULL.equals( value ) ) { - allowNull = true; - } - else { - if ( NOT_NULL.equals( value ) ) { - throw new IllegalArgumentException( "not null makes no sense for in expression" ); + if ( NULL.equals( value ) ) { + buf.append( " is null" ); } + else { + if ( NOT_NULL.equals( value ) ) { + buf.append( " is not null" ); + } + else { + buf.append( '=' ).append( value ); + } + } + return buf.toString(); + } + default: { + boolean allowNull = false; + + for ( Object value : values ) { + if ( NULL.equals( value ) ) { + allowNull = true; + } + else { + if ( NOT_NULL.equals( value ) ) { + throw new IllegalArgumentException( "not null makes no sense for in expression" ); + } + } + } + + if ( allowNull ) { + buf.append( '(' ) + .append( columnName ) + .append( " is null or " ) + .append( columnName ) + .append( " in (" ); + } + else { + buf.append( columnName ).append( " in (" ); + } + + for ( Object value : values ) { + if ( !NULL.equals( value ) ) { + buf.append( value ); + buf.append( ", " ); + } + } + + buf.setLength( buf.length() - 2 ); + + if ( allowNull ) { + buf.append( "))" ); + } + else { + buf.append( ')' ); + } + + return buf.toString(); } } - - if ( allowNull ) { - buf.append( '(' ).append( columnName ).append( " is null or " ).append( columnName ).append( " in (" ); - } - else { - buf.append( columnName ).append( " in (" ); - } - - for ( Object value : values ) { - if ( !NULL.equals( value ) ) { - buf.append( value ); - buf.append( ", " ); - } - } - - buf.setLength( buf.length() - 2 ); - - if ( allowNull ) { - buf.append( "))" ); - } - else { - buf.append( ')' ); - } - - return buf.toString(); - } } 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 f881b27873..b870e64313 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 @@ -7603,7 +7603,7 @@ public abstract class AbstractSqlAstTranslator implemen public void visitInListPredicate(InListPredicate inListPredicate) { final List listExpressions = inListPredicate.getListExpressions(); if ( listExpressions.isEmpty() ) { - appendSql( "1=" + ( inListPredicate.isNegated() ? "1" : "0" ) ); + emptyInList( inListPredicate ); return; } Function itemAccessor = Function.identity(); @@ -7710,6 +7710,16 @@ public abstract class AbstractSqlAstTranslator implemen } } + 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 " );