Get rid of using specialized BasicType implementations and references to those and instead use a BasicTypeReference that is lazily resolved

This commit is contained in:
Christian Beikov 2021-10-06 16:51:57 +02:00
parent 1cb6ff8916
commit 710ebe57b0
221 changed files with 2833 additions and 1618 deletions

View File

@ -32,6 +32,7 @@ import org.hibernate.dialect.OracleDialect;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.StringType;
import org.hibernate.userguide.model.AddressType;
import org.hibernate.userguide.model.Call;
@ -771,7 +772,7 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
"select p " +
"from Person p " +
"where p.name like :name" )
.setParameter( "name", "J%", StringType.INSTANCE );
.setParameter( "name", "J%", StandardBasicTypes.STRING );
//end::hql-api-parameter-example[]
});
}

View File

@ -27,7 +27,7 @@ public class BitSetUserType implements UserType {
@Override
public int[] sqlTypes() {
return new int[] {StringType.INSTANCE.getJdbcTypeDescriptor().getDefaultSqlTypeCode()};
return new int[] { Types.VARCHAR };
}
@Override

View File

@ -21,6 +21,7 @@ import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
import org.hibernate.loader.NonUniqueDiscoveredSqlAliasException;
import org.hibernate.transform.Transformers;
import org.hibernate.type.LongType;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.StringType;
import org.hibernate.userguide.model.AddressType;
import org.hibernate.userguide.model.Call;
@ -215,8 +216,8 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
//tag::sql-hibernate-scalar-query-explicit-result-set-example[]
List<Object[]> persons = session.createNativeQuery(
"SELECT * FROM Person" )
.addScalar( "id", LongType.INSTANCE )
.addScalar( "name", StringType.INSTANCE )
.addScalar( "id", StandardBasicTypes.LONG )
.addScalar( "name", StandardBasicTypes.STRING )
.list();
for(Object[] person : persons) {
@ -236,7 +237,7 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
//tag::sql-hibernate-scalar-query-partial-explicit-result-set-example[]
List<Object[]> persons = session.createNativeQuery(
"SELECT * FROM Person" )
.addScalar( "id", LongType.INSTANCE )
.addScalar( "id", StandardBasicTypes.LONG )
.addScalar( "name" )
.list();

View File

@ -152,7 +152,7 @@ public class CacheDialect extends Dialect {
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"locate",
StandardBasicTypes.INTEGER,
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
"$find(?2,?1)",
"$find(?2,?1,?3)"
).setArgumentListSignature("(pattern, string[, start])");

View File

@ -52,12 +52,16 @@ import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.community.dialect.sequence.SequenceInformationExtractorFirebirdDatabaseImpl;
import org.hibernate.tool.schema.extract.internal.SequenceNameExtractorImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.BasicType;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
import org.hibernate.type.spi.TypeConfiguration;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.temporal.TemporalAccessor;
import java.util.Arrays;
@ -227,6 +231,13 @@ public class FirebirdDialect extends Dialect {
public void initializeFunctionRegistry(QueryEngine queryEngine) {
super.initializeFunctionRegistry( queryEngine );
final BasicTypeRegistry basicTypeRegistry = queryEngine.getTypeConfiguration().getBasicTypeRegistry();
final BasicType<byte[]> byteArrayType = basicTypeRegistry.resolve( StandardBasicTypes.BINARY );
final BasicType<Integer> integerType = basicTypeRegistry.resolve( StandardBasicTypes.INTEGER );
final BasicType<Short> shortType = basicTypeRegistry.resolve( StandardBasicTypes.SHORT );
final BasicType<Double> doubleType = basicTypeRegistry.resolve( StandardBasicTypes.DOUBLE );
final BasicType<Character> characterType = basicTypeRegistry.resolve( StandardBasicTypes.CHARACTER );
CommonFunctionFactory.concat_pipeOperator( queryEngine );
CommonFunctionFactory.cot( queryEngine );
CommonFunctionFactory.cosh( queryEngine );
@ -260,30 +271,30 @@ public class FirebirdDialect extends Dialect {
SqmFunctionRegistry functionRegistry = queryEngine.getSqmFunctionRegistry();
functionRegistry.registerBinaryTernaryPattern(
"locate",
StandardBasicTypes.INTEGER,
integerType,
"position(?1 in ?2)",
"position(?1,?2,?3)"
).setArgumentListSignature( "(pattern, string[, start])" );
functionRegistry.namedDescriptorBuilder( "ascii_val" )
.setExactArgumentCount( 1 )
.setInvariantType( StandardBasicTypes.SHORT )
.setInvariantType( shortType )
.register();
functionRegistry.registerAlternateKey( "ascii", "ascii_val" );
functionRegistry.namedDescriptorBuilder( "ascii_char" )
.setExactArgumentCount( 1 )
.setInvariantType( StandardBasicTypes.CHARACTER )
.setInvariantType( characterType )
.register();
functionRegistry.registerAlternateKey( "chr", "ascii_char" );
functionRegistry.registerAlternateKey( "char", "ascii_char" );
functionRegistry.registerPattern(
"radians",
"((?1)*pi()/180e0)",
StandardBasicTypes.DOUBLE
doubleType
);
functionRegistry.registerPattern(
"degrees",
"((?1)*180e0/pi())",
StandardBasicTypes.DOUBLE
doubleType
);
if ( getVersion() >= 400 ) {
@ -291,13 +302,13 @@ public class FirebirdDialect extends Dialect {
.forEach( hash -> functionRegistry.registerPattern(
hash,
"crypt_hash(?1 using " + hash + ")",
StandardBasicTypes.BINARY
byteArrayType
) );
functionRegistry.registerAlternateKey( "sha", "sha1" );
functionRegistry.registerPattern(
"crc32",
"hash(?1 using crc32)",
StandardBasicTypes.INTEGER
integerType
);
}
}

View File

@ -167,7 +167,7 @@ public class InformixDialect extends Dialect {
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"locate",
StandardBasicTypes.INTEGER,
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
"instr(?2,?1)",
"instr(?2,?1,?3)"
).setArgumentListSignature("(pattern, string[, start])");

View File

@ -48,6 +48,8 @@ import org.hibernate.sql.ast.tree.select.SelectStatement;
import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.tool.schema.extract.internal.SequenceNameExtractorImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.BasicType;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
@ -217,6 +219,9 @@ public class IngresDialect extends Dialect {
public void initializeFunctionRegistry(QueryEngine queryEngine) {
super.initializeFunctionRegistry( queryEngine );
final BasicTypeRegistry basicTypeRegistry = queryEngine.getTypeConfiguration().getBasicTypeRegistry();
final BasicType<String> stringType = basicTypeRegistry.resolve( StandardBasicTypes.STRING );
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Common functions
@ -247,20 +252,22 @@ public class IngresDialect extends Dialect {
CommonFunctionFactory.dateTrunc( queryEngine );
CommonFunctionFactory.bitLength_pattern( queryEngine, "octet_length(hex(?1))*4" );
final BasicType<Integer> integerType = queryEngine.getTypeConfiguration().getBasicTypeRegistry()
.resolve( StandardBasicTypes.INTEGER );
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"locate",
StandardBasicTypes.INTEGER,
integerType,
"position(?1 in ?2)",
"(position(?1 in substring(?2 from ?3))+(?3)-1)"
).setArgumentListSignature("(pattern, string[, start])");
queryEngine.getSqmFunctionRegistry().registerPattern( "extract", "date_part('?1',?2)", StandardBasicTypes.INTEGER );
queryEngine.getSqmFunctionRegistry().registerPattern( "extract", "date_part('?1',?2)", integerType );
CommonFunctionFactory.bitandorxornot_bitAndOrXorNot(queryEngine);
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "squeeze" )
.setExactArgumentCount( 1 )
.setInvariantType( StandardBasicTypes.STRING )
.setInvariantType( stringType )
.register();
}

View File

@ -28,6 +28,7 @@ import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.community.dialect.sequence.SequenceInformationExtractorSAPDBDatabaseImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.BasicType;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
@ -131,20 +132,22 @@ public class MaxDBDialect extends Dialect {
CommonFunctionFactory.adddateSubdateAddtimeSubtime( queryEngine );
CommonFunctionFactory.addMonths( queryEngine );
queryEngine.getSqmFunctionRegistry().registerPattern( "extract", "?1(?2)", StandardBasicTypes.INTEGER );
final BasicType<Integer> integerType = queryEngine.getTypeConfiguration().getBasicTypeRegistry()
.resolve( StandardBasicTypes.INTEGER );
queryEngine.getSqmFunctionRegistry().registerPattern( "extract", "?1(?2)", integerType );
queryEngine.getSqmFunctionRegistry().patternDescriptorBuilder( "nullif", "case ?1 when ?2 then null else ?1 end" )
.setExactArgumentCount(2)
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "index" )
.setInvariantType( StandardBasicTypes.INTEGER )
.setInvariantType( integerType )
.setArgumentCountBetween( 2, 4 )
.register();
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"locate",
StandardBasicTypes.INTEGER, "index(?2,?1)", "index(?2,?1,?3)"
integerType, "index(?2,?1)", "index(?2,?1,?3)"
).setArgumentListSignature("(pattern, string[, start])");
}

View File

@ -48,6 +48,8 @@ import org.hibernate.sql.ast.spi.SqlAppender;
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.BasicType;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.jdbc.BlobJdbcTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.ClobJdbcTypeDescriptor;
@ -235,6 +237,10 @@ public class SQLiteDialect extends Dialect {
public void initializeFunctionRegistry(QueryEngine queryEngine) {
super.initializeFunctionRegistry( queryEngine );
final BasicTypeRegistry basicTypeRegistry = queryEngine.getTypeConfiguration().getBasicTypeRegistry();
final BasicType<String> stringType = basicTypeRegistry.resolve( StandardBasicTypes.STRING );
final BasicType<Integer> integerType = basicTypeRegistry.resolve( StandardBasicTypes.INTEGER );
CommonFunctionFactory.mod_operator( queryEngine );
CommonFunctionFactory.leftRight_substr( queryEngine );
CommonFunctionFactory.concat_pipeOperator( queryEngine );
@ -252,25 +258,25 @@ public class SQLiteDialect extends Dialect {
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"locate",
StandardBasicTypes.INTEGER,
integerType,
"instr(?2,?1)",
"instr(?2,?1,?3)"
).setArgumentListSignature("(pattern, string[, start])");
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"lpad",
StandardBasicTypes.STRING,
stringType,
"(substr(replace(hex(zeroblob(?2)),'00',' '),1,?2-length(?1))||?1)",
"(substr(replace(hex(zeroblob(?2)),'00',?3),1,?2-length(?1))||?1)"
).setArgumentListSignature("(string, length[, padding])");
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"rpad",
StandardBasicTypes.STRING,
stringType,
"(?1||substr(replace(hex(zeroblob(?2)),'00',' '),1,?2-length(?1)))",
"(?1||substr(replace(hex(zeroblob(?2)),'00',?3),1,?2-length(?1)))"
).setArgumentListSignature("(string, length[, padding])");
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder("format", "strftime")
.setInvariantType( StandardBasicTypes.STRING )
.setInvariantType( stringType )
.setExactArgumentCount( 2 )
.setArgumentListSignature("(datetime as pattern)")
.register();

View File

@ -43,6 +43,8 @@ import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.tool.schema.internal.StandardIndexExporter;
import org.hibernate.tool.schema.spi.Exporter;
import org.hibernate.type.BasicType;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
@ -234,6 +236,8 @@ public class TeradataDialect extends Dialect {
@Override
public void initializeFunctionRegistry(QueryEngine queryEngine) {
super.initializeFunctionRegistry( queryEngine );
final BasicTypeRegistry basicTypeRegistry = queryEngine.getTypeConfiguration().getBasicTypeRegistry();
final BasicType<String> stringType = basicTypeRegistry.resolve( StandardBasicTypes.STRING );
CommonFunctionFactory.concat_pipeOperator( queryEngine );
CommonFunctionFactory.octetLength( queryEngine );
@ -246,7 +250,7 @@ public class TeradataDialect extends Dialect {
CommonFunctionFactory.bitLength_pattern( queryEngine, "octet_length(cast(?1 as char))*4" );
queryEngine.getSqmFunctionRegistry().patternDescriptorBuilder( "mod", "(?1 mod ?2)" )
.setInvariantType( StandardBasicTypes.STRING )
.setInvariantType( stringType )
.setExactArgumentCount( 2 )
.register();

View File

@ -151,7 +151,7 @@ public class TimesTenDialect extends Dialect {
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"locate",
StandardBasicTypes.INTEGER,
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
"instr(?2,?1)",
"instr(?2,?1,?3)"
).setArgumentListSignature("(pattern, string[, start])");

View File

@ -18,7 +18,13 @@ import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.type.BasicType;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.java.DateJavaTypeDescriptor;
import org.hibernate.type.descriptor.java.JdbcDateJavaTypeDescriptor;
import org.hibernate.type.descriptor.java.JdbcTimestampJavaTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.DateJdbcTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.TimestampJdbcTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.testing.TestForIssue;
@ -28,6 +34,7 @@ import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* Testing of patched support for Informix boolean type; see HHH-9894, HHH-10800
@ -85,9 +92,11 @@ public class InformixDialectTestCase extends BaseUnitTestCase {
SelfRenderingSqmFunction<Object> sqmExpression = functionDescriptor.generateSqmExpression(
null,
queryEngine,
null
new TypeConfiguration()
);
assertEquals( StandardBasicTypes.TIMESTAMP, sqmExpression.getNodeType() );
BasicType<?> basicType = (BasicType<?>) sqmExpression.getNodeType();
assertEquals( DateJavaTypeDescriptor.INSTANCE, basicType.getJavaTypeDescriptor() );
assertEquals( TimestampJdbcTypeDescriptor.INSTANCE, basicType.getJdbcTypeDescriptor() );
SqlAppender appender = new StringBuilderSqlAppender();
sqmExpression.getRenderingSupport().render( appender, Collections.emptyList(), null );
@ -102,9 +111,11 @@ public class InformixDialectTestCase extends BaseUnitTestCase {
SelfRenderingSqmFunction<Object> sqmExpression = functionDescriptor.generateSqmExpression(
null,
queryEngine,
null
new TypeConfiguration()
);
assertEquals( StandardBasicTypes.DATE, sqmExpression.getNodeType() );
BasicType<?> basicType = (BasicType<?>) sqmExpression.getNodeType();
assertEquals( DateJavaTypeDescriptor.INSTANCE, basicType.getJavaTypeDescriptor() );
assertEquals( DateJdbcTypeDescriptor.INSTANCE, basicType.getJdbcTypeDescriptor() );
SqlAppender appender = new StringBuilderSqlAppender();
sqmExpression.getRenderingSupport().render( appender, Collections.emptyList(), null );

View File

@ -749,6 +749,11 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
return basicTypeRegistrations;
}
@Override
public TypeConfiguration getTypeConfiguration() {
return bootstrapContext.getTypeConfiguration();
}
@Override
public ReflectionManager getReflectionManager() {
return bootstrapContext.getReflectionManager();
@ -887,7 +892,7 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
}
}
public void setBootstrapContext(BootstrapContextImpl bootstrapContext) {
public void setBootstrapContext(BootstrapContext bootstrapContext) {
this.bootstrapContext = bootstrapContext;
}
}

View File

@ -0,0 +1,24 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.boot.model;
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.spi.TypeConfiguration;
/**
* Defines the target contributing functions, whether via dialects or {@link FunctionContributor}
*
* @author Christian Beikov
*/
public interface FunctionContributions {
TypeConfiguration getTypeConfiguration();
SqmFunctionRegistry getFunctionRegistry();
ServiceRegistry getServiceRegistry();
}

View File

@ -27,10 +27,9 @@ public interface FunctionContributor {
/**
* Contribute functions
*
* @param functionRegistry The target for the contributions
* @param serviceRegistry The service registry
* @param functionContributions The target for the contributions
*/
void contributeFunctions(SqmFunctionRegistry functionRegistry, ServiceRegistry serviceRegistry);
void contributeFunctions(FunctionContributions functionContributions);
/**
* Determines order in which the contributions will be applied (lowest ordinal first).

View File

@ -14,12 +14,10 @@ import org.hibernate.mapping.BasicValue;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.type.BasicType;
import org.hibernate.type.RowVersionType;
import org.hibernate.type.descriptor.java.BasicJavaTypeDescriptor;
import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.MutabilityPlan;
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
import org.hibernate.type.spi.TypeConfiguration;
@ -45,16 +43,6 @@ public class VersionResolution<E> implements BasicValue.Resolution<E> {
final java.lang.reflect.Type implicitJavaType = implicitJavaTypeAccess.apply( typeConfiguration );
final JavaTypeDescriptor registered = typeConfiguration.getJavaTypeDescriptorRegistry().resolveDescriptor( implicitJavaType );
if ( registered instanceof PrimitiveByteArrayJavaTypeDescriptor ) {
return new VersionResolution<>(
RowVersionType.INSTANCE.getJavaTypeDescriptor(),
RowVersionType.INSTANCE.getJdbcTypeDescriptor(),
RowVersionType.INSTANCE,
RowVersionType.INSTANCE
);
}
final BasicJavaTypeDescriptor jtd = (BasicJavaTypeDescriptor) registered;
final JdbcTypeDescriptor recommendedJdbcType = jtd.getRecommendedJdbcType(

View File

@ -22,6 +22,7 @@ import org.hibernate.dialect.H2Dialect;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Steve Ebersole
@ -29,6 +30,7 @@ import org.hibernate.service.ServiceRegistry;
public class Database {
private final Dialect dialect;
private final TypeConfiguration typeConfiguration;
private final JdbcEnvironment jdbcEnvironment;
private final Map<Namespace.Name,Namespace> namespaceMap = new TreeMap<>();
private final Map<String,AuxiliaryDatabaseObject> auxiliaryDatabaseObjects = new HashMap<>();
@ -44,6 +46,7 @@ public class Database {
public Database(MetadataBuildingOptions buildingOptions, JdbcEnvironment jdbcEnvironment) {
this.serviceRegistry = buildingOptions.getServiceRegistry();
this.typeConfiguration = buildingOptions.getTypeConfiguration();
this.jdbcEnvironment = jdbcEnvironment;
this.physicalNamingStrategy = buildingOptions.getPhysicalNamingStrategy();
this.dialect = determineDialect( buildingOptions );
@ -169,4 +172,8 @@ public class Database {
public ServiceRegistry getServiceRegistry() {
return serviceRegistry;
}
public TypeConfiguration getTypeConfiguration() {
return typeConfiguration;
}
}

View File

@ -6,6 +6,7 @@
*/
package org.hibernate.boot.model.source.internal.hbm;
import java.sql.Types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@ -2019,14 +2020,22 @@ public class ModelBinder {
private static boolean isLob(Integer sqlType, String sqlTypeName) {
if ( sqlType != null ) {
return ClobType.INSTANCE.getJdbcTypeDescriptor().getJdbcTypeCode() == sqlType ||
BlobType.INSTANCE.getJdbcTypeDescriptor().getJdbcTypeCode() == sqlType ||
NClobType.INSTANCE.getJdbcTypeDescriptor().getJdbcTypeCode() == sqlType;
switch ( sqlType ) {
case Types.BLOB:
case Types.CLOB:
case Types.NCLOB:
return true;
}
return false;
}
else if ( sqlTypeName != null ) {
return ClobType.INSTANCE.getName().equalsIgnoreCase( sqlTypeName ) ||
BlobType.INSTANCE.getName().equalsIgnoreCase( sqlTypeName ) ||
NClobType.INSTANCE.getName().equalsIgnoreCase( sqlTypeName );
switch ( sqlTypeName.toLowerCase( Locale.ROOT ) ) {
case "blob":
case "clob":
case "nclob":
return true;
}
return false;
}
return false;
}
@ -2405,8 +2414,9 @@ public class ModelBinder {
);
}
else {
discriminatorTypeName = StandardBasicTypes.STRING.getTypeName();
discriminatorType = StandardBasicTypes.STRING;
discriminatorTypeName = StandardBasicTypes.STRING.getName();
discriminatorType = metadataBuildingContext.getBootstrapContext().getTypeConfiguration().getBasicTypeRegistry()
.resolve( StandardBasicTypes.STRING );
}
anyBinding.setMetaType( discriminatorTypeName );

View File

@ -22,6 +22,7 @@ import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cfg.MetadataSourceType;
import org.hibernate.type.spi.TypeConfiguration;
import org.jboss.jandex.IndexView;
@ -59,6 +60,11 @@ public abstract class AbstractDelegatingMetadataBuildingOptions implements Metad
return delegate.getBasicTypeRegistrations();
}
@Override
public TypeConfiguration getTypeConfiguration() {
return delegate.getTypeConfiguration();
}
@Override
public IndexView getJandexView() {
return delegate.getJandexView();

View File

@ -25,6 +25,7 @@ import org.hibernate.collection.internal.StandardCollectionSemanticsResolver;
import org.hibernate.collection.spi.CollectionSemanticsResolver;
import org.hibernate.metamodel.internal.ManagedTypeRepresentationResolverStandard;
import org.hibernate.metamodel.spi.ManagedTypeRepresentationResolver;
import org.hibernate.type.spi.TypeConfiguration;
import org.jboss.jandex.IndexView;
@ -182,6 +183,8 @@ public interface MetadataBuildingOptions {
IdGeneratorStrategyInterpreter getIdGenerationTypeInterpreter();
TypeConfiguration getTypeConfiguration();
/**
* Access to all explicit cache region mappings.
*

View File

@ -15,6 +15,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.UUID;
import org.hibernate.AssertionFailure;
import org.hibernate.FlushMode;
@ -39,14 +40,9 @@ import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.resource.transaction.spi.TransactionStatus;
import org.hibernate.type.BasicType;
import org.hibernate.type.CompositeType;
import org.hibernate.type.IntegerType;
import org.hibernate.type.LongType;
import org.hibernate.type.PostgresUUIDType;
import org.hibernate.type.StringType;
import org.hibernate.type.Type;
import org.hibernate.type.UUIDBinaryType;
import org.hibernate.type.UUIDCharType;
/**
* Base class implementing {@link PersistentCollection}
@ -1261,12 +1257,14 @@ public abstract class AbstractPersistentCollection<E> implements Serializable, P
}
private static boolean mayUseIdDirect(Type idType) {
return idType == StringType.INSTANCE
|| idType == IntegerType.INSTANCE
|| idType == LongType.INSTANCE
|| idType == UUIDBinaryType.INSTANCE
|| idType == UUIDCharType.INSTANCE
|| idType == PostgresUUIDType.INSTANCE;
if ( idType instanceof BasicType<?> ) {
final Class<?> javaType = ( (BasicType<?>) idType ).getJavaType();
return javaType == String.class
|| javaType == Integer.class
|| javaType == Long.class
|| javaType == UUID.class;
}
return false;
}
/**

View File

@ -60,7 +60,7 @@ import org.hibernate.type.descriptor.java.DataHelper;
import org.hibernate.type.descriptor.java.DoubleJavaTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.*;
import org.hibernate.type.internal.StandardBasicTypeImpl;
import org.hibernate.type.internal.BasicTypeImpl;
import java.io.*;
import java.nio.charset.StandardCharsets;
@ -823,7 +823,7 @@ public abstract class AbstractHANADialect extends Dialect {
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"locate",
StandardBasicTypes.INTEGER,
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
"locate(?2,?1)",
"locate(?2,?1,?3)"
).setArgumentListSignature("(pattern, string[, start])");
@ -1477,7 +1477,7 @@ public abstract class AbstractHANADialect extends Dialect {
registerHibernateType( Types.DOUBLE, StandardBasicTypes.BIG_DECIMAL.getName() );
typeContributions.getTypeConfiguration().getBasicTypeRegistry()
.register(
new StandardBasicTypeImpl<>(
new BasicTypeImpl<>(
DoubleJavaTypeDescriptor.INSTANCE,
NumericJdbcTypeDescriptor.INSTANCE
),

View File

@ -125,7 +125,7 @@ public abstract class AbstractTransactSQLDialect extends Dialect {
queryEngine.getSqmFunctionRegistry().register( "least", new CaseLeastGreatestEmulation( true ) );
queryEngine.getSqmFunctionRegistry().register( "greatest", new CaseLeastGreatestEmulation( false ) );
queryEngine.getSqmFunctionRegistry().register( "str", new TransactSQLStrFunction() );
queryEngine.getSqmFunctionRegistry().register( "str", new TransactSQLStrFunction( queryEngine.getTypeConfiguration() ) );
}
@Override

View File

@ -28,6 +28,8 @@ import org.hibernate.sql.ast.spi.SqlAppender;
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.BasicType;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.StandardBasicTypes;
import java.sql.DatabaseMetaData;
@ -107,6 +109,9 @@ public class CockroachDialect extends Dialect {
public void initializeFunctionRegistry(QueryEngine queryEngine) {
super.initializeFunctionRegistry(queryEngine);
final BasicTypeRegistry basicTypeRegistry = queryEngine.getTypeConfiguration().getBasicTypeRegistry();
final BasicType<String> stringType = basicTypeRegistry.resolve( StandardBasicTypes.STRING );
CommonFunctionFactory.ascii( queryEngine );
CommonFunctionFactory.char_chr( queryEngine );
CommonFunctionFactory.overlay( queryEngine );
@ -129,7 +134,7 @@ public class CockroachDialect extends Dialect {
CommonFunctionFactory.trunc( queryEngine ); //TODO: emulate second arg
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder("format", "experimental_strftime")
.setInvariantType( StandardBasicTypes.STRING )
.setInvariantType( stringType )
.setExactArgumentCount( 2 )
.setArgumentListSignature("(datetime as pattern)")
.register();

View File

@ -197,10 +197,12 @@ public class DB2Dialect extends Dialect {
CommonFunctionFactory.dateTrunc( queryEngine );
CommonFunctionFactory.bitLength_pattern( queryEngine, "length(?1)*8" );
queryEngine.getSqmFunctionRegistry().register( "format", new DB2FormatEmulation() );
queryEngine.getSqmFunctionRegistry().register( "format", new DB2FormatEmulation( queryEngine.getTypeConfiguration() ) );
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "posstr" )
.setInvariantType( StandardBasicTypes.INTEGER )
.setInvariantType(
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER )
)
.setExactArgumentCount( 2 )
.setArgumentListSignature("(string, pattern)")
.register();

View File

@ -53,6 +53,8 @@ import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorDerbyDatabaseImpl;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.BasicType;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.JavaObjectType;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.jdbc.DecimalJdbcTypeDescriptor;
@ -188,13 +190,16 @@ public class DerbyDialect extends Dialect {
public void initializeFunctionRegistry(QueryEngine queryEngine) {
super.initializeFunctionRegistry( queryEngine );
final BasicTypeRegistry basicTypeRegistry = queryEngine.getTypeConfiguration().getBasicTypeRegistry();
final BasicType<String> stringType = basicTypeRegistry.resolve( StandardBasicTypes.STRING );
// Derby needs an actual argument type for aggregates like SUM, AVG, MIN, MAX to determine the result type
CommonFunctionFactory.aggregates(
this,
queryEngine,
SqlAstNodeRenderingMode.NO_PLAIN_PARAMETER,
"||",
getCastTypeName( StandardBasicTypes.STRING, null, null, null )
getCastTypeName( stringType, null, null, null )
);
CommonFunctionFactory.concat_pipeOperator( queryEngine );
@ -223,14 +228,14 @@ public class DerbyDialect extends Dialect {
.setExactArgumentCount( 2 )
.register();
queryEngine.getSqmFunctionRegistry().register( "concat", new DerbyConcatFunction( this ) );
queryEngine.getSqmFunctionRegistry().register( "concat", new DerbyConcatFunction( this, queryEngine.getTypeConfiguration() ) );
//no way I can see to pad with anything other than spaces
queryEngine.getSqmFunctionRegistry().register( "lpad", new DerbyLpadEmulation() );
queryEngine.getSqmFunctionRegistry().register( "rpad", new DerbyRpadEmulation() );
queryEngine.getSqmFunctionRegistry().register( "lpad", new DerbyLpadEmulation( queryEngine.getTypeConfiguration() ) );
queryEngine.getSqmFunctionRegistry().register( "rpad", new DerbyRpadEmulation( queryEngine.getTypeConfiguration() ) );
queryEngine.getSqmFunctionRegistry().register( "least", new CaseLeastGreatestEmulation( true ) );
queryEngine.getSqmFunctionRegistry().register( "greatest", new CaseLeastGreatestEmulation( false ) );
queryEngine.getSqmFunctionRegistry().register( "overlay", new InsertSubstringOverlayEmulation( true ) );
queryEngine.getSqmFunctionRegistry().register( "overlay", new InsertSubstringOverlayEmulation( queryEngine.getTypeConfiguration(), true ) );
}
@Override

View File

@ -73,6 +73,8 @@ import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNo
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.tool.schema.internal.*;
import org.hibernate.tool.schema.spi.Exporter;
import org.hibernate.type.BasicType;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
@ -89,6 +91,11 @@ import jakarta.persistence.TemporalType;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.*;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.temporal.TemporalAccessor;
import java.util.Date;
import java.util.*;
@ -188,43 +195,43 @@ public abstract class Dialect implements ConversionContext {
registerColumnType( Types.NCLOB, "nclob" );
// register hibernate types for default use in scalar sqlquery type auto detection
registerHibernateType( Types.BOOLEAN, StandardBasicTypes.BOOLEAN.getTypeName() );
registerHibernateType( Types.BOOLEAN, StandardBasicTypes.BOOLEAN.getName() );
registerHibernateType( Types.BIT, 64, StandardBasicTypes.LONG.getTypeName() );
registerHibernateType( Types.BIT, 32, StandardBasicTypes.INTEGER.getTypeName() );
registerHibernateType( Types.BIT, 16, StandardBasicTypes.SHORT.getTypeName() );
registerHibernateType( Types.BIT, 8, StandardBasicTypes.BYTE.getTypeName() );
registerHibernateType( Types.BIT, 1, StandardBasicTypes.BOOLEAN.getTypeName() );
registerHibernateType( Types.BIT, 64, StandardBasicTypes.LONG.getName() );
registerHibernateType( Types.BIT, 32, StandardBasicTypes.INTEGER.getName() );
registerHibernateType( Types.BIT, 16, StandardBasicTypes.SHORT.getName() );
registerHibernateType( Types.BIT, 8, StandardBasicTypes.BYTE.getName() );
registerHibernateType( Types.BIT, 1, StandardBasicTypes.BOOLEAN.getName() );
registerHibernateType( Types.REAL, StandardBasicTypes.FLOAT.getTypeName() );
registerHibernateType( Types.DOUBLE, StandardBasicTypes.DOUBLE.getTypeName() );
registerHibernateType( Types.FLOAT, StandardBasicTypes.DOUBLE.getTypeName() );
registerHibernateType( Types.NUMERIC, StandardBasicTypes.BIG_DECIMAL.getTypeName() );
registerHibernateType( Types.DECIMAL, StandardBasicTypes.BIG_DECIMAL.getTypeName() );
registerHibernateType( Types.REAL, StandardBasicTypes.FLOAT.getName() );
registerHibernateType( Types.DOUBLE, StandardBasicTypes.DOUBLE.getName() );
registerHibernateType( Types.FLOAT, StandardBasicTypes.DOUBLE.getName() );
registerHibernateType( Types.NUMERIC, StandardBasicTypes.BIG_DECIMAL.getName() );
registerHibernateType( Types.DECIMAL, StandardBasicTypes.BIG_DECIMAL.getName() );
registerHibernateType( Types.BIGINT, StandardBasicTypes.LONG.getTypeName() );
registerHibernateType( Types.INTEGER, StandardBasicTypes.INTEGER.getTypeName() );
registerHibernateType( Types.SMALLINT, StandardBasicTypes.SHORT.getTypeName() );
registerHibernateType( Types.TINYINT, StandardBasicTypes.BYTE.getTypeName() );
registerHibernateType( Types.BIGINT, StandardBasicTypes.LONG.getName() );
registerHibernateType( Types.INTEGER, StandardBasicTypes.INTEGER.getName() );
registerHibernateType( Types.SMALLINT, StandardBasicTypes.SHORT.getName() );
registerHibernateType( Types.TINYINT, StandardBasicTypes.BYTE.getName() );
registerHibernateType( Types.CHAR, 1, StandardBasicTypes.CHARACTER.getTypeName() );
registerHibernateType( Types.CHAR, StandardBasicTypes.STRING.getTypeName() );
registerHibernateType( Types.VARCHAR, 1, StandardBasicTypes.CHARACTER.getTypeName() );
registerHibernateType( Types.VARCHAR, StandardBasicTypes.STRING.getTypeName() );
registerHibernateType( Types.NVARCHAR, StandardBasicTypes.NSTRING.getTypeName() );
registerHibernateType( Types.LONGVARCHAR, StandardBasicTypes.TEXT.getTypeName() );
registerHibernateType( Types.LONGNVARCHAR, StandardBasicTypes.NTEXT.getTypeName() );
registerHibernateType( Types.CHAR, 1, StandardBasicTypes.CHARACTER.getName() );
registerHibernateType( Types.CHAR, StandardBasicTypes.STRING.getName() );
registerHibernateType( Types.VARCHAR, 1, StandardBasicTypes.CHARACTER.getName() );
registerHibernateType( Types.VARCHAR, StandardBasicTypes.STRING.getName() );
registerHibernateType( Types.NVARCHAR, StandardBasicTypes.NSTRING.getName() );
registerHibernateType( Types.LONGVARCHAR, StandardBasicTypes.TEXT.getName() );
registerHibernateType( Types.LONGNVARCHAR, StandardBasicTypes.NTEXT.getName() );
registerHibernateType( Types.BINARY, StandardBasicTypes.BINARY.getTypeName() );
registerHibernateType( Types.VARBINARY, StandardBasicTypes.BINARY.getTypeName() );
registerHibernateType( Types.LONGVARBINARY, StandardBasicTypes.IMAGE.getTypeName() );
registerHibernateType( Types.BINARY, StandardBasicTypes.BINARY.getName() );
registerHibernateType( Types.VARBINARY, StandardBasicTypes.BINARY.getName() );
registerHibernateType( Types.LONGVARBINARY, StandardBasicTypes.IMAGE.getName() );
registerHibernateType( Types.BLOB, StandardBasicTypes.BLOB.getTypeName() );
registerHibernateType( Types.CLOB, StandardBasicTypes.CLOB.getTypeName() );
registerHibernateType( Types.BLOB, StandardBasicTypes.BLOB.getName() );
registerHibernateType( Types.CLOB, StandardBasicTypes.CLOB.getName() );
registerHibernateType( Types.DATE, StandardBasicTypes.DATE.getTypeName() );
registerHibernateType( Types.TIME, StandardBasicTypes.TIME.getTypeName() );
registerHibernateType( Types.TIMESTAMP, StandardBasicTypes.TIMESTAMP.getTypeName() );
registerHibernateType( Types.DATE, StandardBasicTypes.DATE.getName() );
registerHibernateType( Types.TIME, StandardBasicTypes.TIME.getName() );
registerHibernateType( Types.TIMESTAMP, StandardBasicTypes.TIMESTAMP.getName() );
if(supportsPartitionBy()) {
registerKeyword( "PARTITION" );
@ -478,6 +485,15 @@ public abstract class Dialect implements ConversionContext {
*
*/
public void initializeFunctionRegistry(QueryEngine queryEngine) {
final BasicTypeRegistry basicTypeRegistry = queryEngine.getTypeConfiguration().getBasicTypeRegistry();
final BasicType<Date> timestampType = basicTypeRegistry.resolve( StandardBasicTypes.TIMESTAMP );
final BasicType<Date> dateType = basicTypeRegistry.resolve( StandardBasicTypes.DATE );
final BasicType<Date> timeType = basicTypeRegistry.resolve( StandardBasicTypes.TIME );
final BasicType<Instant> instantType = basicTypeRegistry.resolve( StandardBasicTypes.INSTANT );
final BasicType<OffsetDateTime> offsetDateTimeType = basicTypeRegistry.resolve( StandardBasicTypes.OFFSET_DATE_TIME );
final BasicType<LocalDateTime> localDateTimeType = basicTypeRegistry.resolve( StandardBasicTypes.LOCAL_DATE_TIME );
final BasicType<LocalTime> localTimeType = basicTypeRegistry.resolve( StandardBasicTypes.LOCAL_TIME );
final BasicType<LocalDate> localDateType = basicTypeRegistry.resolve( StandardBasicTypes.LOCAL_DATE );
//aggregate functions, supported on every database
@ -531,18 +547,18 @@ public abstract class Dialect implements ConversionContext {
//only some databases support the ANSI SQL-style position() function, so
//define it here as an alias for locate()
queryEngine.getSqmFunctionRegistry().register( "position", new LocatePositionEmulation() );
queryEngine.getSqmFunctionRegistry().register( "position", new LocatePositionEmulation( queryEngine.getTypeConfiguration() ) );
//very few databases support ANSI-style overlay() function, so emulate
//it here in terms of either insert() or concat()/substring()
queryEngine.getSqmFunctionRegistry().register( "overlay", new InsertSubstringOverlayEmulation( false ) );
queryEngine.getSqmFunctionRegistry().register( "overlay", new InsertSubstringOverlayEmulation( queryEngine.getTypeConfiguration(), false ) );
//ANSI SQL trim() function is supported on almost all of the databases
//we care about, but on some it must be emulated using ltrim(), rtrim(),
//and replace()
queryEngine.getSqmFunctionRegistry().register( "trim", new TrimFunction( this ) );
queryEngine.getSqmFunctionRegistry().register( "trim", new TrimFunction( this, queryEngine.getTypeConfiguration() ) );
//ANSI SQL cast() function is supported on the databases we care most
//about but in certain cases it doesn't allow some useful typecasts,
@ -580,12 +596,12 @@ public abstract class Dialect implements ConversionContext {
//pad() is a function we've designed to look like ANSI trim()
queryEngine.getSqmFunctionRegistry().register( "pad", new LpadRpadPadEmulation() );
queryEngine.getSqmFunctionRegistry().register( "pad", new LpadRpadPadEmulation( queryEngine.getTypeConfiguration() ) );
//legacy Hibernate convenience function for casting to string, defined
//here as an alias for cast(arg as String)
queryEngine.getSqmFunctionRegistry().register( "str", new CastStrEmulation() );
queryEngine.getSqmFunctionRegistry().register( "str", new CastStrEmulation( queryEngine.getTypeConfiguration() ) );
//format() function for datetimes, emulated on many databases using the
//Oracle-style to_char() function, and on others using their native
@ -596,8 +612,8 @@ public abstract class Dialect implements ConversionContext {
//timestampadd()/timestampdiff() delegated back to the Dialect itself
//since there is a great variety of different ways to emulate them
queryEngine.getSqmFunctionRegistry().register( "timestampadd", new TimestampaddFunction( this ) );
queryEngine.getSqmFunctionRegistry().register( "timestampdiff", new TimestampdiffFunction( this ) );
queryEngine.getSqmFunctionRegistry().register( "timestampadd", new TimestampaddFunction( this, queryEngine.getTypeConfiguration() ) );
queryEngine.getSqmFunctionRegistry().register( "timestampdiff", new TimestampdiffFunction( this, queryEngine.getTypeConfiguration() ) );
queryEngine.getSqmFunctionRegistry().registerAlternateKey( "dateadd", "timestampadd" );
queryEngine.getSqmFunctionRegistry().registerAlternateKey( "datediff", "timestampdiff" );
@ -609,7 +625,7 @@ public abstract class Dialect implements ConversionContext {
new CurrentFunction(
"current_date",
currentDate(),
StandardBasicTypes.DATE
dateType
)
);
queryEngine.getSqmFunctionRegistry().register(
@ -617,7 +633,7 @@ public abstract class Dialect implements ConversionContext {
new CurrentFunction(
"current_time",
currentTime(),
StandardBasicTypes.TIME
timeType
)
);
queryEngine.getSqmFunctionRegistry().register(
@ -625,7 +641,7 @@ public abstract class Dialect implements ConversionContext {
new CurrentFunction(
"current_timestamp",
currentTimestamp(),
StandardBasicTypes.TIMESTAMP
timestampType
)
);
queryEngine.getSqmFunctionRegistry().registerAlternateKey( "current date", "current_date" );
@ -638,7 +654,7 @@ public abstract class Dialect implements ConversionContext {
new CurrentFunction(
"local_date",
currentDate(),
StandardBasicTypes.LOCAL_DATE
localDateType
)
);
queryEngine.getSqmFunctionRegistry().register(
@ -646,7 +662,7 @@ public abstract class Dialect implements ConversionContext {
new CurrentFunction(
"local_time",
currentLocalTime(),
StandardBasicTypes.LOCAL_TIME
localTimeType
)
);
queryEngine.getSqmFunctionRegistry().register(
@ -654,7 +670,7 @@ public abstract class Dialect implements ConversionContext {
new CurrentFunction(
"local_datetime",
currentLocalTimestamp(),
StandardBasicTypes.LOCAL_DATE_TIME
localDateTimeType
)
);
queryEngine.getSqmFunctionRegistry().register(
@ -662,7 +678,7 @@ public abstract class Dialect implements ConversionContext {
new CurrentFunction(
"offset_datetime",
currentTimestampWithTimeZone(),
StandardBasicTypes.OFFSET_DATE_TIME
offsetDateTimeType
)
);
queryEngine.getSqmFunctionRegistry().registerAlternateKey( "local date", "local_date" );
@ -675,7 +691,7 @@ public abstract class Dialect implements ConversionContext {
new CurrentFunction(
"instant",
currentTimestamp(),
StandardBasicTypes.INSTANT
instantType
)
);
queryEngine.getSqmFunctionRegistry().registerAlternateKey( "current_instant", "instant" ); //deprecated legacy!
@ -3458,7 +3474,8 @@ public abstract class Dialect implements ConversionContext {
JdbcTypeDescriptor jdbcType,
JavaTypeDescriptor<?> javaType,
Integer precision,
Integer scale, Long length);
Integer scale,
Long length);
}
public class SizeStrategyImpl implements SizeStrategy {
@ -3478,25 +3495,27 @@ public abstract class Dialect implements ConversionContext {
if ( javaType.getJavaTypeClass() == Boolean.class && length != null && length == 255 ) {
length = null;
}
size.setLength( javaType.getDefaultSqlLength( Dialect.this ) );
size.setLength( javaType.getDefaultSqlLength( Dialect.this, jdbcType ) );
break;
case Types.CHAR:
// Use the default length for char if we encounter the JPA default 255 instead
if ( javaType.getJavaTypeClass() == Character.class && length != null && length == 255 ) {
case Types.NCHAR:
// Use the default length for char and UUID if we encounter the JPA default 255 instead
if ( length != null && length == 255 ) {
if ( javaType.getJavaTypeClass() == Character.class || javaType.getJavaTypeClass() == UUID.class ) {
length = null;
}
size.setLength( javaType.getDefaultSqlLength( Dialect.this ) );
}
size.setLength( javaType.getDefaultSqlLength( Dialect.this, jdbcType ) );
break;
case Types.NCHAR:
case Types.BINARY:
case Types.VARCHAR:
case Types.NVARCHAR:
case Types.BINARY:
case Types.VARBINARY:
// Use the default length for UUID if we encounter the JPA default 255 instead
if ( javaType.getJavaTypeClass() == UUID.class && length != null && length == 255 ) {
length = null;
}
size.setLength( javaType.getDefaultSqlLength( Dialect.this ) );
size.setLength( javaType.getDefaultSqlLength( Dialect.this, jdbcType ) );
break;
case Types.LONGVARCHAR:
case Types.LONGNVARCHAR:
@ -3528,7 +3547,7 @@ public abstract class Dialect implements ConversionContext {
break;
case Types.CLOB:
case Types.BLOB:
size.setLength( javaType.getDefaultSqlLength(Dialect.this) );
size.setLength( javaType.getDefaultSqlLength( Dialect.this, jdbcType ) );
break;
}

View File

@ -103,12 +103,15 @@ public class HANAColumnStoreDialect extends AbstractHANADialect {
super.initializeFunctionRegistry( queryEngine );
// full-text search functions
queryEngine.getSqmFunctionRegistry().registerNamed( "score", StandardBasicTypes.DOUBLE );
queryEngine.getSqmFunctionRegistry().registerNamed(
"score",
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.DOUBLE )
);
queryEngine.getSqmFunctionRegistry().registerNamed( "snippets" );
queryEngine.getSqmFunctionRegistry().registerNamed( "highlighted" );
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"contains",
StandardBasicTypes.BOOLEAN,
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.BOOLEAN ),
"contains(?1,?2)",
"contains(?1,?2,?3)"
);

View File

@ -77,7 +77,12 @@ public class MariaDBDialect extends MySQLDialect {
super.initializeFunctionRegistry(queryEngine);
if ( getVersion() >= 1020 ) {
queryEngine.getSqmFunctionRegistry().registerNamed("json_valid", StandardBasicTypes.NUMERIC_BOOLEAN);
queryEngine.getSqmFunctionRegistry().registerNamed(
"json_valid",
queryEngine.getTypeConfiguration()
.getBasicTypeRegistry()
.resolve( StandardBasicTypes.BOOLEAN )
);
}
}

View File

@ -59,7 +59,6 @@ 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;
@ -394,7 +393,7 @@ public class MySQLDialect extends Dialect {
CommonFunctionFactory.sysdateExplicitMicros( queryEngine );
}
queryEngine.getSqmFunctionRegistry().register( "field", new FieldFunction() );
queryEngine.getSqmFunctionRegistry().register( "field", new FieldFunction( queryEngine.getTypeConfiguration() ) );
}
@Override
@ -448,7 +447,9 @@ public class MySQLDialect extends Dialect {
private void time(QueryEngine queryEngine) {
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "time" )
.setExactArgumentCount( 1 )
.setInvariantType( StandardBasicTypes.STRING )
.setInvariantType(
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
)
.register();
}
@ -731,7 +732,10 @@ public class MySQLDialect extends Dialect {
//inconsistent with other Dialects which need a length
return String.format(
"binary(%d)",
length == null ? type.getJdbcMapping().getJavaTypeDescriptor().getDefaultSqlLength(this) : length
length != null ? length : type.getJdbcMapping().getJavaTypeDescriptor().getDefaultSqlLength(
this,
type.getJdbcMapping().getJdbcTypeDescriptor()
)
);
case Types.VARCHAR:
case Types.LONGVARCHAR:
@ -740,7 +744,10 @@ public class MySQLDialect extends Dialect {
//inconsistent with other Dialects which need a length
return String.format(
"char(%d)",
length == null ? type.getJdbcMapping().getJavaTypeDescriptor().getDefaultSqlLength(this) : length
length != null ? length : type.getJdbcMapping().getJavaTypeDescriptor().getDefaultSqlLength(
this,
type.getJdbcMapping().getJdbcTypeDescriptor()
)
);
default:
return super.getCastTypeName( type, length, precision, scale );

View File

@ -189,7 +189,7 @@ public class OracleDialect extends Dialect {
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"locate",
StandardBasicTypes.INTEGER,
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
"instr(?2,?1)",
"instr(?2,?1,?3)"
).setArgumentListSignature("(pattern, string[, start])");

View File

@ -335,7 +335,7 @@ public class PostgreSQLDialect extends Dialect {
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"locate",
StandardBasicTypes.INTEGER,
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
"position(?1 in ?2)",
"(position(?1 in substring(?2 from ?3))+(?3)-1)"
).setArgumentListSignature("(pattern, string[, start])");

View File

@ -44,6 +44,8 @@ import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.tool.schema.internal.StandardSequenceExporter;
import org.hibernate.tool.schema.spi.Exporter;
import org.hibernate.type.BasicType;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
@ -51,6 +53,7 @@ import org.hibernate.type.descriptor.jdbc.SmallIntJdbcTypeDescriptor;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
@ -167,6 +170,11 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
public void initializeFunctionRegistry(QueryEngine queryEngine) {
super.initializeFunctionRegistry(queryEngine);
final BasicTypeRegistry basicTypeRegistry = queryEngine.getTypeConfiguration().getBasicTypeRegistry();
BasicType<Date> dateType = basicTypeRegistry.resolve( StandardBasicTypes.DATE );
BasicType<Date> timeType = basicTypeRegistry.resolve( StandardBasicTypes.TIME );
BasicType<Date> timestampType = basicTypeRegistry.resolve( StandardBasicTypes.TIMESTAMP );
// For SQL-Server we need to cast certain arguments to varchar(max) to be able to concat them
CommonFunctionFactory.aggregates( this, queryEngine, SqlAstNodeRenderingMode.DEFAULT, "+", "varchar(max)" );
@ -181,7 +189,7 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
}
if ( getVersion() >= 11 ) {
queryEngine.getSqmFunctionRegistry().register( "format", new SQLServerFormatEmulation( this ) );
queryEngine.getSqmFunctionRegistry().register( "format", new SQLServerFormatEmulation( this, queryEngine.getTypeConfiguration() ) );
//actually translate() was added in 2017 but
//it's not worth adding a new dialect for that!
@ -190,27 +198,27 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
CommonFunctionFactory.median_percentileCont( queryEngine, true );
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "datefromparts" )
.setInvariantType( StandardBasicTypes.DATE )
.setInvariantType( dateType )
.setExactArgumentCount( 3 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "timefromparts" )
.setInvariantType( StandardBasicTypes.TIME )
.setInvariantType( timeType )
.setExactArgumentCount( 5 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "smalldatetimefromparts" )
.setInvariantType( StandardBasicTypes.TIMESTAMP )
.setInvariantType( timestampType )
.setExactArgumentCount( 5 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "datetimefromparts" )
.setInvariantType( StandardBasicTypes.TIMESTAMP )
.setInvariantType( timestampType )
.setExactArgumentCount( 7 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "datetime2fromparts" )
.setInvariantType( StandardBasicTypes.TIMESTAMP )
.setInvariantType( timestampType )
.setExactArgumentCount( 8 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "datetimeoffsetfromparts" )
.setInvariantType( StandardBasicTypes.TIMESTAMP )
.setInvariantType( timestampType )
.setExactArgumentCount( 10 )
.register();
}

View File

@ -39,9 +39,12 @@ import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.tool.schema.spi.Exporter;
import org.hibernate.type.BasicType;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.StandardBasicTypes;
import java.sql.Types;
import java.util.Date;
import java.util.Map;
import jakarta.persistence.TemporalType;
@ -108,6 +111,13 @@ public class SpannerDialect extends Dialect {
@Override
public void initializeFunctionRegistry(QueryEngine queryEngine) {
super.initializeFunctionRegistry( queryEngine );
final BasicTypeRegistry basicTypeRegistry = queryEngine.getTypeConfiguration().getBasicTypeRegistry();
final BasicType<byte[]> byteArrayType = basicTypeRegistry.resolve( StandardBasicTypes.BINARY );
final BasicType<Long> longType = basicTypeRegistry.resolve( StandardBasicTypes.LONG );
final BasicType<Boolean> booleanType = basicTypeRegistry.resolve( StandardBasicTypes.BOOLEAN );
final BasicType<String> stringType = basicTypeRegistry.resolve( StandardBasicTypes.STRING );
final BasicType<Date> dateType = basicTypeRegistry.resolve( StandardBasicTypes.DATE );
final BasicType<Date> timestampType = basicTypeRegistry.resolve( StandardBasicTypes.TIMESTAMP );
// Aggregate Functions
queryEngine.getSqmFunctionRegistry().namedAggregateDescriptorBuilder( "any_value" )
@ -117,19 +127,19 @@ public class SpannerDialect extends Dialect {
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedAggregateDescriptorBuilder( "countif" )
.setInvariantType( StandardBasicTypes.LONG )
.setInvariantType( longType )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedAggregateDescriptorBuilder( "logical_and" )
.setInvariantType( StandardBasicTypes.BOOLEAN )
.setInvariantType( booleanType )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedAggregateDescriptorBuilder( "logical_or" )
.setInvariantType( StandardBasicTypes.BOOLEAN )
.setInvariantType( booleanType )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedAggregateDescriptorBuilder( "string_agg" )
.setInvariantType( StandardBasicTypes.STRING )
.setInvariantType( stringType )
.setArgumentCountBetween( 1, 2 )
.register();
@ -146,19 +156,19 @@ public class SpannerDialect extends Dialect {
CommonFunctionFactory.bitandorxornot_bitAndOrXorNot( queryEngine );
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "is_inf" )
.setInvariantType( StandardBasicTypes.BOOLEAN )
.setInvariantType( booleanType )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "is_nan" )
.setInvariantType( StandardBasicTypes.BOOLEAN )
.setInvariantType( booleanType )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "ieee_divide" )
.setInvariantType( StandardBasicTypes.DOUBLE )
.setInvariantType( booleanType )
.setExactArgumentCount( 2 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "div" )
.setInvariantType( StandardBasicTypes.LONG )
.setInvariantType( longType )
.setExactArgumentCount( 2 )
.register();
@ -166,15 +176,15 @@ public class SpannerDialect extends Dialect {
// Hash Functions
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "farm_fingerprint" )
.setInvariantType( StandardBasicTypes.LONG )
.setInvariantType( longType )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "sha256" )
.setInvariantType( StandardBasicTypes.BINARY )
.setInvariantType( byteArrayType )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "sha512" )
.setInvariantType( StandardBasicTypes.BINARY )
.setInvariantType( byteArrayType )
.setExactArgumentCount( 1 )
.register();
@ -186,34 +196,34 @@ public class SpannerDialect extends Dialect {
CommonFunctionFactory.substr( queryEngine );
CommonFunctionFactory.substring_substr( queryEngine );
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "byte_length" )
.setInvariantType( StandardBasicTypes.LONG )
.setInvariantType( longType )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "code_points_to_bytes" )
.setInvariantType( StandardBasicTypes.BINARY )
.setInvariantType( byteArrayType )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "code_points_to_string" )
.setInvariantType( StandardBasicTypes.STRING )
.setInvariantType( stringType )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "ends_with" )
.setInvariantType( StandardBasicTypes.BOOLEAN )
.setInvariantType( booleanType )
.setExactArgumentCount( 2 )
.register();
// queryEngine.getSqmFunctionRegistry().namedTemplateBuilder( "format" )
// .setInvariantType( StandardBasicTypes.STRING )
// .register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "from_base64" )
.setInvariantType( StandardBasicTypes.BINARY )
.setInvariantType( byteArrayType )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "from_hex" )
.setInvariantType( StandardBasicTypes.BINARY )
.setInvariantType( byteArrayType )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "regexp_contains" )
.setInvariantType( StandardBasicTypes.BOOLEAN )
.setInvariantType( booleanType )
.setExactArgumentCount( 2 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "regexp_extract" )
@ -226,39 +236,39 @@ public class SpannerDialect extends Dialect {
.setExactArgumentCount( 3 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "safe_convert_bytes_to_string" )
.setInvariantType( StandardBasicTypes.STRING )
.setInvariantType( stringType )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "split" )
.setArgumentCountBetween( 1, 2 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "starts_with" )
.setInvariantType( StandardBasicTypes.BOOLEAN )
.setInvariantType( booleanType )
.setExactArgumentCount( 2 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "strpos" )
.setInvariantType( StandardBasicTypes.LONG )
.setInvariantType( longType )
.setExactArgumentCount( 2 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "to_base64" )
.setInvariantType( StandardBasicTypes.STRING )
.setInvariantType( stringType )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "to_code_points" )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "to_hex" )
.setInvariantType( StandardBasicTypes.STRING )
.setInvariantType( stringType )
.setExactArgumentCount( 1 )
.register();
// JSON Functions
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "json_query" )
.setInvariantType( StandardBasicTypes.STRING )
.setInvariantType( stringType )
.setExactArgumentCount( 2 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "json_value" )
.setInvariantType( StandardBasicTypes.STRING )
.setInvariantType( stringType )
.setExactArgumentCount( 2 )
.register();
@ -269,11 +279,11 @@ public class SpannerDialect extends Dialect {
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "array_concat" )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "array_length" )
.setInvariantType( StandardBasicTypes.LONG )
.setInvariantType( longType )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "array_to_string" )
.setInvariantType( StandardBasicTypes.STRING )
.setInvariantType( stringType )
.setArgumentCountBetween( 2, 3 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "array_reverse" )
@ -282,102 +292,102 @@ public class SpannerDialect extends Dialect {
// Date functions
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "date" )
.setInvariantType( StandardBasicTypes.DATE )
.setInvariantType( dateType )
.setArgumentCountBetween( 1, 3 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "date_add" )
.setInvariantType( StandardBasicTypes.DATE )
.setInvariantType( dateType )
.setExactArgumentCount( 2 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "date_sub" )
.setInvariantType( StandardBasicTypes.DATE )
.setInvariantType( dateType )
.setExactArgumentCount( 2 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "date_diff" )
.setInvariantType( StandardBasicTypes.LONG )
.setInvariantType( longType )
.setExactArgumentCount( 3 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "date_trunc" )
.setInvariantType( StandardBasicTypes.DATE )
.setInvariantType( dateType )
.setExactArgumentCount( 2 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "date_from_unix_date" )
.setInvariantType( StandardBasicTypes.DATE )
.setInvariantType( dateType )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "format_date" )
.setInvariantType( StandardBasicTypes.STRING )
.setInvariantType( stringType )
.setExactArgumentCount( 2 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "parse_date" )
.setInvariantType( StandardBasicTypes.DATE )
.setInvariantType( dateType )
.setExactArgumentCount( 2 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "unix_date" )
.setInvariantType( StandardBasicTypes.LONG )
.setInvariantType( longType )
.setExactArgumentCount( 1 )
.register();
// Timestamp functions
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "string" )
.setInvariantType( StandardBasicTypes.STRING )
.setInvariantType( stringType )
.setArgumentCountBetween( 1, 2 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "timestamp" )
.setInvariantType( StandardBasicTypes.TIMESTAMP )
.setInvariantType( timestampType )
.setArgumentCountBetween( 1, 2 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "timestamp_add" )
.setInvariantType( StandardBasicTypes.TIMESTAMP )
.setInvariantType( timestampType )
.setExactArgumentCount( 2 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "timestamp_sub" )
.setInvariantType( StandardBasicTypes.TIMESTAMP )
.setInvariantType( timestampType )
.setExactArgumentCount( 2 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "timestamp_diff" )
.setInvariantType( StandardBasicTypes.LONG )
.setInvariantType( longType )
.setExactArgumentCount( 3 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "timestamp_trunc" )
.setInvariantType( StandardBasicTypes.TIMESTAMP )
.setInvariantType( timestampType )
.setArgumentCountBetween( 2, 3 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "format_timestamp" )
.setInvariantType( StandardBasicTypes.STRING )
.setInvariantType( stringType )
.setArgumentCountBetween( 2, 3 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "parse_timestamp" )
.setInvariantType( StandardBasicTypes.TIMESTAMP )
.setInvariantType( timestampType )
.setArgumentCountBetween( 2, 3 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "timestamp_seconds" )
.setInvariantType( StandardBasicTypes.TIMESTAMP )
.setInvariantType( timestampType )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "timestamp_millis" )
.setInvariantType( StandardBasicTypes.TIMESTAMP )
.setInvariantType( timestampType )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "timestamp_micros" )
.setInvariantType( StandardBasicTypes.TIMESTAMP )
.setInvariantType( timestampType )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "unix_seconds" )
.setInvariantType( StandardBasicTypes.LONG )
.setInvariantType( longType )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "unix_millis" )
.setInvariantType( StandardBasicTypes.LONG )
.setInvariantType( longType )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "unix_micros" )
.setInvariantType( StandardBasicTypes.LONG )
.setInvariantType( longType )
.setExactArgumentCount( 1 )
.register();
queryEngine.getSqmFunctionRegistry().patternDescriptorBuilder("format", "format_timestamp(?2,?1)")
.setInvariantType( StandardBasicTypes.STRING )
.setInvariantType( stringType )
.setExactArgumentCount( 2 )
.setArgumentListSignature("(datetime as pattern)")
.register();

View File

@ -237,7 +237,7 @@ public class SybaseDialect extends AbstractTransactSQLDialect {
// For SQL-Server we need to cast certain arguments to varchar(16384) to be able to concat them
CommonFunctionFactory.aggregates( this, queryEngine, SqlAstNodeRenderingMode.DEFAULT, "+", "varchar(16384)" );
queryEngine.getSqmFunctionRegistry().register( "concat", new SybaseConcatFunction( this ) );
queryEngine.getSqmFunctionRegistry().register( "concat", new SybaseConcatFunction( this, queryEngine.getTypeConfiguration() ) );
//this doesn't work 100% on earlier versions of Sybase
//which were missing the third parameter in charindex()

View File

@ -17,6 +17,7 @@ import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.sql.ast.tree.predicate.Predicate;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Jan Schatteman
@ -25,12 +26,14 @@ public class CaseWhenEveryAnyEmulation extends AbstractSqmSelfRenderingFunctionD
private final boolean every;
public CaseWhenEveryAnyEmulation(boolean every) {
public CaseWhenEveryAnyEmulation(TypeConfiguration typeConfiguration, boolean every) {
super(
every ? "every" : "any",
FunctionKind.AGGREGATE,
StandardArgumentsValidators.exactly( 1 ),
StandardFunctionReturnTypeResolvers.invariant( StandardBasicTypes.BOOLEAN )
StandardFunctionReturnTypeResolvers.invariant(
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.BOOLEAN )
)
);
this.every = every;
}

View File

@ -29,11 +29,13 @@ import static java.util.Arrays.asList;
public class CastStrEmulation
extends AbstractSqmFunctionDescriptor {
public CastStrEmulation() {
public CastStrEmulation(TypeConfiguration typeConfiguration) {
super(
"str",
StandardArgumentsValidators.exactly( 1 ),
StandardFunctionReturnTypeResolvers.invariant( StandardBasicTypes.STRING )
StandardFunctionReturnTypeResolvers.invariant(
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
)
);
}
@ -56,7 +58,7 @@ public class CastStrEmulation
asList(
argument,
new SqmCastTarget<>(
StandardBasicTypes.STRING,
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING ),
argument.nodeBuilder()
)
),

View File

@ -34,6 +34,7 @@ import org.hibernate.sql.ast.tree.from.TableGroupJoin;
import org.hibernate.sql.ast.tree.predicate.Predicate;
import org.hibernate.sql.ast.tree.select.QuerySpec;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Christian Beikov
@ -45,12 +46,14 @@ public class CountFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
private final String concatOperator;
private final String concatArgumentCastType;
public CountFunction(Dialect dialect, String concatOperator, String concatArgumentCastType) {
public CountFunction(Dialect dialect, TypeConfiguration typeConfiguration, String concatOperator, String concatArgumentCastType) {
super(
FUNCTION_NAME,
FunctionKind.AGGREGATE,
StandardArgumentsValidators.exactly( 1 ),
StandardFunctionReturnTypeResolvers.invariant( StandardBasicTypes.LONG )
StandardFunctionReturnTypeResolvers.invariant(
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.LONG )
)
);
this.dialect = dialect;
this.concatOperator = concatOperator;

View File

@ -7,6 +7,7 @@
package org.hibernate.dialect.function;
import org.hibernate.dialect.OracleDialect;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
@ -32,11 +33,13 @@ import jakarta.persistence.TemporalType;
public class DB2FormatEmulation
extends AbstractSqmSelfRenderingFunctionDescriptor {
public DB2FormatEmulation() {
public DB2FormatEmulation(TypeConfiguration typeConfiguration) {
super(
"format",
StandardArgumentsValidators.exactly( 2 ),
StandardFunctionReturnTypeResolvers.invariant( StandardBasicTypes.STRING )
StandardFunctionReturnTypeResolvers.invariant(
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
)
);
}

View File

@ -12,6 +12,7 @@ import java.util.List;
import org.hibernate.dialect.Dialect;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.query.CastType;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
@ -22,16 +23,19 @@ import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.spi.TypeConfiguration;
public class DerbyConcatFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
private final Dialect dialect;
public DerbyConcatFunction(Dialect dialect) {
public DerbyConcatFunction(Dialect dialect, TypeConfiguration typeConfiguration) {
super(
"concat",
StandardArgumentsValidators.min( 1 ),
StandardFunctionReturnTypeResolvers.invariant( StandardBasicTypes.STRING )
StandardFunctionReturnTypeResolvers.invariant(
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
)
);
this.dialect = dialect;
}

View File

@ -8,6 +8,7 @@ package org.hibernate.dialect.function;
import java.util.List;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
@ -16,6 +17,7 @@ import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.spi.TypeConfiguration;
/**
* A derby implementation for lpad.
@ -25,11 +27,13 @@ import org.hibernate.type.StandardBasicTypes;
public class DerbyLpadEmulation
extends AbstractSqmSelfRenderingFunctionDescriptor {
public DerbyLpadEmulation() {
public DerbyLpadEmulation(TypeConfiguration typeConfiguration) {
super(
"lpad",
StandardArgumentsValidators.exactly( 2 ),
StandardFunctionReturnTypeResolvers.invariant( StandardBasicTypes.STRING )
StandardFunctionReturnTypeResolvers.invariant(
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
)
);
}

View File

@ -8,6 +8,7 @@ package org.hibernate.dialect.function;
import java.util.List;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
@ -16,6 +17,7 @@ import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.spi.TypeConfiguration;
/**
* A derby implementation for rpad.
@ -25,11 +27,13 @@ import org.hibernate.type.StandardBasicTypes;
public class DerbyRpadEmulation
extends AbstractSqmSelfRenderingFunctionDescriptor {
public DerbyRpadEmulation() {
public DerbyRpadEmulation(TypeConfiguration typeConfiguration) {
super(
"rpad",
StandardArgumentsValidators.exactly( 2 ),
StandardFunctionReturnTypeResolvers.invariant( StandardBasicTypes.STRING )
StandardFunctionReturnTypeResolvers.invariant(
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
)
);
}

View File

@ -32,12 +32,14 @@ public class EveryAnyEmulation extends AbstractSqmSelfRenderingFunctionDescripto
private final boolean every;
public EveryAnyEmulation(boolean every) {
public EveryAnyEmulation(TypeConfiguration typeConfiguration, boolean every) {
super(
every ? "every" : "any",
FunctionKind.AGGREGATE,
StandardArgumentsValidators.exactly( 1 ),
StandardFunctionReturnTypeResolvers.invariant( StandardBasicTypes.BOOLEAN )
StandardFunctionReturnTypeResolvers.invariant(
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.BOOLEAN )
)
);
this.every = every;
}

View File

@ -18,13 +18,17 @@ import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.expression.SqlTuple;
import org.hibernate.sql.ast.tree.expression.SqlTupleContainer;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.spi.TypeConfiguration;
public class FieldFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
public FieldFunction() {
public FieldFunction(TypeConfiguration typeConfiguration) {
super(
"field",
StandardArgumentsValidators.min( 2 ),
StandardFunctionReturnTypeResolvers.invariant( StandardBasicTypes.INTEGER )
StandardFunctionReturnTypeResolvers.invariant(
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER )
)
);
}

View File

@ -40,11 +40,13 @@ public class InsertSubstringOverlayEmulation
private final boolean strictSubstring;
public InsertSubstringOverlayEmulation(boolean strictSubstring) {
public InsertSubstringOverlayEmulation(TypeConfiguration typeConfiguration, boolean strictSubstring) {
super(
"overlay",
StandardArgumentsValidators.between( 3, 4 ),
StandardFunctionReturnTypeResolvers.invariant( StandardBasicTypes.STRING )
StandardFunctionReturnTypeResolvers.invariant(
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
)
);
this.strictSubstring = strictSubstring;
}

View File

@ -21,14 +21,15 @@ import java.util.List;
/**
* @author Gavin King
*/
public class LocatePositionEmulation
extends AbstractSqmFunctionDescriptor {
public class LocatePositionEmulation extends AbstractSqmFunctionDescriptor {
public LocatePositionEmulation() {
public LocatePositionEmulation(TypeConfiguration typeConfiguration) {
super(
"position",
StandardArgumentsValidators.exactly( 2 ),
StandardFunctionReturnTypeResolvers.invariant( StandardBasicTypes.INTEGER )
StandardFunctionReturnTypeResolvers.invariant(
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER )
)
);
}

View File

@ -28,11 +28,13 @@ import static java.util.Arrays.asList;
public class LpadRpadPadEmulation
extends AbstractSqmFunctionDescriptor {
public LpadRpadPadEmulation() {
public LpadRpadPadEmulation(TypeConfiguration typeConfiguration) {
super(
"pad",
StandardArgumentsValidators.between( 3, 4 ),
StandardFunctionReturnTypeResolvers.invariant( StandardBasicTypes.STRING )
StandardFunctionReturnTypeResolvers.invariant(
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
)
);
}

View File

@ -17,6 +17,7 @@ import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.sql.ast.tree.predicate.Predicate;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Jan Schatteman
@ -25,12 +26,14 @@ public class SQLServerEveryAnyEmulation extends AbstractSqmSelfRenderingFunction
private final boolean every;
public SQLServerEveryAnyEmulation(boolean every) {
public SQLServerEveryAnyEmulation(TypeConfiguration typeConfiguration, boolean every) {
super(
every ? "every" : "any",
FunctionKind.AGGREGATE,
StandardArgumentsValidators.exactly( 1 ),
StandardFunctionReturnTypeResolvers.invariant( StandardBasicTypes.BOOLEAN )
StandardFunctionReturnTypeResolvers.invariant(
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.BOOLEAN )
)
);
this.every = every;
}

View File

@ -10,6 +10,7 @@ import java.util.List;
import jakarta.persistence.TemporalType;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
@ -30,11 +31,13 @@ public class SQLServerFormatEmulation extends AbstractSqmSelfRenderingFunctionDe
private final SQLServerDialect dialect;
public SQLServerFormatEmulation(SQLServerDialect dialect) {
public SQLServerFormatEmulation(SQLServerDialect dialect, TypeConfiguration typeConfiguration) {
super(
"format",
StandardArgumentsValidators.exactly( 2 ),
StandardFunctionReturnTypeResolvers.invariant( StandardBasicTypes.STRING )
StandardFunctionReturnTypeResolvers.invariant(
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
)
);
this.dialect = dialect;
}

View File

@ -6,8 +6,8 @@
*/
package org.hibernate.dialect.function;
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
import org.hibernate.query.sqm.function.NamedSqmFunctionDescriptor;
import org.hibernate.type.BasicTypeReference;
/**
* Simplified API allowing users to contribute
@ -17,22 +17,22 @@ import org.hibernate.query.sqm.function.NamedSqmFunctionDescriptor;
* @author David Channon
*/
public class StandardSQLFunction extends NamedSqmFunctionDescriptor {
private final AllowableFunctionReturnType type;
private final BasicTypeReference<?> type;
public StandardSQLFunction(String name) {
this( name, null );
}
public StandardSQLFunction(String name, AllowableFunctionReturnType type) {
public StandardSQLFunction(String name, BasicTypeReference<?> type) {
this( name, true, type );
}
public StandardSQLFunction(String name, boolean useParentheses, AllowableFunctionReturnType type) {
public StandardSQLFunction(String name, boolean useParentheses, BasicTypeReference<?> type) {
super( name, useParentheses, null, null );
this.type = type;
}
public AllowableFunctionReturnType getType() {
public BasicTypeReference<?> getType() {
return type;
}
}

View File

@ -12,6 +12,7 @@ import java.util.List;
import org.hibernate.dialect.Dialect;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.query.CastType;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
@ -22,16 +23,19 @@ import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.spi.TypeConfiguration;
public class SybaseConcatFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
private final Dialect dialect;
public SybaseConcatFunction(Dialect dialect) {
public SybaseConcatFunction(Dialect dialect, TypeConfiguration typeConfiguration) {
super(
"concat",
StandardArgumentsValidators.min( 1 ),
StandardFunctionReturnTypeResolvers.invariant( StandardBasicTypes.STRING )
StandardFunctionReturnTypeResolvers.invariant(
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
)
);
this.dialect = dialect;
}

View File

@ -25,6 +25,7 @@ import org.hibernate.sql.ast.tree.expression.CastTarget;
import org.hibernate.sql.ast.tree.expression.DurationUnit;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.expression.QueryLiteral;
import org.hibernate.type.BasicType;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.spi.TypeConfiguration;
@ -43,8 +44,9 @@ public class TimestampaddFunction
private final Dialect dialect;
private final CastFunction castFunction;
private final BasicType<Integer> integerType;
public TimestampaddFunction(Dialect dialect) {
public TimestampaddFunction(Dialect dialect, TypeConfiguration typeConfiguration) {
super(
"timestampadd",
StandardArgumentsValidators.exactly( 3 ),
@ -52,6 +54,7 @@ public class TimestampaddFunction
);
this.dialect = dialect;
this.castFunction = new CastFunction( dialect, Types.BOOLEAN );
this.integerType = typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER );
}
@Override
@ -123,7 +126,8 @@ public class TimestampaddFunction
)
);
}
castArguments.add( new CastTarget( StandardBasicTypes.INTEGER ) );
castArguments.add( new CastTarget( integerType ) );
newArguments.set( 0, new DurationUnit( unit, field.getExpressionType() ) );
newArguments.set(
1,
@ -131,8 +135,8 @@ public class TimestampaddFunction
"cast",
castFunction::render,
castArguments,
StandardBasicTypes.INTEGER,
StandardBasicTypes.INTEGER
integerType,
integerType
)
);

View File

@ -33,11 +33,13 @@ public class TimestampdiffFunction
private final Dialect dialect;
public TimestampdiffFunction(Dialect dialect) {
public TimestampdiffFunction(Dialect dialect, TypeConfiguration typeConfiguration) {
super(
"timestampdiff",
StandardArgumentsValidators.exactly( 3 ),
StandardFunctionReturnTypeResolvers.invariant( StandardBasicTypes.LONG )
StandardFunctionReturnTypeResolvers.invariant(
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.LONG )
)
);
this.dialect = dialect;
}

View File

@ -29,11 +29,13 @@ import org.hibernate.type.spi.TypeConfiguration;
*/
public class TransactSQLStrFunction extends CastStrEmulation implements FunctionRenderingSupport {
public TransactSQLStrFunction() {
public TransactSQLStrFunction(TypeConfiguration typeConfiguration) {
super(
"str",
StandardArgumentsValidators.between( 1, 3 ),
StandardFunctionReturnTypeResolvers.invariant( StandardBasicTypes.STRING )
StandardFunctionReturnTypeResolvers.invariant(
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
)
);
}

View File

@ -8,6 +8,7 @@ package org.hibernate.dialect.function;
import org.hibernate.dialect.Dialect;
import org.hibernate.query.TrimSpec;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
@ -19,6 +20,7 @@ import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.expression.QueryLiteral;
import org.hibernate.sql.ast.tree.expression.TrimSpecification;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.spi.TypeConfiguration;
import java.util.Collections;
import java.util.List;
@ -28,13 +30,15 @@ import java.util.List;
*/
public class TrimFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
private Dialect dialect;
private final Dialect dialect;
public TrimFunction(Dialect dialect) {
public TrimFunction(Dialect dialect, TypeConfiguration typeConfiguration) {
super(
"trim",
StandardArgumentsValidators.exactly( 3 ),
StandardFunctionReturnTypeResolvers.invariant( StandardBasicTypes.STRING )
StandardFunctionReturnTypeResolvers.invariant(
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
)
);
this.dialect = dialect;
}

View File

@ -42,7 +42,9 @@ import org.hibernate.mapping.Column;
import org.hibernate.mapping.PrimaryKey;
import org.hibernate.mapping.Table;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.LongType;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.StringType;
import org.hibernate.type.Type;
@ -332,11 +334,12 @@ public class MultipleHiLoPerTableGenerator implements PersistentIdentifierGenera
// todo : not sure the best solution here. do we add the columns if missing? other?
table.setPrimaryKey( new PrimaryKey( table ) );
final BasicTypeRegistry basicTypeRegistry = database.getTypeConfiguration().getBasicTypeRegistry();
final Column pkColumn = new ExportableColumn(
database,
table,
segmentColumnName,
StringType.INSTANCE,
basicTypeRegistry.resolve( StandardBasicTypes.STRING ),
database.getDialect().getTypeName( Types.VARCHAR, Size.length(keySize) )
);
pkColumn.setNullable( false );
@ -347,7 +350,7 @@ public class MultipleHiLoPerTableGenerator implements PersistentIdentifierGenera
database,
table,
valueColumnName,
LongType.INSTANCE
basicTypeRegistry.resolve( StandardBasicTypes.LONG )
);
table.addColumn( valueColumn );
}

View File

@ -50,7 +50,9 @@ import org.hibernate.mapping.Column;
import org.hibernate.mapping.PrimaryKey;
import org.hibernate.mapping.Table;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.LongType;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.StringType;
import org.hibernate.type.Type;
@ -714,12 +716,13 @@ public class TableGenerator implements PersistentIdentifierGenerator, Configurab
(identifier) -> new Table( contributor, namespace, identifier, false )
);
final BasicTypeRegistry basicTypeRegistry = database.getTypeConfiguration().getBasicTypeRegistry();
// todo : not sure the best solution here. do we add the columns if missing? other?
final Column segmentColumn = new ExportableColumn(
database,
table,
segmentColumnName,
StringType.INSTANCE,
basicTypeRegistry.resolve( StandardBasicTypes.STRING ),
dialect.getTypeName( Types.VARCHAR, Size.length(segmentValueLength) )
);
segmentColumn.setNullable( false );
@ -733,7 +736,7 @@ public class TableGenerator implements PersistentIdentifierGenerator, Configurab
database,
table,
valueColumnName,
LongType.INSTANCE
basicTypeRegistry.resolve( StandardBasicTypes.LONG )
);
table.addColumn( valueColumn );
}

View File

@ -36,6 +36,7 @@ import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.jdbc.AbstractReturningWork;
import org.hibernate.mapping.Table;
import org.hibernate.type.LongType;
import org.hibernate.type.StandardBasicTypes;
import org.jboss.logging.Logger;
@ -284,7 +285,7 @@ public class TableStructure implements DatabaseStructure {
database,
table,
valueColumnNameText,
LongType.INSTANCE
database.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.LONG )
);
table.addColumn( valueColumn );

View File

@ -839,7 +839,7 @@ public interface CoreMessageLogger extends BasicLogger {
@LogMessage(level = WARN)
@Message(value = "Type [%s] defined no registration keys; ignoring", id = 269)
void typeDefinedNoRegistrationKeys(BasicType type);
void typeDefinedNoRegistrationKeys(Object type);
@LogMessage(level = DEBUG)
@Message(value = "Type registration key [%s] overrode previous key : %s", id = 270)

View File

@ -48,6 +48,7 @@ import org.hibernate.sql.results.graph.basic.BasicResult;
import org.hibernate.sql.results.internal.RowTransformerDatabaseSnapshotImpl;
import org.hibernate.sql.results.spi.ListResultsConsumer;
import org.hibernate.type.IntegerType;
import org.hibernate.type.StandardBasicTypes;
import org.jboss.logging.Logger;
@ -107,7 +108,12 @@ class DatabaseSnapshotExecutor {
// We just need a literal to have a result set
domainResults.add(
new QueryLiteral<>( null, IntegerType.INSTANCE ).createDomainResult( null, state )
new QueryLiteral<>(
null,
sessionFactory.getTypeConfiguration()
.getBasicTypeRegistry()
.resolve( StandardBasicTypes.INTEGER )
).createDomainResult( null, state )
);
final NavigablePath idNavigablePath = rootPath.append( entityDescriptor.getIdentifierMapping().getNavigableRole().getNavigableName() );
entityDescriptor.getIdentifierMapping().forEachSelectable(

View File

@ -68,7 +68,9 @@ public class EntityTypeImpl<J>
discriminatorType = (DomainType) discriminatorMetadata.getResolutionType();
}
else {
discriminatorType = StandardBasicTypes.STRING;
discriminatorType = jpaMetamodel.getTypeConfiguration()
.getBasicTypeRegistry()
.resolve( StandardBasicTypes.STRING );
}
this.discriminatorPathSource = new DiscriminatorSqmPathSource<>(

View File

@ -1,67 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.persister.collection;
import org.hibernate.QueryException;
import org.hibernate.persister.entity.PropertyMapping;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;
/**
* @author Gavin King
*/
public class CollectionPropertyMapping implements PropertyMapping {
private final QueryableCollection memberPersister;
public CollectionPropertyMapping(QueryableCollection memberPersister) {
this.memberPersister = memberPersister;
}
public Type toType(String propertyName) throws QueryException {
if ( propertyName.equals(CollectionPropertyNames.COLLECTION_ELEMENTS) ) {
return memberPersister.getElementType();
}
else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_INDICES) ) {
if ( !memberPersister.hasIndex() ) {
throw new QueryException("unindexed collection before indices()");
}
return memberPersister.getIndexType();
}
else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_SIZE) ) {
return StandardBasicTypes.INTEGER;
}
else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_MAX_INDEX) ) {
return memberPersister.getIndexType();
}
else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_MIN_INDEX) ) {
return memberPersister.getIndexType();
}
else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_MAX_ELEMENT) ) {
return memberPersister.getElementType();
}
else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_MIN_ELEMENT) ) {
return memberPersister.getElementType();
}
else {
//return memberPersister.getPropertyType(propertyName);
throw new QueryException("illegal syntax near collection: " + propertyName);
}
}
/**
* Given a property path, return the corresponding column name(s).
*/
public String[] toColumns(String propertyName) throws QueryException, UnsupportedOperationException {
throw new UnsupportedOperationException( "References to collections must be define a SQL alias" );
}
public Type getType() {
//return memberPersister.getType();
return memberPersister.getCollectionType();
}
}

View File

@ -212,7 +212,9 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
else {
explicitDiscriminatorColumnName = null;
discriminatorAlias = IMPLICIT_DISCRIMINATOR_ALIAS;
discriminatorType = StandardBasicTypes.INTEGER;
discriminatorType = factory.getTypeConfiguration()
.getBasicTypeRegistry()
.resolve( StandardBasicTypes.INTEGER );
try {
discriminatorValue = persistentClass.getSubclassId();
discriminatorSQLString = discriminatorValue.toString();
@ -225,7 +227,9 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
else {
explicitDiscriminatorColumnName = null;
discriminatorAlias = IMPLICIT_DISCRIMINATOR_ALIAS;
discriminatorType = StandardBasicTypes.INTEGER;
discriminatorType = factory.getTypeConfiguration()
.getBasicTypeRegistry()
.resolve( StandardBasicTypes.INTEGER );
discriminatorValue = null;
discriminatorSQLString = null;
}

View File

@ -53,6 +53,7 @@ import org.hibernate.sql.ast.tree.from.TableReference;
import org.hibernate.sql.ast.tree.from.UnionTableGroup;
import org.hibernate.sql.ast.tree.from.UnionTableReference;
import org.hibernate.sql.ast.tree.predicate.Predicate;
import org.hibernate.type.BasicType;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;
@ -74,6 +75,7 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
private final String[] subclassTableExpressions;
private final Object discriminatorValue;
private final String discriminatorSQLValue;
private final BasicType<?> discriminatorType;
private final Map<Object,String> subclassByDiscriminatorValue = new HashMap<>();
private final String[] constraintOrderedTableNames;
@ -144,6 +146,9 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
discriminatorValue = persistentClass.getSubclassId();
discriminatorSQLValue = String.valueOf( persistentClass.getSubclassId() );
discriminatorType = factory.getTypeConfiguration()
.getBasicTypeRegistry()
.resolve( StandardBasicTypes.INTEGER );
// PROPERTIES
@ -286,7 +291,7 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
@Override
public Type getDiscriminatorType() {
return StandardBasicTypes.INTEGER;
return discriminatorType;
}
@Override

View File

@ -65,6 +65,7 @@ import org.hibernate.result.UpdateCountOutput;
import org.hibernate.result.spi.ResultContext;
import org.hibernate.sql.exec.spi.JdbcCall;
import org.hibernate.sql.results.NoMoreOutputsException;
import org.hibernate.type.BasicTypeReference;
import org.jboss.logging.Logger;
@ -898,7 +899,8 @@ public class ProcedureCallImpl<R>
QueryParameter<P> parameter,
P value,
AllowableParameterType type) {
return (ProcedureCallImplementor<R>) super.setParameter( parameter, value, type );
super.setParameter( parameter, value, type );
return this;
}
// @Override
@ -908,7 +910,8 @@ public class ProcedureCallImpl<R>
@Override
public ProcedureCallImplementor<R> setParameter(String name, Object value, AllowableParameterType type) {
return (ProcedureCallImplementor<R>) super.setParameter( name, value, type );
super.setParameter( name, value, type );
return this;
}
// @Override
@ -918,10 +921,27 @@ public class ProcedureCallImpl<R>
@Override
public ProcedureCallImplementor<R> setParameter(int position, Object value, AllowableParameterType type) {
//noinspection unchecked
return (ProcedureCallImplementor<R>) super.setParameter( position, value, type );
super.setParameter( position, value, type );
return this;
}
@Override
public ProcedureCallImplementor<R> setParameter(String name, Object value, BasicTypeReference<?> type) {
super.setParameter( name, value, type );
return this;
}
@Override
public ProcedureCallImplementor<R> setParameter(int position, Object value, BasicTypeReference<?> type) {
super.setParameter( position, value, type );
return this;
}
@Override
public <P> ProcedureCallImplementor<R> setParameter(QueryParameter<P> parameter, P val, BasicTypeReference<?> type) {
super.setParameter( parameter, val, type );
return this;
}
// @Override
// public ProcedureCallImplementor<R> setParameter(int position, Object value, Type type) {
// return (ProcedureCallImplementor<R>) super.setParameter( position, value, type );

View File

@ -31,6 +31,7 @@ import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.metamodel.model.domain.AllowableParameterType;
import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.transform.ResultTransformer;
import org.hibernate.type.BasicTypeReference;
/**
* Represents a native (SQL) query.
@ -79,6 +80,20 @@ public interface NativeQuery<T> extends Query<T>, SynchronizeableQuery {
*/
NativeQuery<T> addScalar(String columnAlias);
/**
* Declare a scalar query result.
* <p/>
* Functions like {@code <return-scalar/>} in {@code hbm.xml} or
* {@link jakarta.persistence.ColumnResult} in annotations
*
* @param columnAlias The column alias in the result-set to be processed
* as a scalar result
* @param type The Hibernate type as which to treat the value.
*
* @return {@code this}, for method chaining
*/
NativeQuery<T> addScalar(String columnAlias, BasicTypeReference<?> type);
/**
* Declare a scalar query result.
* <p/>
@ -677,6 +692,15 @@ public interface NativeQuery<T> extends Query<T>, SynchronizeableQuery {
@Override
<P> NativeQuery<T> setParameter(QueryParameter<P> parameter, P val, AllowableParameterType type);
@Override
NativeQuery<T> setParameter(String name, Object val, BasicTypeReference<?> type);
@Override
NativeQuery<T> setParameter(int position, Object val, BasicTypeReference<?> type);
@Override
<P> NativeQuery<T> setParameter(QueryParameter<P> parameter, P val, BasicTypeReference<?> type);
@Override
NativeQuery<T> setParameterList(int position, Collection values);

View File

@ -38,6 +38,7 @@ import org.hibernate.graph.RootGraph;
import org.hibernate.metamodel.model.domain.AllowableParameterType;
import org.hibernate.query.spi.QueryOptions;
import org.hibernate.transform.ResultTransformer;
import org.hibernate.type.BasicTypeReference;
/**
* Represents an HQL/JPQL query or a compiled Criteria query. Also acts as the Hibernate
@ -301,6 +302,29 @@ public interface Query<R> extends TypedQuery<R>, CommonQueryContract {
*/
Query<R> setParameter(int position, Object val, AllowableParameterType type);
/**
* Bind a named query parameter using the supplied Type
*
* @param name the name of the parameter
* @param val the possibly-null parameter value
* @param type the Hibernate allowable parameter type
*
* @return {@code this}, for method chaining
*/
Query<R> setParameter(String name, Object val, BasicTypeReference<?> type);
/**
* Bind a value to a JDBC-style query parameter.
*
* @param position the position of the parameter in the query
* string, numbered from <tt>0</tt>.
* @param val the possibly-null parameter value
* @param type the Hibernate allowable parameter type
*
* @return {@code this}, for method chaining
*/
Query<R> setParameter(int position, Object val, BasicTypeReference<?> type);
/**
* Bind a named query parameter as some form of date/time using
* the indicated temporal-type.
@ -349,6 +373,17 @@ public interface Query<R> extends TypedQuery<R>, CommonQueryContract {
*/
<P> Query<R> setParameter(QueryParameter<P> parameter, P val, AllowableParameterType type);
/**
* Bind a query parameter using the supplied Type
*
* @param parameter The query parameter memento
* @param val the possibly-null parameter value
* @param type the Hibernate allowable parameter type
*
* @return {@code this}, for method chaining
*/
<P> Query<R> setParameter(QueryParameter<P> parameter, P val, BasicTypeReference<?> type);
Query<R> setParameter(Parameter<Instant> param, Instant value, TemporalType temporalType);
Query<R> setParameter(

View File

@ -185,6 +185,7 @@ import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
import org.hibernate.type.BasicType;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaTypeDescriptor;
import org.jboss.logging.Logger;
@ -2969,7 +2970,9 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
private SqmLiteral<byte[]> binaryLiteral(String text) {
return new SqmLiteral<>(
StandardBasicTypes.BINARY.fromStringValue( CharSequenceHelper.subSequence( text, 2, text.length() - 1 ) ),
PrimitiveByteArrayJavaTypeDescriptor.INSTANCE.fromString(
CharSequenceHelper.subSequence( text, 2, text.length() - 1 )
),
resolveExpressableTypeBasic( byte[].class ),
creationContext.getNodeBuilder()
);
@ -3688,7 +3691,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
if ( collectionReferenceCtx == null ) {
final SqmLiteral<Integer> literal = new SqmLiteral<>(
1,
StandardBasicTypes.INTEGER,
creationContext.getNodeBuilder().getIntegerType(),
creationContext.getNodeBuilder()
);
subQuery.applyInferableType( literal.getNodeType() );

View File

@ -30,7 +30,6 @@ public class QueryHelper {
//noinspection unchecked
SqmExpressable<? extends T> highest = highestPrecedenceType2( (SqmExpressable) types[0], types[1] );
for ( int i = 2; i < types.length; i++ ) {
//noinspection unchecked
highest = highestPrecedenceType2( highest, types[i] );
}

View File

@ -55,6 +55,7 @@ import org.hibernate.property.access.spi.BuiltInPropertyAccessStrategies;
import org.hibernate.property.access.spi.Getter;
import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.query.IllegalQueryOperationException;
import org.hibernate.query.Query;
import org.hibernate.query.QueryLogging;
import org.hibernate.query.QueryParameter;
import org.hibernate.query.ResultListTransformer;
@ -63,6 +64,7 @@ import org.hibernate.query.TypedParameterValue;
import org.hibernate.query.internal.ScrollableResultsIterator;
import org.hibernate.query.named.NamedQueryMemento;
import org.hibernate.type.BasicType;
import org.hibernate.type.BasicTypeReference;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import static org.hibernate.LockMode.UPGRADE;
@ -1031,6 +1033,22 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
return this;
}
@Override
public QueryImplementor<R> setParameter(String name, Object value, BasicTypeReference<?> type) {
return setParameter( name, value, session.getTypeConfiguration().getBasicTypeRegistry().resolve( type ) );
}
@Override
@SuppressWarnings( {"unchecked", "rawtypes"} )
public QueryImplementor setParameter(int position, Object value, BasicTypeReference<?> type) {
return setParameter( position, value, session.getTypeConfiguration().getBasicTypeRegistry().resolve( type ) );
}
@Override
public <P> Query<R> setParameter(QueryParameter<P> parameter, P val, BasicTypeReference<?> type) {
return setParameter( parameter, val, session.getTypeConfiguration().getBasicTypeRegistry().resolve( type ) );
}
@Override
public <P> QueryImplementor<R> setParameter(QueryParameter<P> parameter, P value, TemporalType temporalType) {
locateBinding( parameter ).setBindValue( value, temporalType );

View File

@ -13,6 +13,7 @@ import java.util.Map;
import java.util.function.Supplier;
import org.hibernate.Incubating;
import org.hibernate.boot.model.FunctionContributions;
import org.hibernate.boot.model.FunctionContributor;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.spi.BootstrapContext;
@ -138,8 +139,24 @@ public class QueryEngine {
userDefinedRegistry.overlay( sqmFunctionRegistry );
}
final FunctionContributions functionContributions = new FunctionContributions() {
@Override
public TypeConfiguration getTypeConfiguration() {
return typeConfiguration;
}
@Override
public SqmFunctionRegistry getFunctionRegistry() {
return sqmFunctionRegistry;
}
@Override
public ServiceRegistry getServiceRegistry() {
return serviceRegistry;
}
};
for ( FunctionContributor contributor : sortedFunctionContributors( serviceRegistry ) ) {
contributor.contributeFunctions( sqmFunctionRegistry, serviceRegistry );
contributor.contributeFunctions( functionContributions );
}
final boolean showSQLFunctions = ConfigurationHelper.getBoolean(

View File

@ -54,6 +54,7 @@ import org.hibernate.metamodel.model.domain.AllowableParameterType;
import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.persister.entity.Loadable;
import org.hibernate.query.Limit;
import org.hibernate.query.NativeQuery;
import org.hibernate.query.ParameterMetadata;
import org.hibernate.query.Query;
import org.hibernate.query.QueryParameter;
@ -76,6 +77,7 @@ import org.hibernate.query.spi.MutableQueryOptions;
import org.hibernate.query.spi.NonSelectQueryPlan;
import org.hibernate.query.spi.ParameterMetadataImplementor;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.spi.QueryImplementor;
import org.hibernate.query.spi.QueryInterpretationCache;
import org.hibernate.query.spi.QueryParameterBindings;
import org.hibernate.query.spi.QueryParameterImplementor;
@ -95,6 +97,7 @@ import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducer;
import org.hibernate.sql.results.spi.RowTransformer;
import org.hibernate.transform.ResultTransformer;
import org.hibernate.type.BasicType;
import org.hibernate.type.BasicTypeReference;
import static org.hibernate.jpa.QueryHints.HINT_NATIVE_LOCKMODE;
@ -713,6 +716,16 @@ public class NativeQueryImpl<R>
return this;
}
@Override
public NativeQuery<R> addScalar(String columnAlias, BasicTypeReference<?> type) {
return registerBuilder(
Builders.scalar(
columnAlias,
getSessionFactory().getTypeConfiguration().getBasicTypeRegistry().resolve( type )
)
);
}
@Override
public NativeQueryImplementor<R> addScalar(String columnAlias, BasicDomainType type) {
return registerBuilder( Builders.scalar( columnAlias, (BasicType<?>) type ) );
@ -1337,44 +1350,62 @@ public class NativeQueryImpl<R>
@Override
public <P> NativeQueryImplementor<R> setParameter(QueryParameter<P> parameter, P value, AllowableParameterType type) {
//noinspection unchecked
return (NativeQueryImplementor) super.setParameter( parameter, value, type );
super.setParameter( parameter, value, type );
return this;
}
@Override
public NativeQueryImplementor<R> setParameter(String name, Object value, AllowableParameterType type) {
//noinspection unchecked
return (NativeQueryImplementor) super.setParameter( name, value, type );
super.setParameter( name, value, type );
return this;
}
@Override
public NativeQueryImplementor<R> setParameter(int position, Object value, AllowableParameterType type) {
//noinspection unchecked
return (NativeQueryImplementor) super.setParameter( position, value, type );
super.setParameter( position, value, type );
return this;
}
@Override
public NativeQueryImplementor<R> setParameter(String name, Object value, BasicTypeReference<?> type) {
super.setParameter( name, value, type );
return this;
}
@Override
public NativeQueryImplementor<R> setParameter(int position, Object value, BasicTypeReference<?> type) {
super.setParameter( position, value, type );
return this;
}
@Override
public <P> NativeQueryImplementor<R> setParameter(QueryParameter<P> parameter, P val, BasicTypeReference<?> type) {
super.setParameter( parameter, val, type );
return this;
}
@Override
public NativeQueryImplementor<R> setParameterList(int position, Collection values) {
//noinspection unchecked
return (NativeQueryImplementor) super.setParameterList( position, values );
super.setParameterList( position, values );
return this;
}
@Override
public NativeQueryImplementor<R> setParameterList(int position, Object[] values) {
//noinspection unchecked
return (NativeQueryImplementor) super.setParameterList( position, values );
super.setParameterList( position, values );
return this;
}
@Override
public NativeQueryImplementor<R> setParameterList(String name, Collection values, Class javaType) {
//noinspection unchecked
return (NativeQueryImplementor) super.setParameterList( name, values, javaType );
super.setParameterList( name, values, javaType );
return this;
}
@Override
public NativeQueryImplementor<R> setParameterList(int position, Collection values, Class javaType) {
//noinspection unchecked
return (NativeQueryImplementor) super.setParameterList( position, values, javaType );
super.setParameterList( position, values, javaType );
return this;
}

View File

@ -36,6 +36,7 @@ import org.hibernate.query.TupleTransformer;
import org.hibernate.query.named.NameableQuery;
import org.hibernate.query.results.dynamic.DynamicResultBuilderEntityStandard;
import org.hibernate.query.spi.QueryImplementor;
import org.hibernate.type.BasicTypeReference;
/**
* @author Steve Ebersole
@ -225,6 +226,15 @@ public interface NativeQueryImplementor<R> extends QueryImplementor<R>, NativeQu
@Override
NativeQueryImplementor<R> setParameter(int position, Object val, AllowableParameterType type);
@Override
NativeQueryImplementor<R> setParameter(String name, Object val, BasicTypeReference<?> type);
@Override
NativeQueryImplementor<R> setParameter(int position, Object val, BasicTypeReference<?> type);
@Override
<P> NativeQueryImplementor<R> setParameter(QueryParameter<P> parameter, P val, BasicTypeReference<?> type);
@Override
<P> NativeQueryImplementor<R> setParameter(
QueryParameter<P> parameter,

View File

@ -62,6 +62,7 @@ import org.hibernate.query.sqm.tree.select.SqmSubQuery;
import org.hibernate.query.sqm.tree.update.SqmUpdateStatement;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.query.sqm.tree.expression.SqmFunction;
import org.hibernate.type.BasicType;
import org.hibernate.type.spi.TypeConfiguration;
/**
@ -639,4 +640,8 @@ public interface NodeBuilder extends HibernateCriteriaBuilder {
@Override
SqmSortSpecification desc(Expression<?> x);
BasicType<Boolean> getBooleanType();
BasicType<Integer> getIntegerType();
}

View File

@ -165,6 +165,8 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
private final transient Supplier<JpaMetamodel> domainModelAccess;
private final transient ServiceRegistry serviceRegistry;
private final transient ValueHandlingMode criteriaValueHandlingMode;
private transient BasicType<Boolean> booleanType;
private transient BasicType<Integer> integerType;
public SqmCriteriaNodeBuilder(
String uuid,
@ -186,6 +188,25 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
return domainModelAccess.get();
}
@Override
public BasicType<Boolean> getBooleanType() {
final BasicType<Boolean> booleanType = this.booleanType;
if ( booleanType == null ) {
return this.booleanType = getTypeConfiguration().getBasicTypeRegistry()
.resolve( StandardBasicTypes.BOOLEAN );
}
return booleanType;
}
@Override
public BasicType<Integer> getIntegerType() {
final BasicType<Integer> integerType = this.integerType;
if ( integerType == null ) {
return this.integerType = getTypeConfiguration().getBasicTypeForJavaType( Integer.class );
}
return integerType;
}
@Override
public ServiceRegistry getServiceRegistry() {
return serviceRegistry;
@ -987,14 +1008,9 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
public SqmExpression<String> concat(Expression<String> x, Expression<String> y) {
final SqmExpression<String> xSqmExpression = (SqmExpression<String>) x;
final SqmExpression<String> ySqmExpression = (SqmExpression<String>) y;
//noinspection unchecked
return getFunctionDescriptor( "concat" ).generateSqmExpression(
asList( xSqmExpression, ySqmExpression ),
(AllowableFunctionReturnType<String>) highestPrecedenceType(
xSqmExpression.getNodeType(),
ySqmExpression.getNodeType(),
StandardBasicTypes.STRING
),
null,
getQueryEngine(),
getJpaMetamodel().getTypeConfiguration()
);
@ -1008,11 +1024,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
return getFunctionDescriptor( "concat" ).generateSqmExpression(
asList( xSqmExpression, ySqmExpression ),
(AllowableFunctionReturnType<String>) highestPrecedenceType(
xSqmExpression.getNodeType(),
ySqmExpression.getNodeType(),
StandardBasicTypes.STRING
),
null,
getQueryEngine(),
getJpaMetamodel().getTypeConfiguration()
);
@ -1026,11 +1038,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
return getFunctionDescriptor( "concat" ).generateSqmExpression(
asList( xSqmExpression, ySqmExpression ),
(AllowableFunctionReturnType<String>) highestPrecedenceType(
xSqmExpression.getNodeType(),
ySqmExpression.getNodeType(),
StandardBasicTypes.STRING
),
null,
getQueryEngine(),
getJpaMetamodel().getTypeConfiguration()
);
@ -1044,11 +1052,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
return getFunctionDescriptor( "concat" ).generateSqmExpression(
asList( xSqmExpression, ySqmExpression ),
(AllowableFunctionReturnType<String>) highestPrecedenceType(
xSqmExpression.getNodeType(),
ySqmExpression.getNodeType(),
StandardBasicTypes.STRING
),
null,
getQueryEngine(),
getJpaMetamodel().getTypeConfiguration()
);
@ -1067,15 +1071,9 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
SqmExpression<String> source,
SqmExpression<Integer> from,
SqmExpression<Integer> len) {
//noinspection unchecked
final AllowableFunctionReturnType<String> resultType = (AllowableFunctionReturnType<String>) QueryHelper.highestPrecedenceType2(
source.getNodeType(),
StandardBasicTypes.STRING
);
return getFunctionDescriptor( "substring" ).generateSqmExpression(
len == null ? asList( source, from ) : asList( source, from, len ),
resultType,
null,
getQueryEngine(),
getJpaMetamodel().getTypeConfiguration()
);
@ -1132,10 +1130,9 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
arguments.add( trimCharacter );
arguments.add( source );
//noinspection unchecked
return getFunctionDescriptor( "trim" ).generateSqmExpression(
arguments,
(AllowableFunctionReturnType<String>) QueryHelper.highestPrecedenceType2( source.getNodeType(), StandardBasicTypes.STRING ),
null,
getQueryEngine(),
getJpaMetamodel().getTypeConfiguration()
);
@ -1246,7 +1243,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
return getFunctionDescriptor("locate").generateSqmExpression(
arguments,
StandardBasicTypes.INTEGER,
null,
getQueryEngine(),
getJpaMetamodel().getTypeConfiguration()
);
@ -1281,10 +1278,9 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
@Override
public SqmFunction<Date> currentDate() {
//noinspection unchecked
return getFunctionDescriptor("current_date")
.generateSqmExpression(
(AllowableFunctionReturnType<Date>) (AllowableFunctionReturnType<?>) StandardBasicTypes.DATE,
null,
queryEngine,
getJpaMetamodel().getTypeConfiguration()
);
@ -1292,10 +1288,9 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
@Override
public SqmFunction<Timestamp> currentTimestamp() {
//noinspection unchecked
return getFunctionDescriptor("current_timestamp")
.generateSqmExpression(
(AllowableFunctionReturnType<Timestamp>) (AllowableFunctionReturnType<?>) StandardBasicTypes.TIMESTAMP,
null,
queryEngine,
getJpaMetamodel().getTypeConfiguration()
);
@ -1303,10 +1298,9 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
@Override
public SqmFunction<Time> currentTime() {
//noinspection unchecked
return getFunctionDescriptor("current_time")
.generateSqmExpression(
(AllowableFunctionReturnType<Time>) (AllowableFunctionReturnType<?>) StandardBasicTypes.TIME,
null,
queryEngine,
getJpaMetamodel().getTypeConfiguration()
);
@ -1316,7 +1310,9 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
public SqmFunction<Instant> currentInstant() {
return getFunctionDescriptor("current_timestamp")
.generateSqmExpression(
StandardBasicTypes.INSTANT,
getJpaMetamodel().getTypeConfiguration()
.getBasicTypeRegistry()
.resolve( StandardBasicTypes.INSTANT ),
queryEngine,
getJpaMetamodel().getTypeConfiguration()
);
@ -1471,7 +1467,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
public <C extends Collection<?>> SqmExpression<Integer> size(C collection) {
return new SqmLiteral<>(
collection.size(),
StandardBasicTypes.INTEGER,
getIntegerType(),
this
);
}
@ -1551,7 +1547,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
@Override
public <M extends Map<?, ?>> SqmExpression<Integer> mapSize(M map) {
return new SqmLiteral<>( map.size(), StandardBasicTypes.INTEGER, this );
return new SqmLiteral<>( map.size(), getIntegerType(), this );
}
@ -1616,9 +1612,9 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
@Override
public SqmPredicate conjunction() {
return new SqmComparisonPredicate(
new SqmLiteral<>( 1, StandardBasicTypes.INTEGER, this ),
new SqmLiteral<>( 1, getIntegerType(), this ),
ComparisonOperator.EQUAL,
new SqmLiteral<>( 1, StandardBasicTypes.INTEGER, this ),
new SqmLiteral<>( 1, getIntegerType(), this ),
this
);
}
@ -1626,9 +1622,9 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
@Override
public SqmPredicate disjunction() {
return new SqmComparisonPredicate(
new SqmLiteral<>( 1, StandardBasicTypes.INTEGER, this ),
new SqmLiteral<>( 1, getIntegerType(), this ),
ComparisonOperator.NOT_EQUAL,
new SqmLiteral<>( 1, StandardBasicTypes.INTEGER, this ),
new SqmLiteral<>( 1, getIntegerType(), this ),
this
);
}

View File

@ -17,6 +17,7 @@ import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.engine.transaction.spi.IsolationDelegate;
import org.hibernate.metamodel.mapping.BasicValuedMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.query.ComparisonOperator;
import org.hibernate.query.NavigablePath;
@ -118,7 +119,7 @@ public final class ExecuteWithIdTableHelper {
jdbcPosition + 1,
new QueryLiteral<>(
sessionUidAccess.apply( executionContext.getSession() ),
StandardBasicTypes.STRING
(BasicValuedMapping) idTable.getSessionUidColumn().getJdbcMapping()
)
)
);
@ -238,7 +239,7 @@ public final class ExecuteWithIdTableHelper {
ComparisonOperator.EQUAL,
new QueryLiteral<>(
sessionUidAccess.apply( executionContext.getSession() ),
UUIDCharType.INSTANCE
(BasicValuedMapping) idTable.getSessionUidColumn().getJdbcMapping()
)
)
);

View File

@ -6,18 +6,21 @@
*/
package org.hibernate.query.sqm.mutation.internal.idtable;
import org.hibernate.type.UUIDCharType;
import org.hibernate.metamodel.mapping.JdbcMapping;
/**
* @author Steve Ebersole
*/
public class IdTableSessionUidColumn extends IdTableColumn {
public IdTableSessionUidColumn(IdTable containingTable) {
public IdTableSessionUidColumn(
IdTable containingTable,
JdbcMapping jdbcMapping,
String sqlTypeName) {
super(
containingTable,
IdTableHelper.SESSION_ID_COLUMN_NAME,
UUIDCharType.INSTANCE,
null
jdbcMapping,
sqlTypeName
);
}
}

View File

@ -60,37 +60,37 @@ public abstract class AbstractSqmExpression<T> extends AbstractJpaSelection<T> i
@Override
public SqmExpression<Long> asLong() {
return castAs( StandardBasicTypes.LONG );
return castAs( nodeBuilder().getTypeConfiguration().getBasicTypeForJavaType( Long.class ) );
}
@Override
public SqmExpression<Integer> asInteger() {
return castAs( StandardBasicTypes.INTEGER );
return castAs( nodeBuilder().getTypeConfiguration().getBasicTypeForJavaType( Integer.class ) );
}
@Override
public SqmExpression<Float> asFloat() {
return castAs( StandardBasicTypes.FLOAT );
return castAs( nodeBuilder().getTypeConfiguration().getBasicTypeForJavaType( Float.class ) );
}
@Override
public SqmExpression<Double> asDouble() {
return castAs( StandardBasicTypes.DOUBLE );
return castAs( nodeBuilder().getTypeConfiguration().getBasicTypeForJavaType( Double.class ) );
}
@Override
public SqmExpression<BigDecimal> asBigDecimal() {
return castAs( StandardBasicTypes.BIG_DECIMAL );
return castAs( nodeBuilder().getTypeConfiguration().getBasicTypeForJavaType( BigDecimal.class ) );
}
@Override
public SqmExpression<BigInteger> asBigInteger() {
return castAs( StandardBasicTypes.BIG_INTEGER );
return castAs( nodeBuilder().getTypeConfiguration().getBasicTypeForJavaType( BigInteger.class ) );
}
@Override
public SqmExpression<String> asString() {
return castAs( StandardBasicTypes.STRING );
return castAs( nodeBuilder().getTypeConfiguration().getBasicTypeForJavaType( String.class ) );
}
@Override

View File

@ -47,7 +47,7 @@ public class LiteralHelper {
public static SqmLiteral<Integer> integerLiteral(int value, QueryEngine queryEngine) {
return new SqmLiteral<>(
value,
StandardBasicTypes.INTEGER,
queryEngine.getCriteriaBuilder().getIntegerType(),
queryEngine.getCriteriaBuilder()
);
}

View File

@ -20,10 +20,10 @@ import org.hibernate.type.StandardBasicTypes;
* @author Gunnar Morling
*/
public class SqmCollectionSize extends AbstractSqmExpression<Integer> implements DomainResultProducer<Integer> {
private final SqmPath pluralPath;
private final SqmPath<?> pluralPath;
public SqmCollectionSize(SqmPath<?> pluralPath, NodeBuilder nodeBuilder) {
this( pluralPath, StandardBasicTypes.INTEGER, nodeBuilder );
this( pluralPath, nodeBuilder.getIntegerType(), nodeBuilder );
}
public SqmCollectionSize(SqmPath<?> pluralPath, SqmExpressable<Integer> sizeType, NodeBuilder nodeBuilder) {
@ -31,7 +31,7 @@ public class SqmCollectionSize extends AbstractSqmExpression<Integer> implements
this.pluralPath = pluralPath;
}
public SqmPath getPluralPath() {
public SqmPath<?> getPluralPath() {
return pluralPath;
}

View File

@ -19,7 +19,7 @@ public abstract class AbstractNegatableSqmPredicate extends AbstractSqmPredicate
}
public AbstractNegatableSqmPredicate(boolean negated, NodeBuilder nodeBuilder) {
super( nodeBuilder );
super( nodeBuilder.getBooleanType(), nodeBuilder );
this.negated = negated;
}

View File

@ -11,6 +11,7 @@ import java.util.List;
import jakarta.persistence.criteria.Expression;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmExpressable;
import org.hibernate.query.sqm.tree.expression.AbstractSqmExpression;
import org.hibernate.type.StandardBasicTypes;
@ -18,10 +19,9 @@ import org.hibernate.type.StandardBasicTypes;
* @author Steve Ebersole
*/
public abstract class AbstractSqmPredicate extends AbstractSqmExpression<Boolean> implements SqmPredicate {
@SuppressWarnings("WeakerAccess")
public AbstractSqmPredicate(NodeBuilder criteriaBuilder) {
//noinspection unchecked
super( StandardBasicTypes.BOOLEAN, criteriaBuilder );
public AbstractSqmPredicate(SqmExpressable<Boolean> type, NodeBuilder criteriaBuilder) {
super( type, criteriaBuilder );
}
@Override

View File

@ -24,7 +24,7 @@ public class SqmAndPredicate extends AbstractSqmPredicate implements SqmJunctive
SqmPredicate leftHandPredicate,
SqmPredicate rightHandPredicate,
NodeBuilder nodeBuilder) {
super( nodeBuilder );
super( leftHandPredicate.getExpressable(), nodeBuilder );
this.leftHandPredicate = leftHandPredicate;
this.rightHandPredicate = rightHandPredicate;
}

View File

@ -20,7 +20,7 @@ public class SqmGroupedPredicate extends AbstractSqmPredicate {
private final SqmPredicate subPredicate;
public SqmGroupedPredicate(SqmPredicate subPredicate, NodeBuilder nodeBuilder) {
super( nodeBuilder );
super( subPredicate.getExpressable(), nodeBuilder );
this.subPredicate = subPredicate;
}

View File

@ -20,12 +20,12 @@ public class SqmNullnessPredicate extends AbstractNegatableSqmPredicate {
this( expression, false, nodeBuilder );
}
public SqmNullnessPredicate(SqmExpression expression, boolean negated, NodeBuilder nodeBuilder) {
public SqmNullnessPredicate(SqmExpression<?> expression, boolean negated, NodeBuilder nodeBuilder) {
super( negated, nodeBuilder );
this.expression = expression;
}
public SqmExpression getExpression() {
public SqmExpression<?> getExpression() {
return expression;
}

View File

@ -65,7 +65,7 @@ public abstract class SqmQueryPart<T> implements SqmVisitableNode, JpaQueryPart<
public void setOffsetExpression(SqmExpression<?> offsetExpression) {
if ( offsetExpression != null ) {
offsetExpression.applyInferableType( StandardBasicTypes.INTEGER );
offsetExpression.applyInferableType( nodeBuilder.getIntegerType() );
}
this.offsetExpression = offsetExpression;
}
@ -83,7 +83,7 @@ public abstract class SqmQueryPart<T> implements SqmVisitableNode, JpaQueryPart<
if ( fetchClauseType == null ) {
throw new IllegalArgumentException( "Fetch clause may not be null!" );
}
fetchExpression.applyInferableType( StandardBasicTypes.INTEGER );
fetchExpression.applyInferableType( nodeBuilder.getIntegerType() );
this.fetchExpression = fetchExpression;
this.fetchClauseType = fetchClauseType;
}

View File

@ -326,37 +326,37 @@ public class SqmSubQuery<T> extends AbstractSqmSelectQuery<T> implements SqmSele
@Override
public SqmExpression<Long> asLong() {
return castAs( StandardBasicTypes.LONG );
return castAs( nodeBuilder().getTypeConfiguration().getBasicTypeForJavaType( Long.class ) );
}
@Override
public SqmExpression<Integer> asInteger() {
return castAs( StandardBasicTypes.INTEGER );
return castAs( nodeBuilder().getTypeConfiguration().getBasicTypeForJavaType( Integer.class ) );
}
@Override
public SqmExpression<Float> asFloat() {
return castAs( StandardBasicTypes.FLOAT );
return castAs( nodeBuilder().getTypeConfiguration().getBasicTypeForJavaType( Float.class ) );
}
@Override
public SqmExpression<Double> asDouble() {
return castAs( StandardBasicTypes.DOUBLE );
return castAs( nodeBuilder().getTypeConfiguration().getBasicTypeForJavaType( Double.class ) );
}
@Override
public SqmExpression<BigDecimal> asBigDecimal() {
return castAs( StandardBasicTypes.BIG_DECIMAL );
return castAs( nodeBuilder().getTypeConfiguration().getBasicTypeForJavaType( BigDecimal.class ) );
}
@Override
public SqmExpression<BigInteger> asBigInteger() {
return castAs( StandardBasicTypes.BIG_INTEGER );
return castAs( nodeBuilder().getTypeConfiguration().getBasicTypeForJavaType( BigInteger.class ) );
}
@Override
public SqmExpression<String> asString() {
return castAs( StandardBasicTypes.STRING );
return castAs( nodeBuilder().getTypeConfiguration().getBasicTypeForJavaType( String.class ) );
}
@Override

View File

@ -166,8 +166,6 @@ import static org.hibernate.sql.results.graph.DomainResultGraphPrinter.logDomain
*/
public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implements SqlAstTranslator<T>, SqlAppender {
private static final QueryLiteral<Integer> ONE_LITERAL = new QueryLiteral<>( 1, IntegerType.INSTANCE );
// pre-req state
private final SessionFactoryImplementor sessionFactory;
@ -197,6 +195,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
private int queryGroupAliasCounter;
private transient AbstractSqmSelfRenderingFunctionDescriptor castFunction;
private transient LazySessionWrapperOptions lazySessionWrapperOptions;
private transient BasicType<Integer> integerType;
private SqlAstNodeRenderingMode parameterRenderingMode = SqlAstNodeRenderingMode.DEFAULT;
@ -240,6 +239,15 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
return lazySessionWrapperOptions;
}
public BasicType<Integer> getIntegerType() {
if ( integerType == null ) {
integerType = sessionFactory.getTypeConfiguration()
.getBasicTypeRegistry()
.resolve( StandardBasicTypes.INTEGER );
}
return integerType;
}
/**
* A lazy session implementation that is needed for rendering literals.
* Usually, only the {@link WrapperOptions} interface is needed,
@ -517,10 +525,10 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
protected Object getParameterBindValue(JdbcParameter parameter) {
final JdbcParameterBinding binding;
if ( parameter == getOffsetParameter() ) {
binding = new JdbcParameterBindingImpl( IntegerType.INSTANCE, getLimit().getFirstRow() );
binding = new JdbcParameterBindingImpl( getIntegerType(), getLimit().getFirstRow() );
}
else if ( parameter == getLimitParameter() ) {
binding = new JdbcParameterBindingImpl( IntegerType.INSTANCE, getLimit().getMaxRows() );
binding = new JdbcParameterBindingImpl( getIntegerType(), getLimit().getMaxRows() );
}
else {
binding = jdbcParameterBindings.getBinding( parameter );
@ -1431,7 +1439,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
false,
null,
null,
StandardBasicTypes.INTEGER,
getIntegerType(),
null
)
)
@ -4290,7 +4298,11 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
appendSql( i + 1 );
appendSql( order );
}
renderFetch( ONE_LITERAL, null, FetchClauseType.ROWS_ONLY );
renderFetch(
new QueryLiteral<>( 1, getIntegerType() ),
null,
FetchClauseType.ROWS_ONLY
);
appendSql( CLOSE_PARENTHESIS );
}
finally {

View File

@ -11,6 +11,8 @@ import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.time.ZonedDateTime;
import java.util.Map;
import org.hibernate.Hibernate;
@ -22,9 +24,11 @@ import org.hibernate.engine.spi.Mapping;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.query.CastType;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.BooleanJavaTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.MutabilityPlan;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
@ -103,15 +107,6 @@ public abstract class AbstractStandardBasicType<T>
return javaTypeDescriptor.getMutabilityPlan();
}
protected T getReplacement(T original, T target, SharedSessionContractImplementor session) {
if ( !isMutable() || ( target != null && isEqual( original, target ) ) ) {
return original;
}
else {
return deepCopy( original );
}
}
@Override
public boolean[] toColumnNullness(Object value, Mapping mapping) {
return value == null ? ArrayHelper.FALSE : ArrayHelper.TRUE;
@ -384,7 +379,7 @@ public abstract class AbstractStandardBasicType<T>
return null;
}
return getReplacement( (T) original, (T) target, session );
return javaTypeDescriptor.getReplacement( (T) original, (T) target, session );
}
@Override
@ -397,7 +392,7 @@ public abstract class AbstractStandardBasicType<T>
Map copyCache,
ForeignKeyDirection foreignKeyDirection) {
return ForeignKeyDirection.FROM_PARENT == foreignKeyDirection
? getReplacement( (T) original, (T) target, session )
? javaTypeDescriptor.getReplacement( (T) original, (T) target, session )
: target;
}
@ -453,4 +448,33 @@ public abstract class AbstractStandardBasicType<T>
public boolean canDoSetting() {
return true;
}
@Override
public CastType getCastType() {
final JdbcTypeDescriptor jdbcTypeDescriptor = getJdbcTypeDescriptor();
final int jdbcTypeCode = jdbcTypeDescriptor.getJdbcTypeCode();
switch ( jdbcTypeCode ) {
case Types.BIT:
case Types.SMALLINT:
case Types.TINYINT:
case Types.INTEGER:
if ( getJavaType() == Boolean.class ) {
return CastType.INTEGER_BOOLEAN;
}
break;
case Types.CHAR:
if ( getJavaType() == Boolean.class ) {
return (Boolean) getJavaTypeDescriptor().wrap( 'Y', null )
? CastType.YN_BOOLEAN
: CastType.TF_BOOLEAN;
}
break;
case Types.TIMESTAMP_WITH_TIMEZONE:
if ( getJavaType() == ZonedDateTime.class ) {
return CastType.ZONE_TIMESTAMP;
}
break;
}
return jdbcTypeDescriptor.getCastType();
}
}

View File

@ -1,35 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.type;
import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan;
import org.hibernate.type.descriptor.java.MutabilityPlan;
/**
* Optimize a mutable type, if the user promises not to mutable the
* instances.
*
* @author Gavin King
* @author Steve Ebersole
*/
public class AdaptedImmutableType<T> extends AbstractSingleColumnStandardBasicType<T> {
private final AbstractStandardBasicType<T> baseMutableType;
public AdaptedImmutableType(AbstractStandardBasicType<T> baseMutableType) {
super( baseMutableType.getJdbcTypeDescriptor(), baseMutableType.getJavaTypeDescriptor() );
this.baseMutableType = baseMutableType;
}
@Override
@SuppressWarnings({ "unchecked" })
protected MutabilityPlan<T> getMutabilityPlan() {
return ImmutableMutabilityPlan.INSTANCE;
}
public String getName() {
return "imm_" + baseMutableType.getName();
}
}

View File

@ -0,0 +1,77 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.type;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
/**
* A basic type reference.
*
* @author Christian Beikov
*/
public final class BasicTypeReference<T> {
private final String name;
private final Class<? extends T> javaType;
private final int sqlTypeCode;
private final BasicValueConverter<T, ?> converter;
private final boolean forceImmutable;
public BasicTypeReference(String name, Class<? extends T> javaType, int sqlTypeCode) {
this(name, javaType, sqlTypeCode, null);
}
public BasicTypeReference(
String name,
Class<? extends T> javaType,
int sqlTypeCode,
BasicValueConverter<T, ?> converter) {
this( name, javaType, sqlTypeCode, converter, false );
}
private BasicTypeReference(
String name,
Class<? extends T> javaType,
int sqlTypeCode,
BasicValueConverter<T, ?> converter,
boolean forceImmutable) {
this.name = name;
this.javaType = javaType;
this.sqlTypeCode = sqlTypeCode;
this.converter = converter;
this.forceImmutable = forceImmutable;
}
public String getName() {
return name;
}
public Class<? extends T> getJavaType() {
return javaType;
}
public int getSqlTypeCode() {
return sqlTypeCode;
}
public BasicValueConverter<T, ?> getConverter() {
return converter;
}
public boolean isForceImmutable() {
return forceImmutable;
}
public BasicTypeReference<T> asImmutable() {
return forceImmutable ? this : new BasicTypeReference<>(
"imm_" + name,
javaType,
sqlTypeCode,
converter,
true
);
}
}

View File

@ -16,10 +16,14 @@ import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
import org.hibernate.type.internal.NamedStandardBasicTypeImpl;
import org.hibernate.type.internal.StandardBasicTypeImpl;
import org.hibernate.type.internal.ConvertedBasicTypeImpl;
import org.hibernate.type.internal.ImmutableConvertedBasicTypeImpl;
import org.hibernate.type.internal.ImmutableNamedBasicTypeImpl;
import org.hibernate.type.internal.NamedBasicTypeImpl;
import org.hibernate.type.internal.BasicTypeImpl;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.usertype.UserType;
@ -37,6 +41,7 @@ public class BasicTypeRegistry implements Serializable {
private boolean primed;
private final Map<String, BasicType<?>> typesByName = new ConcurrentHashMap<>();
private final Map<String, BasicTypeReference<?>> typeReferencesByName = new ConcurrentHashMap<>();
public BasicTypeRegistry(TypeConfiguration typeConfiguration){
this.typeConfiguration = typeConfiguration;
@ -46,8 +51,72 @@ public class BasicTypeRegistry implements Serializable {
// Access
public <J> BasicType<J> getRegisteredType(String key) {
BasicType<?> basicType = typesByName.get( key );
if ( basicType == null ) {
basicType = resolveTypeReference( key );
}
//noinspection unchecked
return (BasicType<J>) typesByName.get( key );
return (BasicType<J>) basicType;
}
private BasicType<?> resolveTypeReference(String name) {
final BasicTypeReference<?> typeReference = typeReferencesByName.get( name );
if ( typeReference == null ) {
return null;
}
if ( !name.equals( typeReference.getName() ) ) {
final BasicType<?> basicType = typesByName.get( typeReference.getName() );
if ( basicType != null ) {
return basicType;
}
}
final JavaTypeDescriptor<Object> javaTypeDescriptor = typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor(
typeReference.getJavaType()
);
final JdbcTypeDescriptor jdbcTypeDescriptor = typeConfiguration.getJdbcTypeDescriptorRegistry().getDescriptor(
typeReference.getSqlTypeCode()
);
final BasicType<?> type;
if ( typeReference.getConverter() == null ) {
if ( typeReference.isForceImmutable() ) {
type = new ImmutableNamedBasicTypeImpl<>(
javaTypeDescriptor,
jdbcTypeDescriptor,
typeReference.getName()
);
}
else {
type = new NamedBasicTypeImpl<>(
javaTypeDescriptor,
jdbcTypeDescriptor,
typeReference.getName()
);
}
}
else {
if ( typeReference.isForceImmutable() ) {
//noinspection unchecked
type = new ImmutableConvertedBasicTypeImpl<>(
javaTypeDescriptor,
jdbcTypeDescriptor,
typeReference.getName(),
(BasicValueConverter<Object, ?>) typeReference.getConverter()
);
}
else {
//noinspection unchecked
type = new ConvertedBasicTypeImpl<>(
javaTypeDescriptor,
jdbcTypeDescriptor,
typeReference.getName(),
(BasicValueConverter<Object, ?>) typeReference.getConverter()
);
}
}
primeRegistryEntry( type );
typesByName.put( typeReference.getName(), type );
typesByName.put( name, type );
return type;
}
public <J> BasicType<J> getRegisteredType(java.lang.reflect.Type javaType) {
@ -63,6 +132,10 @@ public class BasicTypeRegistry implements Serializable {
return getRegisteredType( javaType.getName() );
}
public <J> BasicType<J> resolve(BasicTypeReference<J> basicTypeReference) {
return getRegisteredType( basicTypeReference.getName() );
}
public <J> BasicType<J> resolve(Class<J> javaType, int sqlTypeCode) {
return resolve( (java.lang.reflect.Type) javaType, sqlTypeCode );
}
@ -83,20 +156,18 @@ public class BasicTypeRegistry implements Serializable {
* SqlTypeDescriptor combo or create (and register) one.
*/
public <J> BasicType<J> resolve(JavaTypeDescriptor<J> jtdToUse, JdbcTypeDescriptor stdToUse) {
//noinspection unchecked
return resolve(
jtdToUse,
stdToUse,
() -> new StandardBasicTypeImpl<>( jtdToUse, stdToUse )
() -> new BasicTypeImpl<>( jtdToUse, stdToUse )
);
}
public <J> BasicType<J> resolve(JavaTypeDescriptor<J> jtdToUse, JdbcTypeDescriptor stdToUse, String baseTypeName) {
//noinspection unchecked
return resolve(
jtdToUse,
stdToUse,
() -> new NamedStandardBasicTypeImpl<>( jtdToUse, stdToUse, baseTypeName )
() -> new NamedBasicTypeImpl<>( jtdToUse, stdToUse, baseTypeName )
);
}
@ -110,8 +181,25 @@ public class BasicTypeRegistry implements Serializable {
sqlTypeDescriptor -> new ConcurrentHashMap<>()
);
final BasicType<?> foundBasicType = typeByJtdForStd.get( jtdToUse );
if ( foundBasicType != null ) {
//noinspection unchecked
return (BasicType<J>) typeByJtdForStd.computeIfAbsent( jtdToUse, javaDescriptor -> creator.get() );
return (BasicType<J>) foundBasicType;
}
// Before simply creating the type, we try to find if there is a registered type for this java type,
// and if so, if the jdbc type descriptor matches. Unless it does, we at least reuse the name
final BasicType<J> basicType = getRegisteredType( jtdToUse.getJavaType() );
if ( basicType != null ) {
if ( basicType.getJdbcTypeDescriptor() == stdToUse ) {
return basicType;
}
else {
return new NamedBasicTypeImpl<>( jtdToUse, stdToUse, basicType.getName() );
}
}
final BasicType<J> createdBasicType = creator.get();
typeByJtdForStd.put( jtdToUse, createdBasicType );
return createdBasicType;
}
@ -212,6 +300,29 @@ public class BasicTypeRegistry implements Serializable {
}
}
public void addPrimeEntry(BasicTypeReference<?> type, String legacyTypeClassName, String[] registrationKeys) {
if ( primed ) {
throw new IllegalStateException( "BasicTypeRegistry already primed" );
}
if ( type == null ) {
throw new HibernateException( "Type to register cannot be null" );
}
// Legacy name registration
if ( StringHelper.isNotEmpty( legacyTypeClassName ) ) {
typeReferencesByName.put( legacyTypeClassName, type );
}
// explicit registration keys
if ( registrationKeys == null || registrationKeys.length == 0 ) {
LOG.typeDefinedNoRegistrationKeys( type );
}
else {
applyRegistrationKeys( type, registrationKeys );
}
}
private void primeRegistryEntry(BasicType<?> type) {
final Map<JavaTypeDescriptor<?>, BasicType<?>> mappingsForStdToUse = registryValues.computeIfAbsent(
type.getJdbcTypeDescriptor(),
@ -257,4 +368,29 @@ public class BasicTypeRegistry implements Serializable {
}
}
}
private void applyRegistrationKeys(BasicTypeReference<?> type, String[] keys) {
for ( String key : keys ) {
// be safe...
if ( key == null ) {
continue;
}
//Use String#intern here as there's high chances of duplicates combined with long term usage:
//just running our testsuite would generate 210,000 instances for the String "java.lang.Class" alone.
//Incidentally this might help with map lookup efficiency too.
key = key.intern();
LOG.debugf( "Adding type registration %s -> %s", key, type );
final BasicTypeReference old = typeReferencesByName.put( key, type );
if ( old != null && old != type ) {
LOG.debugf(
"Type registration key [%s] overrode previous entry : `%s`",
key,
old
);
}
}
}
}

View File

@ -8,7 +8,6 @@ package org.hibernate.type;
import java.sql.Blob;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.java.BlobJavaTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.BlobJdbcTypeDescriptor;
@ -35,9 +34,4 @@ public class BlobType extends AbstractSingleColumnStandardBasicType<Blob> {
return true;
}
@Override
protected Blob getReplacement(Blob original, Blob target, SharedSessionContractImplementor session) {
return session.getJdbcServices().getJdbcEnvironment().getDialect().getLobMergeStrategy().mergeBlob( original, target, session );
}
}

View File

@ -9,7 +9,6 @@ package org.hibernate.type;
import java.sql.Clob;
import java.sql.Types;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.java.ClobJavaTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.ClobJdbcTypeDescriptor;
@ -35,9 +34,4 @@ public class ClobType extends AbstractSingleColumnStandardBasicType<Clob> implem
protected boolean registerUnderJavaType() {
return true;
}
@Override
protected Clob getReplacement(Clob original, Clob target, SharedSessionContractImplementor session) {
return session.getJdbcServices().getJdbcEnvironment().getDialect().getLobMergeStrategy().mergeClob( original, target, session );
}
}

View File

@ -25,8 +25,6 @@ public class InstantType
*/
public static final InstantType INSTANCE = new InstantType();
public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss.S 'Z'", Locale.ENGLISH );
public InstantType() {
super( TimestampJdbcTypeDescriptor.INSTANCE, InstantJavaTypeDescriptor.INSTANCE );
}

View File

@ -8,7 +8,6 @@ package org.hibernate.type;
import java.sql.NClob;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.java.NClobJavaTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.NClobJdbcTypeDescriptor;
@ -35,8 +34,4 @@ public class NClobType extends AbstractSingleColumnStandardBasicType<NClob> {
return true;
}
@Override
protected NClob getReplacement(NClob original, NClob target, SharedSessionContractImplementor session) {
return session.getJdbcServices().getJdbcEnvironment().getDialect().getLobMergeStrategy().mergeNClob( original, target, session );
}
}

View File

@ -6,6 +6,11 @@
*/
package org.hibernate.type;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.type.descriptor.java.BooleanJavaTypeDescriptor;
import org.hibernate.type.descriptor.java.IntegerJavaTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;
@ -15,14 +20,56 @@ import jakarta.persistence.Converter;
* @author Steve Ebersole
*/
@Converter
public class NumericBooleanConverter implements AttributeConverter<Boolean,Integer> {
public class NumericBooleanConverter implements AttributeConverter<Boolean, Integer>,
BasicValueConverter<Boolean, Integer> {
/**
* Singleton access
*/
public static final NumericBooleanConverter INSTANCE = new NumericBooleanConverter();
@Override
public Integer convertToDatabaseColumn(Boolean attribute) {
return NumericBooleanType.NumericConverter.toRelational( attribute );
return toRelationalValue( attribute );
}
@Override
public Boolean convertToEntityAttribute(Integer dbData) {
return NumericBooleanType.NumericConverter.toDomain( dbData );
return toDomainValue( dbData );
}
@Override
public Boolean toDomainValue(Integer relationalForm) {
if ( relationalForm == null ) {
return null;
}
if ( 1 == relationalForm ) {
return true;
}
if ( 0 == relationalForm ) {
return false;
}
return null;
}
@Override
public Integer toRelationalValue(Boolean domainForm) {
if ( domainForm == null ) {
return null;
}
return domainForm ? 1 : 0;
}
@Override
public JavaTypeDescriptor<Boolean> getDomainJavaDescriptor() {
return BooleanJavaTypeDescriptor.INSTANCE;
}
@Override
public JavaTypeDescriptor<Integer> getRelationalJavaDescriptor() {
return IntegerJavaTypeDescriptor.INSTANCE;
}
}

View File

@ -7,10 +7,7 @@
package org.hibernate.type;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.query.CastType;
import org.hibernate.type.descriptor.java.BooleanJavaTypeDescriptor;
import org.hibernate.type.descriptor.java.IntegerJavaTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.IntegerJdbcTypeDescriptor;
/**
@ -23,7 +20,6 @@ public class NumericBooleanType
implements ConvertedBasicType<Boolean> {
public static final NumericBooleanType INSTANCE = new NumericBooleanType();
public static final NumericConverter CONVERTER = new NumericConverter();
public NumericBooleanType() {
super( IntegerJdbcTypeDescriptor.INSTANCE, BooleanJavaTypeDescriptor.INSTANCE );
@ -34,64 +30,9 @@ public class NumericBooleanType
return "numeric_boolean";
}
@Override
public CastType getCastType() {
return CastType.INTEGER_BOOLEAN;
}
@Override
public BasicValueConverter<Boolean, ?> getValueConverter() {
return CONVERTER;
return NumericBooleanConverter.INSTANCE;
}
public static class NumericConverter implements BasicValueConverter<Boolean, Integer> {
/**
* Singleton access
*/
public static final NumericConverter INSTANCE = new NumericConverter();
@Override
public Boolean toDomainValue(Integer relationalForm) {
return toDomain( relationalForm );
}
public static Boolean toDomain(Integer relationalForm) {
if ( relationalForm == null ) {
return null;
}
if ( 1 == relationalForm ) {
return true;
}
if ( 0 == relationalForm ) {
return false;
}
return null;
}
@Override
public Integer toRelationalValue(Boolean domainForm) {
return toRelational( domainForm );
}
public static Integer toRelational(Boolean domainForm) {
if ( domainForm == null ) {
return null;
}
return domainForm ? 1 : 0;
}
@Override
public JavaTypeDescriptor<Boolean> getDomainJavaDescriptor() {
return BooleanJavaTypeDescriptor.INSTANCE;
}
@Override
public JavaTypeDescriptor<Integer> getRelationalJavaDescriptor() {
return IntegerJavaTypeDescriptor.INSTANCE;
}
}
}

View File

@ -36,9 +36,4 @@ public class OffsetDateTimeType
protected boolean registerUnderJavaType() {
return true;
}
@Override
public CastType getCastType() {
return CastType.OFFSET_TIMESTAMP;
}
}

Some files were not shown because too many files have changed in this diff Show More