package org.hibernate.dialect;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Iterator;
import java.util.Map;
import org.hibernate.HibernateException;
import org.hibernate.LockOptions;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.model.relational.QualifiedNameImpl;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.identity.IdentityColumnSupport;
import org.hibernate.dialect.identity.Teradata14IdentityColumnSupport;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.spi.QueryParameters;
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Index;
import org.hibernate.sql.ForUpdateFragment;
import org.hibernate.tool.schema.internal.StandardIndexExporter;
import org.hibernate.tool.schema.spi.Exporter;
import org.hibernate.type.StandardBasicTypes;
public class Teradata14Dialect extends TeradataDialect {
StandardIndexExporter TeraIndexExporter = null;
public Teradata14Dialect() {
super();
registerColumnType( Types.BIGINT, "BIGINT" );
registerColumnType( Types.BINARY, "VARBYTE(100)" );
registerColumnType( Types.LONGVARBINARY, "VARBYTE(32000)" );
registerColumnType( Types.LONGVARCHAR, "VARCHAR(32000)" );
getDefaultProperties().setProperty( Environment.USE_STREAMS_FOR_BINARY, "true" );
getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
registerFunction( "current_time", new SQLFunctionTemplate( StandardBasicTypes.TIME, "current_time" ) );
registerFunction( "current_date", new SQLFunctionTemplate( StandardBasicTypes.DATE, "current_date" ) );
TeraIndexExporter = new TeradataIndexExporter( this );
}
@Override
public String getAddColumnString() {
return "Add";
}
public String getTypeName(int code, int length, int precision, int scale) throws HibernateException {
float f = precision > 0 ? (float) scale / (float) precision : 0;
int p = ( precision > 38 ? 38 : precision );
int s = ( precision > 38 ? (int) ( 38.0 * f ) : ( scale > 38 ? 38 : scale ) );
return super.getTypeName( code, length, p, s );
}
@Override
public boolean areStringComparisonsCaseInsensitive() {
return false;
}
@Override
public boolean supportsExpectedLobUsagePattern() {
return true;
}
@Override
public ViolatedConstraintNameExtracter () {
return EXTRACTER;
}
@Override
public boolean supportsTupleDistinctCounts() {
return false;
}
@Override
public boolean supportsExistsInSelect() {
return false;
}
@Override
public boolean supportsUnboundedLobLocatorMaterialization() {
return false;
}
@Override
public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
statement.registerOutParameter( col, Types.REF );
col++;
return col;
}
@Override
public ResultSet getResultSet(CallableStatement cs) throws SQLException {
boolean isResultSet = cs.execute();
while ( !isResultSet && cs.getUpdateCount() != -1 ) {
isResultSet = cs.getMoreResults();
}
return cs.getResultSet();
}
private static ViolatedConstraintNameExtracter = new TemplatedViolatedConstraintNameExtracter() {
@Override
protected String (SQLException sqle) throws NumberFormatException {
String constraintName = null;
int errorCode = sqle.getErrorCode();
if ( errorCode == 27003 ) {
constraintName = extractUsingTemplate( "Unique constraint (", ") violated.", sqle.getMessage() );
}
else if ( errorCode == 2700 ) {
constraintName = extractUsingTemplate( "Referential constraint", "violation:", sqle.getMessage() );
}
else if ( errorCode == 5317 ) {
constraintName = extractUsingTemplate( "Check constraint (", ") violated.", sqle.getMessage() );
}
if ( constraintName != null ) {
int i = constraintName.indexOf( '.' );
if ( i != -1 ) {
constraintName = constraintName.substring( i + 1 );
}
}
return constraintName;
}
};
@Override
public String getWriteLockString(int timeout) {
String sMsg = " Locking row for write ";
if ( timeout == LockOptions.NO_WAIT ) {
return sMsg + " nowait ";
}
return sMsg;
}
@Override
public String getReadLockString(int timeout) {
String sMsg = " Locking row for read ";
if ( timeout == LockOptions.NO_WAIT ) {
return sMsg + " nowait ";
}
return sMsg;
}
@Override
public String applyLocksToSql(String sql, LockOptions aliasedLockOptions, Map keyColumnNames) {
return new ForUpdateFragment( this, aliasedLockOptions, keyColumnNames ).toFragmentString() + " " + sql;
}
@Override
public boolean useFollowOnLocking(QueryParameters parameters) {
return true;
}
@Override
public boolean supportsLockTimeouts() {
return false;
}
@Override
public Exporter<Index> getIndexExporter() {
return TeraIndexExporter;
}
private class TeradataIndexExporter extends StandardIndexExporter implements Exporter<Index> {
public TeradataIndexExporter(Dialect dialect) {
super(dialect);
}
@Override
public String[] getSqlCreateStrings(Index index, Metadata metadata) {
final JdbcEnvironment jdbcEnvironment = metadata.getDatabase().getJdbcEnvironment();
final String tableName = jdbcEnvironment.getQualifiedObjectNameFormatter().format(
index.getTable().getQualifiedTableName(),
jdbcEnvironment.getDialect()
);
final String indexNameForCreation;
if ( getDialect().qualifyIndexName() ) {
indexNameForCreation = jdbcEnvironment.getQualifiedObjectNameFormatter().format(
new QualifiedNameImpl(
index.getTable().getQualifiedTableName().getCatalogName(),
index.getTable().getQualifiedTableName().getSchemaName(),
jdbcEnvironment.getIdentifierHelper().toIdentifier( index.getName() )
),
jdbcEnvironment.getDialect()
);
}
else {
indexNameForCreation = index.getName();
}
StringBuilder colBuf = new StringBuilder("");
boolean first = true;
Iterator<Column> columnItr = index.getColumnIterator();
while ( columnItr.hasNext() ) {
final Column column = columnItr.next();
if ( first ) {
first = false;
}
else {
colBuf.append( ", " );
}
colBuf.append( ( column.getQuotedName( jdbcEnvironment.getDialect() )) );
}
colBuf.append( ")" );
final StringBuilder buf = new StringBuilder()
.append( "create index " )
.append( indexNameForCreation )
.append( "(" + colBuf )
.append( " on " )
.append( tableName );
return new String[] { buf.toString() };
}
}
@Override
public IdentityColumnSupport getIdentityColumnSupport() {
return new Teradata14IdentityColumnSupport();
}
}