All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hibernate.community.dialect.TimesTenDialect Maven / Gradle / Ivy

There is a newer version: 7.0.0.Beta3
Show newest version
/*
 * 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 .
 */
package org.hibernate.community.dialect;

import java.sql.Types;

import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.boot.model.FunctionContributions;
import org.hibernate.community.dialect.pagination.TimesTenLimitHandler;
import org.hibernate.community.dialect.sequence.SequenceInformationExtractorTimesTenDatabaseImpl;
import org.hibernate.community.dialect.sequence.TimesTenSequenceSupport;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.RowLockStrategy;
import org.hibernate.dialect.function.CommonFunctionFactory;
import org.hibernate.dialect.lock.LockingStrategy;
import org.hibernate.dialect.lock.OptimisticForceIncrementLockingStrategy;
import org.hibernate.dialect.lock.OptimisticLockingStrategy;
import org.hibernate.dialect.lock.PessimisticForceIncrementLockingStrategy;
import org.hibernate.dialect.lock.PessimisticReadUpdateLockingStrategy;
import org.hibernate.dialect.lock.PessimisticWriteUpdateLockingStrategy;
import org.hibernate.dialect.lock.SelectLockingStrategy;
import org.hibernate.dialect.lock.UpdateLockingStrategy;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.sequence.SequenceSupport;
import org.hibernate.dialect.temptable.TemporaryTable;
import org.hibernate.dialect.temptable.TemporaryTableKind;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.persister.entity.Lockable;
import org.hibernate.query.sqm.IntervalType;
import org.hibernate.query.sqm.TemporalUnit;
import org.hibernate.query.sqm.mutation.internal.temptable.GlobalTemporaryTableInsertStrategy;
import org.hibernate.query.sqm.mutation.internal.temptable.GlobalTemporaryTableMutationStrategy;
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy;
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.spi.TypeConfiguration;

import jakarta.persistence.TemporalType;

import static org.hibernate.dialect.SimpleDatabaseVersion.ZERO_VERSION;
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.INTEGER;
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.STRING;

/**
 * A SQL dialect for TimesTen 5.1.
 * 

* Known limitations: * joined-subclass support because of no CASE support in TimesTen * No support for subqueries that includes aggregation * - size() in HQL not supported * - user queries that does subqueries with aggregation * No CLOB/BLOB support * No cascade delete support. * No Calendar support * No support for updating primary keys. * * @author Sherry Listgarten, Max Andersen, Chris Jenkins */ public class TimesTenDialect extends Dialect { public TimesTenDialect() { super( ZERO_VERSION ); } public TimesTenDialect(DialectResolutionInfo info) { super( info ); } @Override protected String columnType(int sqlTypeCode) { switch ( sqlTypeCode ) { //Note: these are the correct type mappings // for the default Oracle type mode // TypeMode=0 case SqlTypes.BOOLEAN: case SqlTypes.TINYINT: return "tt_tinyint"; case SqlTypes.SMALLINT: return "tt_smallint"; case SqlTypes.INTEGER: return "tt_integer"; case SqlTypes.BIGINT: return "tt_bigint"; //note that 'binary_float'/'binary_double' might //be better mappings for Java Float/Double //'numeric'/'decimal' are synonyms for 'number' case SqlTypes.NUMERIC: case SqlTypes.DECIMAL: return "number($p,$s)"; case SqlTypes.DATE: return "tt_date"; case SqlTypes.TIME: return "tt_time"; //`timestamp` has more precision than `tt_timestamp` case SqlTypes.TIMESTAMP_WITH_TIMEZONE: return "timestamp($p)"; default: return super.columnType( sqlTypeCode ); } } @Override public int getDefaultStatementBatchSize() { return 15; } @Override public JdbcType resolveSqlTypeDescriptor( String columnTypeName, int jdbcTypeCode, int precision, int scale, JdbcTypeRegistry jdbcTypeRegistry) { if ( jdbcTypeCode == Types.BIT ) { return jdbcTypeRegistry.getDescriptor( Types.BOOLEAN ); } return super.resolveSqlTypeDescriptor( columnTypeName, jdbcTypeCode, precision, scale, jdbcTypeRegistry ); } @Override public int getPreferredSqlTypeCodeForBoolean() { return Types.BIT; } @Override public int getDefaultDecimalPrecision() { //the maximum return 40; } @Override public void initializeFunctionRegistry(FunctionContributions functionContributions) { super.initializeFunctionRegistry(functionContributions); CommonFunctionFactory functionFactory = new CommonFunctionFactory(functionContributions); functionFactory.trim2(); functionFactory.soundex(); functionFactory.trunc(); functionFactory.toCharNumberDateTimestamp(); functionFactory.ceiling_ceil(); functionFactory.instr(); functionFactory.substr(); functionFactory.substring_substr(); functionFactory.leftRight_substr(); functionFactory.char_chr(); functionFactory.rownumRowid(); functionFactory.sysdate(); functionFactory.addMonths(); functionFactory.monthsBetween(); functionContributions.getFunctionRegistry().registerBinaryTernaryPattern( "locate", functionContributions.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ), "instr(?2,?1)", "instr(?2,?1,?3)", STRING, STRING, INTEGER, functionContributions.getTypeConfiguration() ).setArgumentListSignature("(pattern, string[, start])"); } @Override public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( SessionFactoryImplementor sessionFactory, Statement statement) { return new TimesTenSqlAstTranslator<>( sessionFactory, statement ); } }; } @Override public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType, IntervalType intervalType) { switch (unit) { case NANOSECOND: case NATIVE: return "timestampadd(sql_tsi_frac_second,?2,?3)"; default: return "timestampadd(sql_tsi_?1,?2,?3)"; } } @Override public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) { switch (unit) { case NANOSECOND: case NATIVE: return "timestampdiff(sql_tsi_frac_second,?2,?3)"; default: return "timestampdiff(sql_tsi_?1,?2,?3)"; } } @Override public boolean qualifyIndexName() { return false; } @Override public String getAddColumnString() { return "add"; } @Override public SequenceSupport getSequenceSupport() { return TimesTenSequenceSupport.INSTANCE; } @Override public String getQuerySequencesString() { return "select name from sys.sequences"; } @Override public SequenceInformationExtractor getSequenceInformationExtractor() { return SequenceInformationExtractorTimesTenDatabaseImpl.INSTANCE; } @Override public boolean supportsNoWait() { return true; } @Override public RowLockStrategy getWriteRowLockStrategy() { return RowLockStrategy.COLUMN; } @Override public String getForUpdateString(String aliases) { return " for update of " + aliases; } @Override public String getForUpdateNowaitString() { return " for update nowait"; } @Override public String getWriteLockString(int timeout) { return withTimeout( getForUpdateString(), timeout ); } @Override public String getWriteLockString(String aliases, int timeout) { return withTimeout( getForUpdateString(aliases), timeout ); } @Override public String getReadLockString(int timeout) { return getWriteLockString( timeout ); } @Override public String getReadLockString(String aliases, int timeout) { return getWriteLockString( aliases, timeout ); } private String withTimeout(String lockString, int timeout) { switch (timeout) { case LockOptions.NO_WAIT: return supportsNoWait() ? lockString + " nowait" : lockString; case LockOptions.SKIP_LOCKED: case LockOptions.WAIT_FOREVER: return lockString; default: return supportsWait() ? lockString + " wait " + getTimeoutInSeconds( timeout ) : lockString; } } @Override public boolean supportsColumnCheck() { return false; } @Override public boolean supportsTableCheck() { return false; } @Override public boolean supportsOffsetInSubquery() { return true; } @Override public LimitHandler getLimitHandler() { return TimesTenLimitHandler.INSTANCE; } @Override public boolean supportsCurrentTimestampSelection() { return true; } @Override public String getCurrentTimestampSelectString() { return "select sysdate from sys.dual"; } @Override public boolean isCurrentTimestampSelectStringCallable() { return false; } @Override public SqmMultiTableMutationStrategy getFallbackSqmMutationStrategy( EntityMappingType rootEntityDescriptor, RuntimeModelCreationContext runtimeModelCreationContext) { return new GlobalTemporaryTableMutationStrategy( TemporaryTable.createIdTable( rootEntityDescriptor, name -> TemporaryTable.ID_TABLE_PREFIX + name, this, runtimeModelCreationContext ), runtimeModelCreationContext.getSessionFactory() ); } @Override public SqmMultiTableInsertStrategy getFallbackSqmInsertStrategy( EntityMappingType rootEntityDescriptor, RuntimeModelCreationContext runtimeModelCreationContext) { return new GlobalTemporaryTableInsertStrategy( TemporaryTable.createEntityTable( rootEntityDescriptor, name -> TemporaryTable.ENTITY_TABLE_PREFIX + name, this, runtimeModelCreationContext ), runtimeModelCreationContext.getSessionFactory() ); } @Override public TemporaryTableKind getSupportedTemporaryTableKind() { return TemporaryTableKind.GLOBAL; } @Override public String getTemporaryTableCreateOptions() { return "on commit delete rows"; } @Override public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) { // TimesTen has no known variation of a "SELECT ... FOR UPDATE" syntax... switch ( lockMode ) { case OPTIMISTIC: return new OptimisticLockingStrategy( lockable, lockMode ); case OPTIMISTIC_FORCE_INCREMENT: return new OptimisticForceIncrementLockingStrategy( lockable, lockMode ); case PESSIMISTIC_READ: return new PessimisticReadUpdateLockingStrategy( lockable, lockMode ); case PESSIMISTIC_WRITE: return new PessimisticWriteUpdateLockingStrategy( lockable, lockMode ); case PESSIMISTIC_FORCE_INCREMENT: return new PessimisticForceIncrementLockingStrategy( lockable, lockMode ); } if ( lockMode.greaterThan( LockMode.READ ) ) { return new UpdateLockingStrategy( lockable, lockMode ); } else { return new SelectLockingStrategy( lockable, lockMode ); } } @Override public int getMaxAliasLength() { // Max identifier length is 30, but Hibernate needs to add "uniqueing info" so we account for that return 20; } @Override public int getMaxIdentifierLength() { return 30; } @Override public boolean supportsCircularCascadeDeleteConstraints() { return false; } @Override public String getSelectClauseNullString(int sqlType, TypeConfiguration typeConfiguration) { switch (sqlType) { case Types.VARCHAR: case Types.CHAR: return "to_char(null)"; case Types.DATE: case Types.TIME: case Types.TIMESTAMP: case Types.TIMESTAMP_WITH_TIMEZONE: return "to_date(null)"; default: return "to_number(null)"; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy