Fix setting null values on native queries for mysql/mariadb

This commit is contained in:
Christian Beikov 2021-10-04 11:27:48 +02:00
parent 0557536e16
commit 6c49c55087
2 changed files with 43 additions and 19 deletions

View File

@ -93,25 +93,6 @@ public class MariaDBDialect extends MySQLDialect {
};
}
@Override
public String castPattern(CastType from, CastType to) {
if ( to == CastType.INTEGER_BOOLEAN ) {
switch ( from ) {
case STRING:
case INTEGER:
case LONG:
case YN_BOOLEAN:
case TF_BOOLEAN:
case BOOLEAN:
break;
default:
// MariaDB doesn't support casting to bit
return "abs(sign(?1))";
}
}
return super.castPattern( from, to );
}
@Override
public boolean supportsRowValueConstructorSyntaxInInList() {
return true;

View File

@ -7,11 +7,13 @@
package org.hibernate.dialect;
import org.hibernate.LockOptions;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.dialect.function.FieldFunction;
import org.hibernate.engine.jdbc.env.spi.IdentifierCaseStrategy;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
import org.hibernate.engine.jdbc.env.spi.NameQualifierSupport;
import org.hibernate.query.CastType;
import org.hibernate.query.NullOrdering;
import org.hibernate.query.NullPrecedence;
import org.hibernate.PessimisticLockException;
@ -46,14 +48,18 @@ import org.hibernate.query.sqm.mutation.internal.idtable.IdTable;
import org.hibernate.query.sqm.mutation.internal.idtable.LocalTemporaryTableStrategy;
import org.hibernate.query.sqm.mutation.internal.idtable.TempIdTableExporter;
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.type.NullType;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.NullJdbcTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.ObjectNullAsNullTypeJdbcTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
import java.sql.CallableStatement;
@ -391,6 +397,24 @@ public class MySQLDialect extends Dialect {
queryEngine.getSqmFunctionRegistry().register( "field", new FieldFunction() );
}
@Override
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.contributeTypes( typeContributions, serviceRegistry );
// MySQL requires a custom binder for binding untyped nulls with the NULL type
typeContributions.contributeJdbcTypeDescriptor( NullJdbcTypeDescriptor.INSTANCE );
// Until we remove StandardBasicTypes, we have to keep this
typeContributions.contributeType(
new NullType(
NullJdbcTypeDescriptor.INSTANCE,
typeContributions.getTypeConfiguration()
.getJavaTypeDescriptorRegistry()
.getDescriptor( Object.class )
)
);
}
@Override
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
return new StandardSqlAstTranslatorFactory() {
@ -402,6 +426,25 @@ public class MySQLDialect extends Dialect {
};
}
@Override
public String castPattern(CastType from, CastType to) {
if ( to == CastType.INTEGER_BOOLEAN ) {
switch ( from ) {
case STRING:
case INTEGER:
case LONG:
case YN_BOOLEAN:
case TF_BOOLEAN:
case BOOLEAN:
break;
default:
// MySQL/MariaDB don't support casting to bit
return "abs(sign(?1))";
}
}
return super.castPattern( from, to );
}
private void time(QueryEngine queryEngine) {
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "time" )
.setExactArgumentCount( 1 )