HHH-17804 treat 'null in ()' correctly
This commit is contained in:
parent
492e947b4c
commit
e7dea589ca
|
@ -3255,7 +3255,7 @@ public abstract class AbstractEntityPersister
|
|||
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() );
|
||||
}
|
||||
|
|
|
@ -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<Object> 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();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7603,7 +7603,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
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();
|
||||
|
@ -7710,6 +7710,16 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> 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 " );
|
||||
|
|
Loading…
Reference in New Issue