org.hibernate.community.dialect.RDMSOS2200Dialect Maven / Gradle / Ivy
Show all versions of hibernate-community-dialects Show documentation
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.community.dialect;
import java.lang.invoke.MethodHandles;
import java.sql.Types;
import org.hibernate.LockMode;
import org.hibernate.boot.model.FunctionContributions;
import org.hibernate.community.dialect.sequence.RDMSSequenceSupport;
import org.hibernate.dialect.AbstractTransactSQLDialect;
import org.hibernate.dialect.DatabaseVersion;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.OracleDialect;
import org.hibernate.dialect.SimpleDatabaseVersion;
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.FetchLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.sequence.SequenceSupport;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.sqm.IntervalType;
import org.hibernate.query.common.TemporalUnit;
import org.hibernate.query.sqm.TrimSpec;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
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.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.jboss.logging.Logger;
import jakarta.persistence.TemporalType;
import static org.hibernate.dialect.SimpleDatabaseVersion.ZERO_VERSION;
import static org.hibernate.type.SqlTypes.BIGINT;
import static org.hibernate.type.SqlTypes.BINARY;
import static org.hibernate.type.SqlTypes.BLOB;
import static org.hibernate.type.SqlTypes.BOOLEAN;
import static org.hibernate.type.SqlTypes.CHAR;
import static org.hibernate.type.SqlTypes.CLOB;
import static org.hibernate.type.SqlTypes.LONG32NVARCHAR;
import static org.hibernate.type.SqlTypes.LONG32VARBINARY;
import static org.hibernate.type.SqlTypes.LONG32VARCHAR;
import static org.hibernate.type.SqlTypes.NCHAR;
import static org.hibernate.type.SqlTypes.NCLOB;
import static org.hibernate.type.SqlTypes.NVARCHAR;
import static org.hibernate.type.SqlTypes.TIMESTAMP;
import static org.hibernate.type.SqlTypes.TIMESTAMP_WITH_TIMEZONE;
import static org.hibernate.type.SqlTypes.TINYINT;
import static org.hibernate.type.SqlTypes.VARBINARY;
import static org.hibernate.type.SqlTypes.VARCHAR;
/**
* This is the Hibernate dialect for the Unisys 2200 Relational Database (RDMS).
* This dialect was developed for use with Hibernate 3.0.5. Other versions may
* require modifications to the dialect.
*
* Version History:
* Also change the version displayed below in the constructor
* 1.1
* 1.0 2005-10-24 CDH - First dated version for use with CP 11
*
* @author Ploski and Hanson
*/
public class RDMSOS2200Dialect extends Dialect {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
MethodHandles.lookup(),
CoreMessageLogger.class,
RDMSOS2200Dialect.class.getName()
);
/**
* Constructs a RDMSOS2200Dialect
*/
public RDMSOS2200Dialect() {
super( SimpleDatabaseVersion.ZERO_VERSION );
}
public RDMSOS2200Dialect(DialectResolutionInfo info) {
super( info );
}
@Override
protected String columnType(int sqlTypeCode) {
/*
* For a list of column types to register, see section A-1
* in 7862 7395, the Unisys JDBC manual.
*
* Here are column sizes as documented in Table A-1 of
* 7831 0760, "Enterprise Relational Database Server
* for ClearPath OS2200 Administration Guide"
* Numeric - 21
* Decimal - 22 (21 digits plus one for sign)
* Float - 60 bits
* Char - 28000
* NChar - 14000
* BLOB+ - 4294967296 (4 Gb)
* + RDMS JDBC driver does not support BLOBs
*
* DATE, TIME and TIMESTAMP literal formats are
* are all described in section 2.3.4 DATE Literal Format
* in 7830 8160.
* The DATE literal format is: YYYY-MM-DD
* The TIME literal format is: HH:MM:SS[.[FFFFFF]]
* The TIMESTAMP literal format is: YYYY-MM-DD HH:MM:SS[.[FFFFFF]]
*
* Note that $l (dollar-L) will use the length value if provided.
* Also new for Hibernate3 is the $p percision and $s (scale) parameters
*/
switch ( sqlTypeCode ) {
case BOOLEAN:
case TINYINT:
return "smallint";
case BIGINT:
return "numeric(19,0)";
//'varchar' is not supported in RDMS for OS 2200
//(but it is for other flavors of RDMS)
//'character' means ASCII by default, 'unicode(n)'
//means 'character(n) character set "UCS-2"'
case CHAR:
case NCHAR:
case VARCHAR:
case NVARCHAR:
case LONG32VARCHAR:
case LONG32NVARCHAR:
return "unicode($l)";
case CLOB:
case NCLOB:
return "clob($l)";
//no 'binary' nor 'varbinary' so use 'blob'
case BINARY:
case VARBINARY:
case LONG32VARBINARY:
case BLOB:
return "blob($l)";
case TIMESTAMP_WITH_TIMEZONE:
return columnType( TIMESTAMP );
default:
return super.columnType( sqlTypeCode );
}
}
@Override
public boolean useMaterializedLobWhenCapacityExceeded() {
return false;
}
@Override
public int getMaxVarbinaryLength() {
//no varbinary type
return -1;
}
@Override
public DatabaseVersion getVersion() {
return ZERO_VERSION;
}
@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 (really low) maximum
return 21;
}
@Override
public void initializeFunctionRegistry(FunctionContributions functionContributions) {
super.initializeFunctionRegistry(functionContributions);
CommonFunctionFactory functionFactory = new CommonFunctionFactory(functionContributions);
functionFactory.cosh();
functionFactory.sinh();
functionFactory.tanh();
functionFactory.cot();
functionFactory.log();
functionFactory.log10();
functionFactory.pi();
functionFactory.rand();
functionFactory.trunc();
// functionFactory.truncate();
functionFactory.soundex();
functionFactory.trim2();
functionFactory.space();
functionFactory.repeat();
// functionFactory.replicate(); //synonym for more common repeat()
functionFactory.initcap();
functionFactory.instr();
functionFactory.substr();
functionFactory.translate();
functionFactory.yearMonthDay();
functionFactory.hourMinuteSecond();
functionFactory.dayofweekmonthyear();
functionFactory.weekQuarter();
functionFactory.daynameMonthname();
functionFactory.lastDay();
functionFactory.ceiling_ceil();
functionFactory.concat_pipeOperator();
functionFactory.ascii();
functionFactory.chr_char();
functionFactory.insert();
functionFactory.addMonths();
functionFactory.monthsBetween();
}
@Override
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
return new StandardSqlAstTranslatorFactory() {
@Override
protected SqlAstTranslator buildTranslator(
SessionFactoryImplementor sessionFactory, Statement statement) {
return new RDMSOS2200SqlAstTranslator<>( sessionFactory, statement );
}
};
}
@Override
public long getFractionalSecondPrecisionInNanos() {
return 1_000; //microseconds
}
/**
* RDMS supports a limited list of temporal fields in the
* extract() function, but we can emulate some of them by
* using the appropriate named functions instead of
* extract().
*
* Thus, the additional supported fields are
* {@link TemporalUnit#DAY_OF_YEAR},
* {@link TemporalUnit#DAY_OF_MONTH},
* {@link TemporalUnit#DAY_OF_YEAR}.
*
* In addition, the field {@link TemporalUnit#SECOND} is
* redefined to include microseconds.
*/
@Override
public String extractPattern(TemporalUnit unit) {
switch (unit) {
case SECOND:
return "(second(?2)+microsecond(?2)/1e6)";
case DAY_OF_WEEK:
return "dayofweek(?2)";
case DAY_OF_MONTH:
return "dayofmonth(?2)";
case DAY_OF_YEAR:
return "dayofyear(?2)";
default:
return "?1(?2)";
}
}
@Override
public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType, IntervalType intervalType) {
switch (unit) {
case NANOSECOND:
return "timestampadd('SQL_TSI_FRAC_SECOND',(?2)/1e3,?3)";
case NATIVE:
return "timestampadd('SQL_TSI_FRAC_SECOND',?2,?3)";
default:
return "dateadd('?1',?2,?3)";
}
}
@Override
public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) {
switch (unit) {
case NANOSECOND:
return "timestampdiff('SQL_TSI_FRAC_SECOND',?2,?3)*1e3";
case NATIVE:
return "timestampdiff('SQL_TSI_FRAC_SECOND',?2,?3)";
default:
return "dateadd('?1',?2,?3)";
}
}
// Dialect method overrides ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* RDMS does not support qualifing index names with the schema name.
*
* {@inheritDoc}
*/
@Override
public boolean qualifyIndexName() {
return false;
}
/**
* {@code FOR UPDATE} only supported for cursors
*
* @return the empty string
*/
@Override
public String getForUpdateString() {
// Original Dialect.java returns " for update";
return "";
}
// Verify the state of this new method in Hibernate 3.0 Dialect.java
/**
* RDMS does not support Cascade Deletes.
* Need to review this in the future when support is provided.
*
* {@inheritDoc}
*/
@Override
public boolean supportsCascadeDelete() {
return false;
}
/**
* Currently, RDMS-JDBC does not support ForUpdate.
* Need to review this in the future when support is provided.
*
* {@inheritDoc}
*/
@Override
public boolean supportsOuterJoinForUpdate() {
return false;
}
@Override
public String getAddColumnString() {
return "add";
}
@Override
public String getNullColumnString() {
// The keyword used to specify a nullable column.
return " null";
}
@Override
public SequenceSupport getSequenceSupport() {
return RDMSSequenceSupport.INSTANCE;
}
@Override
public String getCascadeConstraintsString() {
// Used with DROP TABLE to delete all records in the table.
return " including contents";
}
@Override
public LimitHandler getLimitHandler() {
return FetchLimitHandler.INSTANCE;
}
@Override
public boolean supportsOrderByInSubquery() {
// This is just a guess
return false;
}
@Override
public LockingStrategy getLockingStrategy(EntityPersister lockable, LockMode lockMode) {
// RDMS has no known variation of a "SELECT ... FOR UPDATE" syntax...
switch (lockMode) {
case PESSIMISTIC_FORCE_INCREMENT:
return new PessimisticForceIncrementLockingStrategy(lockable, lockMode);
case PESSIMISTIC_WRITE:
return new PessimisticWriteUpdateLockingStrategy(lockable, lockMode);
case PESSIMISTIC_READ:
return new PessimisticReadUpdateLockingStrategy(lockable, lockMode);
case OPTIMISTIC:
return new OptimisticLockingStrategy(lockable, lockMode);
case OPTIMISTIC_FORCE_INCREMENT:
return new OptimisticForceIncrementLockingStrategy(lockable, lockMode);
}
if ( lockMode.greaterThan( LockMode.READ ) ) {
return new UpdateLockingStrategy( lockable, lockMode );
}
else {
return new SelectLockingStrategy( lockable, lockMode );
}
}
@Override
public void appendDatetimeFormat(SqlAppender appender, String format) {
appender.appendSql(
OracleDialect.datetimeFormat( format, true, false ) //Does it really support FM?
.replace("SSSSSS", "MLS")
.replace("SSSSS", "MLS")
.replace("SSSS", "MLS")
.replace("SSS", "MLS")
.replace("SS", "MLS")
.replace("S", "MLS")
.result()
);
}
@Override
public String trimPattern(TrimSpec specification, boolean isWhitespace) {
return AbstractTransactSQLDialect.replaceLtrimRtrim( specification, isWhitespace );
}
@Override
public String getDual() {
return "rdms.rdms_dummy";
}
@Override
public String getFromDualForSelectOnly() {
return " from " + getDual() + " where key_col=1";
}
}