Skip to content

Commit

Permalink
HHH-17804 treat 'null in ()' correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
gavinking committed Mar 5, 2024
1 parent 492e947 commit e7dea58
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3255,7 +3255,7 @@ protected String getPrunedDiscriminatorPredicate(
Map<String, EntityNameUse> entityNameUses,
MappingMetamodelImplementor mappingMetamodel,
String alias) {
final InFragment frag = new InFragment();
final InFragment frag = new InFragment( false );
if ( isDiscriminatorFormula() ) {
frag.setFormula( alias, getDiscriminatorFormulaTemplate() );
}
Expand Down
118 changes: 68 additions & 50 deletions hibernate-core/src/main/java/org/hibernate/sql/InFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,15 @@
@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<Object> values = new ArrayList<>();

/**
Expand Down Expand Up @@ -62,67 +67,80 @@ public List<Object> getValues() {
}

public String toFragmentString() {
if ( values.size() == 0 ) {
return "1=2";
}

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" );
final StringBuilder buf = new StringBuilder( values.size() * 5 );

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();
}
}

if ( allowNull ) {
buf.append( '(' ).append( columnName ).append( " is null or " ).append( columnName ).append( " in (" );
}
else {
buf.append( columnName ).append( " in (" );
}
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" );
}
}
}

for ( Object value : values ) {
if ( !NULL.equals( value ) ) {
buf.append( value );
buf.append( ", " );
}
}
if ( allowNull ) {
buf.append( '(' )
.append( columnName )
.append( " is null or " )
.append( columnName )
.append( " in (" );
}
else {
buf.append( columnName ).append( " in (" );
}

buf.setLength( buf.length() - 2 );
for ( Object value : values ) {
if ( !NULL.equals( value ) ) {
buf.append( value );
buf.append( ", " );
}
}

if ( allowNull ) {
buf.append( "))" );
}
else {
buf.append( ')' );
}
buf.setLength( buf.length() - 2 );

return buf.toString();
if ( allowNull ) {
buf.append( "))" );
}
else {
buf.append( ')' );
}

return buf.toString();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7603,7 +7603,7 @@ public void visitGroupedPredicate(GroupedPredicate groupedPredicate) {
public void visitInListPredicate(InListPredicate inListPredicate) {
final List<Expression> listExpressions = inListPredicate.getListExpressions();
if ( listExpressions.isEmpty() ) {
appendSql( "1=" + ( inListPredicate.isNegated() ? "1" : "0" ) );
emptyInList( inListPredicate );
return;
}
Function<Expression, Expression> itemAccessor = Function.identity();
Expand Down Expand Up @@ -7710,6 +7710,16 @@ 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 " );
Expand Down

0 comments on commit e7dea58

Please sign in to comment.