HHH-15519 make bitand(), bitor(), bitxor() portable

- add bitwise functions on SQL Server and Sybase
- add bitor(), bitxor() on Oracle
- add missing bitwise functions to HANA and h2
- fix broken bitxor() on Postgres
- add bitwise functions for EDB
This commit is contained in:
Gavin King 2024-02-20 00:22:02 +01:00
parent 399b1a0715
commit 5fe2b75d2d
8 changed files with 42 additions and 4 deletions

View File

@ -328,6 +328,7 @@ public class H2LegacyDialect extends Dialect {
functionFactory.bitand();
functionFactory.bitor();
functionFactory.bitxor();
functionFactory.bitnot();
functionFactory.bitAndOr();
functionFactory.yearMonthDay();
functionFactory.hourMinuteSecond();

View File

@ -66,6 +66,7 @@ import org.hibernate.query.sqm.mutation.internal.cte.CteInsertStrategy;
import org.hibernate.query.sqm.mutation.internal.cte.CteMutationStrategy;
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy;
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
@ -80,7 +81,6 @@ import org.hibernate.type.descriptor.jdbc.AggregateJdbcType;
import org.hibernate.type.descriptor.jdbc.BlobJdbcType;
import org.hibernate.type.descriptor.jdbc.ClobJdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeConstructor;
import org.hibernate.type.descriptor.jdbc.ObjectNullAsBinaryTypeJdbcType;
import org.hibernate.type.descriptor.jdbc.XmlJdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
@ -616,6 +616,12 @@ public class PostgreSQLLegacyDialect extends Dialect {
functionContributions.getFunctionRegistry().register( "max", new PostgreSQLMinMaxFunction( "max" ) );
}
// Postgres uses # instead of ^ for XOR
functionContributions.getFunctionRegistry().patternDescriptorBuilder( "bitxor", "(?1#?2)" )
.setExactArgumentCount( 2 )
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
.register();
functionContributions.getFunctionRegistry().register(
"round", new PostgreSQLTruncRoundFunction( "round", true )
);

View File

@ -427,6 +427,9 @@ public abstract class AbstractHANADialect extends Dialect {
functionFactory.log10_log();
functionFactory.log();
functionFactory.bitand();
functionFactory.bitor();
functionFactory.bitxor();
functionFactory.bitnot();
functionFactory.hourMinuteSecond();
functionFactory.yearMonthDay();
functionFactory.dayofweekmonthyear();

View File

@ -150,6 +150,8 @@ public abstract class AbstractTransactSQLDialect extends Dialect {
functionFactory.datepartDatename();
functionFactory.lastDay_eomonth();
functionFactory.bitandorxornot_operator();
functionContributions.getFunctionRegistry().register( "least", new CaseLeastGreatestEmulation( true ) );
functionContributions.getFunctionRegistry().register( "greatest", new CaseLeastGreatestEmulation( false ) );
functionContributions.getFunctionRegistry().register( "str", new TransactSQLStrFunction( functionContributions.getTypeConfiguration() ) );

View File

@ -274,6 +274,7 @@ public class H2Dialect extends Dialect {
functionFactory.bitand();
functionFactory.bitor();
functionFactory.bitxor();
functionFactory.bitnot();
functionFactory.bitAndOr();
functionFactory.yearMonthDay();
functionFactory.hourMinuteSecond();

View File

@ -65,6 +65,7 @@ import org.hibernate.query.sqm.mutation.internal.temptable.GlobalTemporaryTableM
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy;
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
import org.hibernate.query.sqm.produce.function.FunctionParameterType;
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
@ -303,6 +304,17 @@ public class OracleDialect extends Dialect {
//Oracle has had coalesce() since 9.0.1
functionFactory.coalesce();
functionContributions.getFunctionRegistry()
.patternDescriptorBuilder( "bitor", "(?1+?2-bitand(?1,?2))")
.setExactArgumentCount( 2 )
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
.register();
functionContributions.getFunctionRegistry()
.patternDescriptorBuilder( "bitxor", "(?1+?2-2*bitand(?1,?2))")
.setExactArgumentCount( 2 )
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
.register();
functionContributions.getFunctionRegistry().registerBinaryTernaryPattern(
"locate",
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
@ -311,6 +323,7 @@ public class OracleDialect extends Dialect {
FunctionParameterType.STRING, FunctionParameterType.STRING, FunctionParameterType.INTEGER,
typeConfiguration
).setArgumentListSignature("(pattern, string[, start])");
// The within group clause became optional in 18
functionFactory.listagg( null );
functionFactory.windowFunctions();

View File

@ -64,6 +64,7 @@ import org.hibernate.query.sqm.mutation.internal.cte.CteInsertStrategy;
import org.hibernate.query.sqm.mutation.internal.cte.CteMutationStrategy;
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy;
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
@ -662,6 +663,12 @@ public class PostgreSQLDialect extends Dialect {
functionContributions.getFunctionRegistry().register( "max", new PostgreSQLMinMaxFunction( "max" ) );
}
// Postgres uses # instead of ^ for XOR
functionContributions.getFunctionRegistry().patternDescriptorBuilder( "bitxor", "(?1#?2)" )
.setExactArgumentCount( 2 )
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
.register();
functionContributions.getFunctionRegistry().register(
"round", new PostgreSQLTruncRoundFunction( "round", true )
);

View File

@ -17,6 +17,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.persister.entity.mutation.EntityMutationTarget;
import org.hibernate.query.sqm.CastType;
import org.hibernate.query.sqm.TemporalUnit;
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
@ -60,9 +61,13 @@ public class PostgresPlusDialect extends PostgreSQLDialect {
functionFactory.rownumRowid();
functionFactory.sysdate();
functionFactory.systimestamp();
// queryEngine.getSqmFunctionRegistry().register( "coalesce", new NvlCoalesceEmulation() );
functionFactory.bitand();
functionFactory.bitor();
functionContributions.getFunctionRegistry().patternDescriptorBuilder( "bitxor", "(bitor(?1,?2)-bitand(?1,?2))" )
.setExactArgumentCount( 2 )
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
.register();
}
@Override