mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-08 04:08:19 +00:00
HHH-8159 - Apply fixups indicated by analysis tools
This commit is contained in:
parent
8c28ba8463
commit
5fc70fc5ab
@ -101,7 +101,7 @@ public Serializable disassemble(CollectionPersister persister) throws HibernateE
|
||||
final Serializable[] result = new Serializable[length*2];
|
||||
int i = 0;
|
||||
while ( i < length*2 ) {
|
||||
final Element elem = (Element) elements.get(i/2);
|
||||
final Element elem = (Element) elements.get( i/2 );
|
||||
final Object object = elementType.fromXMLNode( elem, persister.getFactory() );
|
||||
final String indexString = getIndex( elem, indexNodeName, i );
|
||||
final Object index = ( (XmlRepresentableType) indexType ).fromXMLString( indexString, persister.getFactory() );
|
||||
|
@ -102,7 +102,7 @@ public SortedSet subSet(Object fromElement, Object toElement) {
|
||||
@SuppressWarnings("unchecked")
|
||||
public SortedSet headSet(Object toElement) {
|
||||
read();
|
||||
final SortedSet headSet = ( (SortedSet) set ).headSet(toElement);
|
||||
final SortedSet headSet = ( (SortedSet) set ).headSet( toElement );
|
||||
return new SubSetProxy( headSet );
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuer
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return propertyName + " in (" + StringHelper.toString(values) + ')';
|
||||
return propertyName + " in (" + StringHelper.toString( values ) + ')';
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) {
|
||||
final StringBuilder expression = new StringBuilder();
|
||||
boolean lower = false;
|
||||
if ( ignoreCase ) {
|
||||
int sqlType = sqlTypes[i];
|
||||
final int sqlType = sqlTypes[i];
|
||||
lower = sqlType == Types.VARCHAR
|
||||
|| sqlType == Types.CHAR
|
||||
|| sqlType == Types.LONGVARCHAR;
|
||||
|
@ -44,7 +44,7 @@ protected PropertyProjection(String prop, boolean grouped) {
|
||||
}
|
||||
|
||||
protected PropertyProjection(String prop) {
|
||||
this(prop, false);
|
||||
this( prop, false );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
@ -47,7 +48,7 @@
|
||||
abstract class AbstractTransactSQLDialect extends Dialect {
|
||||
public AbstractTransactSQLDialect() {
|
||||
super();
|
||||
registerColumnType( Types.BINARY, "binary($l)" );
|
||||
registerColumnType( Types.BINARY, "binary($l)" );
|
||||
registerColumnType( Types.BIT, "tinyint" );
|
||||
registerColumnType( Types.BIGINT, "numeric(19,0)" );
|
||||
registerColumnType( Types.SMALLINT, "smallint" );
|
||||
@ -65,94 +66,108 @@ public AbstractTransactSQLDialect() {
|
||||
registerColumnType( Types.BLOB, "image" );
|
||||
registerColumnType( Types.CLOB, "text" );
|
||||
|
||||
registerFunction( "ascii", new StandardSQLFunction("ascii", StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "char", new StandardSQLFunction("char", StandardBasicTypes.CHARACTER) );
|
||||
registerFunction( "len", new StandardSQLFunction("len", StandardBasicTypes.LONG) );
|
||||
registerFunction( "lower", new StandardSQLFunction("lower") );
|
||||
registerFunction( "upper", new StandardSQLFunction("upper") );
|
||||
registerFunction( "str", new StandardSQLFunction("str", StandardBasicTypes.STRING) );
|
||||
registerFunction( "ltrim", new StandardSQLFunction("ltrim") );
|
||||
registerFunction( "rtrim", new StandardSQLFunction("rtrim") );
|
||||
registerFunction( "reverse", new StandardSQLFunction("reverse") );
|
||||
registerFunction( "space", new StandardSQLFunction("space", StandardBasicTypes.STRING) );
|
||||
registerFunction( "ascii", new StandardSQLFunction( "ascii", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "char", new StandardSQLFunction( "char", StandardBasicTypes.CHARACTER ) );
|
||||
registerFunction( "len", new StandardSQLFunction( "len", StandardBasicTypes.LONG ) );
|
||||
registerFunction( "lower", new StandardSQLFunction( "lower" ) );
|
||||
registerFunction( "upper", new StandardSQLFunction( "upper" ) );
|
||||
registerFunction( "str", new StandardSQLFunction( "str", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "ltrim", new StandardSQLFunction( "ltrim" ) );
|
||||
registerFunction( "rtrim", new StandardSQLFunction( "rtrim" ) );
|
||||
registerFunction( "reverse", new StandardSQLFunction( "reverse" ) );
|
||||
registerFunction( "space", new StandardSQLFunction( "space", StandardBasicTypes.STRING ) );
|
||||
|
||||
registerFunction( "user", new NoArgSQLFunction("user", StandardBasicTypes.STRING) );
|
||||
registerFunction( "user", new NoArgSQLFunction( "user", StandardBasicTypes.STRING ) );
|
||||
|
||||
registerFunction( "current_timestamp", new NoArgSQLFunction("getdate", StandardBasicTypes.TIMESTAMP) );
|
||||
registerFunction( "current_time", new NoArgSQLFunction("getdate", StandardBasicTypes.TIME) );
|
||||
registerFunction( "current_date", new NoArgSQLFunction("getdate", StandardBasicTypes.DATE) );
|
||||
registerFunction( "current_timestamp", new NoArgSQLFunction( "getdate", StandardBasicTypes.TIMESTAMP ) );
|
||||
registerFunction( "current_time", new NoArgSQLFunction( "getdate", StandardBasicTypes.TIME ) );
|
||||
registerFunction( "current_date", new NoArgSQLFunction( "getdate", StandardBasicTypes.DATE ) );
|
||||
|
||||
registerFunction( "getdate", new NoArgSQLFunction("getdate", StandardBasicTypes.TIMESTAMP) );
|
||||
registerFunction( "getutcdate", new NoArgSQLFunction("getutcdate", StandardBasicTypes.TIMESTAMP) );
|
||||
registerFunction( "day", new StandardSQLFunction("day", StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "month", new StandardSQLFunction("month", StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "year", new StandardSQLFunction("year", StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "datename", new StandardSQLFunction("datename", StandardBasicTypes.STRING) );
|
||||
registerFunction( "getdate", new NoArgSQLFunction( "getdate", StandardBasicTypes.TIMESTAMP ) );
|
||||
registerFunction( "getutcdate", new NoArgSQLFunction( "getutcdate", StandardBasicTypes.TIMESTAMP ) );
|
||||
registerFunction( "day", new StandardSQLFunction( "day", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "month", new StandardSQLFunction( "month", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "year", new StandardSQLFunction( "year", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "datename", new StandardSQLFunction( "datename", StandardBasicTypes.STRING ) );
|
||||
|
||||
registerFunction( "abs", new StandardSQLFunction("abs") );
|
||||
registerFunction( "sign", new StandardSQLFunction("sign", StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "abs", new StandardSQLFunction( "abs" ) );
|
||||
registerFunction( "sign", new StandardSQLFunction( "sign", StandardBasicTypes.INTEGER ) );
|
||||
|
||||
registerFunction( "acos", new StandardSQLFunction("acos", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "asin", new StandardSQLFunction("asin", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "atan", new StandardSQLFunction("atan", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "cos", new StandardSQLFunction("cos", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "cot", new StandardSQLFunction("cot", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "exp", new StandardSQLFunction("exp", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "log", new StandardSQLFunction( "log", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "log10", new StandardSQLFunction("log10", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "sin", new StandardSQLFunction("sin", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "sqrt", new StandardSQLFunction("sqrt", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "tan", new StandardSQLFunction("tan", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "pi", new NoArgSQLFunction("pi", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "square", new StandardSQLFunction("square") );
|
||||
registerFunction( "rand", new StandardSQLFunction("rand", StandardBasicTypes.FLOAT) );
|
||||
registerFunction( "acos", new StandardSQLFunction( "acos", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "asin", new StandardSQLFunction( "asin", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "atan", new StandardSQLFunction( "atan", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "cos", new StandardSQLFunction( "cos", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "cot", new StandardSQLFunction( "cot", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "exp", new StandardSQLFunction( "exp", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "log", new StandardSQLFunction( "log", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "log10", new StandardSQLFunction( "log10", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "sin", new StandardSQLFunction( "sin", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "sqrt", new StandardSQLFunction( "sqrt", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "tan", new StandardSQLFunction( "tan", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "pi", new NoArgSQLFunction( "pi", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "square", new StandardSQLFunction( "square" ) );
|
||||
registerFunction( "rand", new StandardSQLFunction( "rand", StandardBasicTypes.FLOAT ) );
|
||||
|
||||
registerFunction("radians", new StandardSQLFunction("radians", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("degrees", new StandardSQLFunction("degrees", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "radians", new StandardSQLFunction( "radians", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "degrees", new StandardSQLFunction( "degrees", StandardBasicTypes.DOUBLE ) );
|
||||
|
||||
registerFunction( "round", new StandardSQLFunction("round") );
|
||||
registerFunction( "ceiling", new StandardSQLFunction("ceiling") );
|
||||
registerFunction( "floor", new StandardSQLFunction("floor") );
|
||||
registerFunction( "round", new StandardSQLFunction( "round" ) );
|
||||
registerFunction( "ceiling", new StandardSQLFunction( "ceiling" ) );
|
||||
registerFunction( "floor", new StandardSQLFunction( "floor" ) );
|
||||
|
||||
registerFunction( "isnull", new StandardSQLFunction("isnull") );
|
||||
registerFunction( "isnull", new StandardSQLFunction( "isnull" ) );
|
||||
|
||||
registerFunction( "concat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "(","+",")" ) );
|
||||
registerFunction( "concat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "(", "+", ")" ) );
|
||||
|
||||
registerFunction( "length", new StandardSQLFunction( "len", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "trim", new SQLFunctionTemplate( StandardBasicTypes.STRING, "ltrim(rtrim(?1))") );
|
||||
registerFunction( "trim", new SQLFunctionTemplate( StandardBasicTypes.STRING, "ltrim(rtrim(?1))" ) );
|
||||
registerFunction( "locate", new CharIndexFunction() );
|
||||
|
||||
getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH);
|
||||
getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, NO_BATCH );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
return "add";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNullColumnString() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean qualifyIndexName() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForUpdateString() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsIdentityColumns() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentitySelectString() {
|
||||
return "select @@identity";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentityColumnString() {
|
||||
return "identity not null"; //starts with 1, implicitly
|
||||
//starts with 1, implicitly
|
||||
return "identity not null";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsInsertSelectIdentity() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String appendIdentitySelectToInsert(String insertSQL) {
|
||||
return insertSQL + "\nselect @@identity";
|
||||
}
|
||||
@ -162,17 +177,19 @@ public String appendLockHint(LockOptions lockOptions, String tableName) {
|
||||
return lockOptions.getLockMode().greaterThan( LockMode.READ ) ? tableName + " holdlock" : tableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String applyLocksToSql(String sql, LockOptions aliasedLockOptions, Map keyColumnNames) {
|
||||
// TODO: merge additional lockoptions support in Dialect.applyLocksToSql
|
||||
Iterator itr = aliasedLockOptions.getAliasLockIterator();
|
||||
StringBuilder buffer = new StringBuilder( sql );
|
||||
final Iterator itr = aliasedLockOptions.getAliasLockIterator();
|
||||
final StringBuilder buffer = new StringBuilder( sql );
|
||||
int correction = 0;
|
||||
while ( itr.hasNext() ) {
|
||||
final Map.Entry entry = ( Map.Entry ) itr.next();
|
||||
final LockMode lockMode = ( LockMode ) entry.getValue();
|
||||
final Map.Entry entry = (Map.Entry) itr.next();
|
||||
final LockMode lockMode = (LockMode) entry.getValue();
|
||||
if ( lockMode.greaterThan( LockMode.READ ) ) {
|
||||
final String alias = ( String ) entry.getKey();
|
||||
int start = -1, end = -1;
|
||||
final String alias = (String) entry.getKey();
|
||||
int start = -1;
|
||||
int end = -1;
|
||||
if ( sql.endsWith( " " + alias ) ) {
|
||||
start = ( sql.length() - alias.length() ) + correction;
|
||||
end = start + alias.length();
|
||||
@ -198,69 +215,89 @@ public String applyLocksToSql(String sql, LockOptions aliasedLockOptions, Map ke
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
|
||||
return col; // sql server just returns automatically
|
||||
// sql server just returns automatically
|
||||
return col;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getResultSet(CallableStatement ps) throws SQLException {
|
||||
boolean isResultSet = ps.execute();
|
||||
// This assumes you will want to ignore any update counts
|
||||
// This assumes you will want to ignore any update counts
|
||||
while ( !isResultSet && ps.getUpdateCount() != -1 ) {
|
||||
isResultSet = ps.getMoreResults();
|
||||
}
|
||||
// You may still have other ResultSets or update counts left to process here
|
||||
// but you can't do it now or the ResultSet you just got will be closed
|
||||
|
||||
// You may still have other ResultSets or update counts left to process here
|
||||
// but you can't do it now or the ResultSet you just got will be closed
|
||||
return ps.getResultSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCurrentTimestampSelection() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurrentTimestampSelectStringCallable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentTimestampSelectString() {
|
||||
return "select getdate()";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTemporaryTables() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateTemporaryTableName(String baseTableName) {
|
||||
return "#" + baseTableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dropTemporaryTableAfterUse() {
|
||||
return true; // sql-server, at least needed this dropped after use; strange!
|
||||
// sql-server, at least needed this dropped after use; strange!
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectGUIDString() {
|
||||
return "select newid()";
|
||||
}
|
||||
|
||||
// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public boolean supportsEmptyInList() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsUnionAll() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsExistsInSelect() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesReadCommittedCauseWritersToBlockReaders() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesRepeatableReadCauseReadersToBlockWriters() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTupleDistinctCounts() {
|
||||
return false;
|
||||
}
|
||||
|
@ -21,18 +21,16 @@
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.function.NoArgSQLFunction;
|
||||
import org.hibernate.dialect.function.StandardSQLFunction;
|
||||
import org.hibernate.dialect.function.VarArgsSQLFunction;
|
||||
import org.hibernate.dialect.pagination.LimitHandler;
|
||||
import org.hibernate.dialect.pagination.CUBRIDLimitHandler;
|
||||
import org.hibernate.dialect.pagination.LimitHandler;
|
||||
import org.hibernate.engine.spi.RowSelection;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
|
||||
@ -42,13 +40,16 @@
|
||||
* @author Seok Jeong Il
|
||||
*/
|
||||
public class CUBRIDDialect extends Dialect {
|
||||
public CUBRIDDialect() {
|
||||
super();
|
||||
/**
|
||||
* Constructs a CUBRIDDialect
|
||||
*/
|
||||
public CUBRIDDialect() {
|
||||
super();
|
||||
|
||||
registerColumnType( Types.BIGINT, "bigint" );
|
||||
registerColumnType( Types.BIT, "bit(8)" );
|
||||
registerColumnType( Types.BLOB, "bit varying(65535)" );
|
||||
registerColumnType( Types.BOOLEAN, "bit(8)");
|
||||
registerColumnType( Types.BIT, "bit(8)" );
|
||||
registerColumnType( Types.BLOB, "bit varying(65535)" );
|
||||
registerColumnType( Types.BOOLEAN, "bit(8)" );
|
||||
registerColumnType( Types.CHAR, "char(1)" );
|
||||
registerColumnType( Types.CLOB, "string" );
|
||||
registerColumnType( Types.DATE, "date" );
|
||||
@ -57,289 +58,324 @@ public CUBRIDDialect() {
|
||||
registerColumnType( Types.FLOAT, "float" );
|
||||
registerColumnType( Types.INTEGER, "int" );
|
||||
registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
|
||||
registerColumnType( Types.REAL, "double" );
|
||||
registerColumnType( Types.SMALLINT, "short" );
|
||||
registerColumnType( Types.TIME, "time" );
|
||||
registerColumnType( Types.TIMESTAMP, "timestamp" );
|
||||
registerColumnType( Types.TINYINT, "short" );
|
||||
registerColumnType( Types.REAL, "double" );
|
||||
registerColumnType( Types.SMALLINT, "short" );
|
||||
registerColumnType( Types.TIME, "time" );
|
||||
registerColumnType( Types.TIMESTAMP, "timestamp" );
|
||||
registerColumnType( Types.TINYINT, "short" );
|
||||
registerColumnType( Types.VARBINARY, 2000, "bit varying($l)" );
|
||||
registerColumnType( Types.VARCHAR, "string" );
|
||||
registerColumnType( Types.VARCHAR, 2000, "varchar($l)" );
|
||||
registerColumnType( Types.VARCHAR, 255, "varchar($l)" );
|
||||
registerColumnType( Types.VARCHAR, "string" );
|
||||
registerColumnType( Types.VARCHAR, 2000, "varchar($l)" );
|
||||
registerColumnType( Types.VARCHAR, 255, "varchar($l)" );
|
||||
|
||||
getDefaultProperties().setProperty(Environment.USE_STREAMS_FOR_BINARY, "true");
|
||||
getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);
|
||||
getDefaultProperties().setProperty( Environment.USE_STREAMS_FOR_BINARY, "true" );
|
||||
getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
|
||||
|
||||
registerFunction("ascii", new StandardSQLFunction("ascii", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("bin", new StandardSQLFunction("bin", StandardBasicTypes.STRING) );
|
||||
registerFunction("char_length", new StandardSQLFunction("char_length", StandardBasicTypes.LONG) );
|
||||
registerFunction("character_length", new StandardSQLFunction("character_length", StandardBasicTypes.LONG) );
|
||||
registerFunction("lengthb", new StandardSQLFunction("lengthb", StandardBasicTypes.LONG) );
|
||||
registerFunction("lengthh", new StandardSQLFunction("lengthh", StandardBasicTypes.LONG) );
|
||||
registerFunction("lcase", new StandardSQLFunction("lcase") );
|
||||
registerFunction("lower", new StandardSQLFunction("lower") );
|
||||
registerFunction("ltrim", new StandardSQLFunction("ltrim") );
|
||||
registerFunction("reverse", new StandardSQLFunction("reverse") );
|
||||
registerFunction("rtrim", new StandardSQLFunction("rtrim") );
|
||||
registerFunction("trim", new StandardSQLFunction("trim") );
|
||||
registerFunction("space", new StandardSQLFunction("space", StandardBasicTypes.STRING) );
|
||||
registerFunction("ucase", new StandardSQLFunction("ucase") );
|
||||
registerFunction("upper", new StandardSQLFunction("upper") );
|
||||
registerFunction( "ascii", new StandardSQLFunction( "ascii", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "bin", new StandardSQLFunction( "bin", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "char_length", new StandardSQLFunction( "char_length", StandardBasicTypes.LONG ) );
|
||||
registerFunction( "character_length", new StandardSQLFunction( "character_length", StandardBasicTypes.LONG ) );
|
||||
registerFunction( "lengthb", new StandardSQLFunction( "lengthb", StandardBasicTypes.LONG ) );
|
||||
registerFunction( "lengthh", new StandardSQLFunction( "lengthh", StandardBasicTypes.LONG ) );
|
||||
registerFunction( "lcase", new StandardSQLFunction( "lcase" ) );
|
||||
registerFunction( "lower", new StandardSQLFunction( "lower" ) );
|
||||
registerFunction( "ltrim", new StandardSQLFunction( "ltrim" ) );
|
||||
registerFunction( "reverse", new StandardSQLFunction( "reverse" ) );
|
||||
registerFunction( "rtrim", new StandardSQLFunction( "rtrim" ) );
|
||||
registerFunction( "trim", new StandardSQLFunction( "trim" ) );
|
||||
registerFunction( "space", new StandardSQLFunction( "space", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "ucase", new StandardSQLFunction( "ucase" ) );
|
||||
registerFunction( "upper", new StandardSQLFunction( "upper" ) );
|
||||
|
||||
registerFunction("abs", new StandardSQLFunction("abs") );
|
||||
registerFunction("sign", new StandardSQLFunction("sign", StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "abs", new StandardSQLFunction( "abs" ) );
|
||||
registerFunction( "sign", new StandardSQLFunction( "sign", StandardBasicTypes.INTEGER ) );
|
||||
|
||||
registerFunction("acos", new StandardSQLFunction("acos", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("asin", new StandardSQLFunction("asin", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("atan", new StandardSQLFunction("atan", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("cos", new StandardSQLFunction("cos", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("cot", new StandardSQLFunction("cot", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("exp", new StandardSQLFunction("exp", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("ln", new StandardSQLFunction("ln", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("log2", new StandardSQLFunction("log2", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("log10", new StandardSQLFunction("log10", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("pi", new NoArgSQLFunction("pi", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("rand", new NoArgSQLFunction("rand", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("random", new NoArgSQLFunction("random", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("sin", new StandardSQLFunction("sin", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("sqrt", new StandardSQLFunction("sqrt", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("tan", new StandardSQLFunction("tan", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "acos", new StandardSQLFunction( "acos", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "asin", new StandardSQLFunction( "asin", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "atan", new StandardSQLFunction( "atan", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "cos", new StandardSQLFunction( "cos", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "cot", new StandardSQLFunction( "cot", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "exp", new StandardSQLFunction( "exp", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "ln", new StandardSQLFunction( "ln", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "log2", new StandardSQLFunction( "log2", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "log10", new StandardSQLFunction( "log10", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "pi", new NoArgSQLFunction( "pi", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "rand", new NoArgSQLFunction( "rand", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "random", new NoArgSQLFunction( "random", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "sin", new StandardSQLFunction( "sin", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "sqrt", new StandardSQLFunction( "sqrt", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "tan", new StandardSQLFunction( "tan", StandardBasicTypes.DOUBLE ) );
|
||||
|
||||
registerFunction("radians", new StandardSQLFunction("radians", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("degrees", new StandardSQLFunction("degrees", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "radians", new StandardSQLFunction( "radians", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "degrees", new StandardSQLFunction( "degrees", StandardBasicTypes.DOUBLE ) );
|
||||
|
||||
registerFunction("ceil", new StandardSQLFunction("ceil", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("floor", new StandardSQLFunction("floor", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("round", new StandardSQLFunction("round") );
|
||||
registerFunction( "ceil", new StandardSQLFunction( "ceil", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "floor", new StandardSQLFunction( "floor", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "round", new StandardSQLFunction( "round" ) );
|
||||
|
||||
registerFunction("datediff", new StandardSQLFunction("datediff", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("timediff", new StandardSQLFunction("timediff", StandardBasicTypes.TIME) );
|
||||
registerFunction( "datediff", new StandardSQLFunction( "datediff", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "timediff", new StandardSQLFunction( "timediff", StandardBasicTypes.TIME ) );
|
||||
|
||||
registerFunction("date", new StandardSQLFunction("date", StandardBasicTypes.DATE) );
|
||||
registerFunction("curdate", new NoArgSQLFunction("curdate", StandardBasicTypes.DATE) );
|
||||
registerFunction("current_date", new NoArgSQLFunction("current_date", StandardBasicTypes.DATE, false) );
|
||||
registerFunction("sys_date", new NoArgSQLFunction("sys_date", StandardBasicTypes.DATE, false) );
|
||||
registerFunction("sysdate", new NoArgSQLFunction("sysdate", StandardBasicTypes.DATE, false) );
|
||||
registerFunction( "date", new StandardSQLFunction( "date", StandardBasicTypes.DATE ) );
|
||||
registerFunction( "curdate", new NoArgSQLFunction( "curdate", StandardBasicTypes.DATE ) );
|
||||
registerFunction( "current_date", new NoArgSQLFunction( "current_date", StandardBasicTypes.DATE, false ) );
|
||||
registerFunction( "sys_date", new NoArgSQLFunction( "sys_date", StandardBasicTypes.DATE, false ) );
|
||||
registerFunction( "sysdate", new NoArgSQLFunction( "sysdate", StandardBasicTypes.DATE, false ) );
|
||||
|
||||
registerFunction("time", new StandardSQLFunction("time", StandardBasicTypes.TIME) );
|
||||
registerFunction("curtime", new NoArgSQLFunction("curtime", StandardBasicTypes.TIME) );
|
||||
registerFunction("current_time", new NoArgSQLFunction("current_time", StandardBasicTypes.TIME, false) );
|
||||
registerFunction("sys_time", new NoArgSQLFunction("sys_time", StandardBasicTypes.TIME, false) );
|
||||
registerFunction("systime", new NoArgSQLFunction("systime", StandardBasicTypes.TIME, false) );
|
||||
registerFunction( "time", new StandardSQLFunction( "time", StandardBasicTypes.TIME ) );
|
||||
registerFunction( "curtime", new NoArgSQLFunction( "curtime", StandardBasicTypes.TIME ) );
|
||||
registerFunction( "current_time", new NoArgSQLFunction( "current_time", StandardBasicTypes.TIME, false ) );
|
||||
registerFunction( "sys_time", new NoArgSQLFunction( "sys_time", StandardBasicTypes.TIME, false ) );
|
||||
registerFunction( "systime", new NoArgSQLFunction( "systime", StandardBasicTypes.TIME, false ) );
|
||||
|
||||
registerFunction("timestamp", new StandardSQLFunction("timestamp", StandardBasicTypes.TIMESTAMP) );
|
||||
registerFunction("current_timestamp", new NoArgSQLFunction("current_timestamp", StandardBasicTypes.TIMESTAMP, false) );
|
||||
registerFunction("sys_timestamp", new NoArgSQLFunction("sys_timestamp", StandardBasicTypes.TIMESTAMP, false) );
|
||||
registerFunction("systimestamp", new NoArgSQLFunction("systimestamp", StandardBasicTypes.TIMESTAMP, false) );
|
||||
registerFunction("localtime", new NoArgSQLFunction("localtime", StandardBasicTypes.TIMESTAMP, false) );
|
||||
registerFunction("localtimestamp", new NoArgSQLFunction("localtimestamp", StandardBasicTypes.TIMESTAMP, false) );
|
||||
registerFunction( "timestamp", new StandardSQLFunction( "timestamp", StandardBasicTypes.TIMESTAMP ) );
|
||||
registerFunction(
|
||||
"current_timestamp", new NoArgSQLFunction(
|
||||
"current_timestamp",
|
||||
StandardBasicTypes.TIMESTAMP,
|
||||
false
|
||||
)
|
||||
);
|
||||
registerFunction(
|
||||
"sys_timestamp", new NoArgSQLFunction(
|
||||
"sys_timestamp",
|
||||
StandardBasicTypes.TIMESTAMP,
|
||||
false
|
||||
)
|
||||
);
|
||||
registerFunction( "systimestamp", new NoArgSQLFunction( "systimestamp", StandardBasicTypes.TIMESTAMP, false ) );
|
||||
registerFunction( "localtime", new NoArgSQLFunction( "localtime", StandardBasicTypes.TIMESTAMP, false ) );
|
||||
registerFunction(
|
||||
"localtimestamp", new NoArgSQLFunction(
|
||||
"localtimestamp",
|
||||
StandardBasicTypes.TIMESTAMP,
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
registerFunction("day", new StandardSQLFunction("day", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("dayofmonth", new StandardSQLFunction("dayofmonth", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("dayofweek", new StandardSQLFunction("dayofweek", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("dayofyear", new StandardSQLFunction("dayofyear", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("from_days", new StandardSQLFunction("from_days", StandardBasicTypes.DATE) );
|
||||
registerFunction("from_unixtime", new StandardSQLFunction("from_unixtime", StandardBasicTypes.TIMESTAMP) );
|
||||
registerFunction("last_day", new StandardSQLFunction("last_day", StandardBasicTypes.DATE) );
|
||||
registerFunction("minute", new StandardSQLFunction("minute", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("month", new StandardSQLFunction("month", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("months_between", new StandardSQLFunction("months_between", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("now", new NoArgSQLFunction("now", StandardBasicTypes.TIMESTAMP) );
|
||||
registerFunction("quarter", new StandardSQLFunction("quarter", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("second", new StandardSQLFunction("second", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("sec_to_time", new StandardSQLFunction("sec_to_time", StandardBasicTypes.TIME) );
|
||||
registerFunction("time_to_sec", new StandardSQLFunction("time_to_sec", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("to_days", new StandardSQLFunction("to_days", StandardBasicTypes.LONG) );
|
||||
registerFunction("unix_timestamp", new StandardSQLFunction("unix_timestamp", StandardBasicTypes.LONG) );
|
||||
registerFunction("utc_date", new NoArgSQLFunction("utc_date", StandardBasicTypes.STRING) );
|
||||
registerFunction("utc_time", new NoArgSQLFunction("utc_time", StandardBasicTypes.STRING) );
|
||||
registerFunction("week", new StandardSQLFunction("week", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("weekday", new StandardSQLFunction("weekday", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("year", new StandardSQLFunction("year", StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "day", new StandardSQLFunction( "day", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "dayofmonth", new StandardSQLFunction( "dayofmonth", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "dayofweek", new StandardSQLFunction( "dayofweek", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "dayofyear", new StandardSQLFunction( "dayofyear", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "from_days", new StandardSQLFunction( "from_days", StandardBasicTypes.DATE ) );
|
||||
registerFunction( "from_unixtime", new StandardSQLFunction( "from_unixtime", StandardBasicTypes.TIMESTAMP ) );
|
||||
registerFunction( "last_day", new StandardSQLFunction( "last_day", StandardBasicTypes.DATE ) );
|
||||
registerFunction( "minute", new StandardSQLFunction( "minute", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "month", new StandardSQLFunction( "month", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "months_between", new StandardSQLFunction( "months_between", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "now", new NoArgSQLFunction( "now", StandardBasicTypes.TIMESTAMP ) );
|
||||
registerFunction( "quarter", new StandardSQLFunction( "quarter", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "second", new StandardSQLFunction( "second", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "sec_to_time", new StandardSQLFunction( "sec_to_time", StandardBasicTypes.TIME ) );
|
||||
registerFunction( "time_to_sec", new StandardSQLFunction( "time_to_sec", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "to_days", new StandardSQLFunction( "to_days", StandardBasicTypes.LONG ) );
|
||||
registerFunction( "unix_timestamp", new StandardSQLFunction( "unix_timestamp", StandardBasicTypes.LONG ) );
|
||||
registerFunction( "utc_date", new NoArgSQLFunction( "utc_date", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "utc_time", new NoArgSQLFunction( "utc_time", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "week", new StandardSQLFunction( "week", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "weekday", new StandardSQLFunction( "weekday", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "year", new StandardSQLFunction( "year", StandardBasicTypes.INTEGER ) );
|
||||
|
||||
registerFunction("hex", new StandardSQLFunction("hex", StandardBasicTypes.STRING) );
|
||||
registerFunction( "hex", new StandardSQLFunction( "hex", StandardBasicTypes.STRING ) );
|
||||
|
||||
registerFunction("octet_length", new StandardSQLFunction("octet_length", StandardBasicTypes.LONG) );
|
||||
registerFunction("bit_length", new StandardSQLFunction("bit_length", StandardBasicTypes.LONG) );
|
||||
registerFunction( "octet_length", new StandardSQLFunction( "octet_length", StandardBasicTypes.LONG ) );
|
||||
registerFunction( "bit_length", new StandardSQLFunction( "bit_length", StandardBasicTypes.LONG ) );
|
||||
|
||||
registerFunction("bit_count", new StandardSQLFunction("bit_count", StandardBasicTypes.LONG) );
|
||||
registerFunction("md5", new StandardSQLFunction("md5", StandardBasicTypes.STRING) );
|
||||
registerFunction( "bit_count", new StandardSQLFunction( "bit_count", StandardBasicTypes.LONG ) );
|
||||
registerFunction( "md5", new StandardSQLFunction( "md5", StandardBasicTypes.STRING ) );
|
||||
|
||||
registerFunction( "concat", new StandardSQLFunction( "concat", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "concat", new StandardSQLFunction( "concat", StandardBasicTypes.STRING ) );
|
||||
|
||||
registerFunction("substring", new StandardSQLFunction("substring", StandardBasicTypes.STRING) );
|
||||
registerFunction("substr", new StandardSQLFunction("substr", StandardBasicTypes.STRING) );
|
||||
registerFunction( "substring", new StandardSQLFunction( "substring", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "substr", new StandardSQLFunction( "substr", StandardBasicTypes.STRING ) );
|
||||
|
||||
registerFunction("length", new StandardSQLFunction("length", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("bit_length",new StandardSQLFunction("bit_length", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("coalesce", new StandardSQLFunction("coalesce") );
|
||||
registerFunction("nullif", new StandardSQLFunction("nullif") );
|
||||
registerFunction("mod", new StandardSQLFunction("mod") );
|
||||
registerFunction( "length", new StandardSQLFunction( "length", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "bit_length", new StandardSQLFunction( "bit_length", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "coalesce", new StandardSQLFunction( "coalesce" ) );
|
||||
registerFunction( "nullif", new StandardSQLFunction( "nullif" ) );
|
||||
registerFunction( "mod", new StandardSQLFunction( "mod" ) );
|
||||
|
||||
registerFunction("power", new StandardSQLFunction("power") );
|
||||
registerFunction("stddev", new StandardSQLFunction("stddev") );
|
||||
registerFunction("variance", new StandardSQLFunction("variance") );
|
||||
registerFunction("trunc", new StandardSQLFunction("trunc") );
|
||||
registerFunction("nvl", new StandardSQLFunction("nvl") );
|
||||
registerFunction("nvl2", new StandardSQLFunction("nvl2") );
|
||||
registerFunction("chr", new StandardSQLFunction("chr", StandardBasicTypes.CHARACTER));
|
||||
registerFunction("to_char", new StandardSQLFunction("to_char", StandardBasicTypes.STRING) );
|
||||
registerFunction("to_date", new StandardSQLFunction("to_date", StandardBasicTypes.TIMESTAMP));
|
||||
registerFunction("instr", new StandardSQLFunction("instr", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("instrb", new StandardSQLFunction("instrb", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("lpad", new StandardSQLFunction("lpad", StandardBasicTypes.STRING) );
|
||||
registerFunction("replace", new StandardSQLFunction("replace", StandardBasicTypes.STRING) );
|
||||
registerFunction("rpad", new StandardSQLFunction("rpad", StandardBasicTypes.STRING) );
|
||||
registerFunction("translate", new StandardSQLFunction("translate", StandardBasicTypes.STRING) );
|
||||
registerFunction( "power", new StandardSQLFunction( "power" ) );
|
||||
registerFunction( "stddev", new StandardSQLFunction( "stddev" ) );
|
||||
registerFunction( "variance", new StandardSQLFunction( "variance" ) );
|
||||
registerFunction( "trunc", new StandardSQLFunction( "trunc" ) );
|
||||
registerFunction( "nvl", new StandardSQLFunction( "nvl" ) );
|
||||
registerFunction( "nvl2", new StandardSQLFunction( "nvl2" ) );
|
||||
registerFunction( "chr", new StandardSQLFunction( "chr", StandardBasicTypes.CHARACTER ) );
|
||||
registerFunction( "to_char", new StandardSQLFunction( "to_char", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "to_date", new StandardSQLFunction( "to_date", StandardBasicTypes.TIMESTAMP ) );
|
||||
registerFunction( "instr", new StandardSQLFunction( "instr", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "instrb", new StandardSQLFunction( "instrb", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "lpad", new StandardSQLFunction( "lpad", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "replace", new StandardSQLFunction( "replace", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "rpad", new StandardSQLFunction( "rpad", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "translate", new StandardSQLFunction( "translate", StandardBasicTypes.STRING ) );
|
||||
|
||||
registerFunction("add_months", new StandardSQLFunction("add_months", StandardBasicTypes.DATE) );
|
||||
registerFunction("user", new NoArgSQLFunction("user", StandardBasicTypes.STRING, false) );
|
||||
registerFunction("rownum", new NoArgSQLFunction("rownum", StandardBasicTypes.LONG, false) );
|
||||
registerFunction("concat", new VarArgsSQLFunction(StandardBasicTypes.STRING, "", "||", ""));
|
||||
registerFunction( "add_months", new StandardSQLFunction( "add_months", StandardBasicTypes.DATE ) );
|
||||
registerFunction( "user", new NoArgSQLFunction( "user", StandardBasicTypes.STRING, false ) );
|
||||
registerFunction( "rownum", new NoArgSQLFunction( "rownum", StandardBasicTypes.LONG, false ) );
|
||||
registerFunction( "concat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "", "||", "" ) );
|
||||
|
||||
registerKeyword( "TYPE" );
|
||||
registerKeyword( "YEAR" );
|
||||
registerKeyword( "MONTH" );
|
||||
registerKeyword( "ALIAS" );
|
||||
registerKeyword( "VALUE" );
|
||||
registerKeyword( "FIRST" );
|
||||
registerKeyword( "ROLE" );
|
||||
registerKeyword( "CLASS" );
|
||||
registerKeyword( "BIT" );
|
||||
registerKeyword( "TIME" );
|
||||
registerKeyword( "QUERY" );
|
||||
registerKeyword( "DATE" );
|
||||
registerKeyword( "USER" );
|
||||
registerKeyword( "ACTION" );
|
||||
registerKeyword( "SYS_USER" );
|
||||
registerKeyword( "ZONE" );
|
||||
registerKeyword( "LANGUAGE" );
|
||||
registerKeyword( "DICTIONARY" );
|
||||
registerKeyword( "DATA" );
|
||||
registerKeyword( "TEST" );
|
||||
registerKeyword( "SUPERCLASS" );
|
||||
registerKeyword( "SECTION" );
|
||||
registerKeyword( "LOWER" );
|
||||
registerKeyword( "LIST" );
|
||||
registerKeyword( "OID" );
|
||||
registerKeyword( "DAY" );
|
||||
registerKeyword( "IF" );
|
||||
registerKeyword( "ATTRIBUTE" );
|
||||
registerKeyword( "STRING" );
|
||||
registerKeyword( "SEARCH" );
|
||||
}
|
||||
|
||||
registerKeyword( "TYPE" );
|
||||
registerKeyword( "YEAR" );
|
||||
registerKeyword( "MONTH" );
|
||||
registerKeyword( "ALIAS" );
|
||||
registerKeyword( "VALUE" );
|
||||
registerKeyword( "FIRST" );
|
||||
registerKeyword( "ROLE" );
|
||||
registerKeyword( "CLASS" );
|
||||
registerKeyword( "BIT" );
|
||||
registerKeyword( "TIME" );
|
||||
registerKeyword( "QUERY" );
|
||||
registerKeyword( "DATE" );
|
||||
registerKeyword( "USER" );
|
||||
registerKeyword( "ACTION" );
|
||||
registerKeyword( "SYS_USER" );
|
||||
registerKeyword( "ZONE" );
|
||||
registerKeyword( "LANGUAGE" );
|
||||
registerKeyword( "DICTIONARY" );
|
||||
registerKeyword( "DATA" );
|
||||
registerKeyword( "TEST" );
|
||||
registerKeyword( "SUPERCLASS" );
|
||||
registerKeyword( "SECTION" );
|
||||
registerKeyword( "LOWER" );
|
||||
registerKeyword( "LIST" );
|
||||
registerKeyword( "OID" );
|
||||
registerKeyword( "DAY" );
|
||||
registerKeyword( "IF" );
|
||||
registerKeyword( "ATTRIBUTE" );
|
||||
registerKeyword( "STRING" );
|
||||
registerKeyword( "SEARCH" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsIdentityColumns() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentityInsertString() {
|
||||
return "NULL";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean supportsColumnCheck() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean supportsPooledSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getIdentitySelectString() {
|
||||
return "select last_insert_id()";
|
||||
}
|
||||
@Override
|
||||
public String getIdentitySelectString() {
|
||||
return "select last_insert_id()";
|
||||
}
|
||||
|
||||
protected String getIdentityColumnString() {
|
||||
return "not null auto_increment"; //starts with 1, implicitly
|
||||
}
|
||||
@Override
|
||||
protected String getIdentityColumnString() {
|
||||
//starts with 1, implicitly
|
||||
return "not null auto_increment";
|
||||
}
|
||||
|
||||
/*
|
||||
* CUBRID supports "ADD [COLUMN | ATTRIBUTE]"
|
||||
*/
|
||||
public String getAddColumnString() {
|
||||
return "add";
|
||||
}
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
return "add";
|
||||
}
|
||||
|
||||
public String getSequenceNextValString(String sequenceName) {
|
||||
return "select " + sequenceName + ".next_value from table({1}) as T(X)";
|
||||
}
|
||||
@Override
|
||||
public String getSequenceNextValString(String sequenceName) {
|
||||
return "select " + sequenceName + ".next_value from table({1}) as T(X)";
|
||||
}
|
||||
|
||||
public String getCreateSequenceString(String sequenceName) {
|
||||
return "create serial " + sequenceName;
|
||||
}
|
||||
@Override
|
||||
public String getCreateSequenceString(String sequenceName) {
|
||||
return "create serial " + sequenceName;
|
||||
}
|
||||
|
||||
public String getDropSequenceString(String sequenceName) {
|
||||
return "drop serial " + sequenceName;
|
||||
}
|
||||
@Override
|
||||
public String getDropSequenceString(String sequenceName) {
|
||||
return "drop serial " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDropForeignKeyString() {
|
||||
return " drop foreign key ";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean qualifyIndexName() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsSequences() {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean supportsSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsExistsInSelect() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getQuerySequencesString() {
|
||||
return "select name from db_serial";
|
||||
}
|
||||
@Override
|
||||
public String getQuerySequencesString() {
|
||||
return "select name from db_serial";
|
||||
}
|
||||
|
||||
/**
|
||||
* The character specific to this dialect used to close a quoted identifier.
|
||||
* CUBRID supports square brackets (MSSQL style), backticks (MySQL style),
|
||||
* as well as double quotes (Oracle style).
|
||||
*
|
||||
* @return The dialect's specific open quote character.
|
||||
*/
|
||||
public char openQuote() {
|
||||
return '[';
|
||||
}
|
||||
@Override
|
||||
public char openQuote() {
|
||||
return '[';
|
||||
}
|
||||
|
||||
public char closeQuote() {
|
||||
return ']';
|
||||
}
|
||||
@Override
|
||||
public char closeQuote() {
|
||||
return ']';
|
||||
}
|
||||
|
||||
public String getForUpdateString() {
|
||||
return " ";
|
||||
}
|
||||
@Override
|
||||
public String getForUpdateString() {
|
||||
return " ";
|
||||
}
|
||||
|
||||
public boolean supportsUnionAll() {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean supportsUnionAll() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean supportsCurrentTimestampSelection() {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean supportsCurrentTimestampSelection() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getCurrentTimestampSelectString() {
|
||||
return "select now()";
|
||||
}
|
||||
@Override
|
||||
public String getCurrentTimestampSelectString() {
|
||||
return "select now()";
|
||||
}
|
||||
|
||||
public boolean isCurrentTimestampSelectStringCallable() {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean isCurrentTimestampSelectStringCallable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsEmptyInList() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsEmptyInList() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsIfExistsBeforeTableName() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTupleDistinctCounts() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LimitHandler buildLimitHandler(String sql, RowSelection selection) {
|
||||
return new CUBRIDLimitHandler( this, sql, selection );
|
||||
}
|
||||
return new CUBRIDLimitHandler( this, sql, selection );
|
||||
}
|
||||
}
|
||||
|
@ -58,15 +58,11 @@
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
|
||||
/**
|
||||
* Caché 2007.1 dialect. This class is required in order to use Hibernate with Intersystems Caché SQL.<br>
|
||||
* <br>
|
||||
* Compatible with Caché 2007.1.
|
||||
* <br>
|
||||
* <head>
|
||||
* <title>Caché and Hibernate</title>
|
||||
* </head>
|
||||
* <body>
|
||||
* <h1>Caché and Hibernate</h1>
|
||||
* Caché 2007.1 dialect.
|
||||
*
|
||||
* This class is required in order to use Hibernate with Intersystems Caché SQL. Compatible with
|
||||
* Caché 2007.1.
|
||||
*
|
||||
* <h2>PREREQUISITES</h2>
|
||||
* These setup instructions assume that both Caché and Hibernate are installed and operational.
|
||||
* <br>
|
||||
@ -144,11 +140,9 @@
|
||||
* </tr>
|
||||
* </table>
|
||||
* <p/>
|
||||
* <dl>
|
||||
* <dt><b>Note 1</b></dt>
|
||||
* <dd>Please contact your administrator for the userid and password you should use when attempting access via JDBC.
|
||||
* By default, these are chosen to be "_SYSTEM" and "SYS" respectively as noted in the SQL standard.</dd>
|
||||
* </dl>
|
||||
* <b>NOTE:</b> Please contact your administrator for the userid and password you should use when
|
||||
* attempting access via JDBC. By default, these are chosen to be "_SYSTEM" and "SYS" respectively
|
||||
* as noted in the SQL standard.
|
||||
* <br>
|
||||
* <h2>CACHÉ VERSION URL</h2>
|
||||
* This is the standard URL for the JDBC driver.
|
||||
@ -239,16 +233,14 @@ protected final void commonRegistration() {
|
||||
registerColumnType( Types.DOUBLE, "double" );
|
||||
registerColumnType( Types.FLOAT, "float" );
|
||||
registerColumnType( Types.INTEGER, "integer" );
|
||||
registerColumnType( Types.LONGVARBINARY, "longvarbinary" ); // binary %Stream
|
||||
registerColumnType( Types.LONGVARCHAR, "longvarchar" ); // character %Stream
|
||||
registerColumnType( Types.LONGVARBINARY, "longvarbinary" );
|
||||
registerColumnType( Types.LONGVARCHAR, "longvarchar" );
|
||||
registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
|
||||
registerColumnType( Types.REAL, "real" );
|
||||
registerColumnType( Types.SMALLINT, "smallint" );
|
||||
registerColumnType( Types.TIMESTAMP, "timestamp" );
|
||||
registerColumnType( Types.TIME, "time" );
|
||||
registerColumnType( Types.TINYINT, "tinyint" );
|
||||
// TBD should this be varbinary($1)?
|
||||
// registerColumnType(Types.VARBINARY, "binary($1)");
|
||||
registerColumnType( Types.VARBINARY, "longvarbinary" );
|
||||
registerColumnType( Types.VARCHAR, "varchar($l)" );
|
||||
registerColumnType( Types.BLOB, "longvarbinary" );
|
||||
@ -256,7 +248,6 @@ protected final void commonRegistration() {
|
||||
|
||||
getDefaultProperties().setProperty( Environment.USE_STREAMS_FOR_BINARY, "false" );
|
||||
getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
|
||||
//getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH);
|
||||
|
||||
getDefaultProperties().setProperty( Environment.USE_SQL_COMMENTS, "false" );
|
||||
|
||||
@ -267,7 +258,6 @@ protected final void commonRegistration() {
|
||||
registerFunction( "asin", new StandardJDBCEscapeFunction( "asin", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "atan", new StandardJDBCEscapeFunction( "atan", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "bit_length", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "($length(?1)*8)" ) );
|
||||
// hibernate impelemnts cast in Dialect.java
|
||||
registerFunction( "ceiling", new StandardSQLFunction( "ceiling", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "char", new StandardJDBCEscapeFunction( "char", StandardBasicTypes.CHARACTER ) );
|
||||
registerFunction( "character_length", new StandardSQLFunction( "character_length", StandardBasicTypes.INTEGER ) );
|
||||
@ -311,9 +301,6 @@ protected final void commonRegistration() {
|
||||
registerFunction( "left", new StandardJDBCEscapeFunction( "left", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "len", new StandardSQLFunction( "len", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "$length", new VarArgsSQLFunction( "$length(", ",", ")" ) );
|
||||
// aggregate functions shouldn't be registered, right?
|
||||
//registerFunction( "list", new StandardSQLFunction("list",StandardBasicTypes.STRING) );
|
||||
// stopped on $list
|
||||
registerFunction( "$list", new VarArgsSQLFunction( "$list(", ",", ")" ) );
|
||||
registerFunction( "$listdata", new VarArgsSQLFunction( "$listdata(", ",", ")" ) );
|
||||
registerFunction( "$listfind", new VarArgsSQLFunction( "$listfind(", ",", ")" ) );
|
||||
@ -391,21 +378,20 @@ protected final void register71Functions() {
|
||||
|
||||
// DDL support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public boolean hasAlterTable() {
|
||||
// Does this dialect support the ALTER TABLE syntax?
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean qualifyIndexName() {
|
||||
// Do we need to qualify index names with the schema name?
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The syntax used to add a foreign key constraint to a table.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("StringBufferReplaceableByString")
|
||||
public String getAddForeignKeyConstraintString(
|
||||
String constraintName,
|
||||
String[] foreignKey,
|
||||
@ -419,97 +405,120 @@ public String getAddForeignKeyConstraintString(
|
||||
.append( " FOREIGN KEY " )
|
||||
.append( constraintName )
|
||||
.append( " (" )
|
||||
.append( StringHelper.join( ", ", foreignKey ) ) // identifier-commalist
|
||||
.append( StringHelper.join( ", ", foreignKey ) )
|
||||
.append( ") REFERENCES " )
|
||||
.append( referencedTable )
|
||||
.append( " (" )
|
||||
.append( StringHelper.join( ", ", primaryKey ) ) // identifier-commalist
|
||||
.append( StringHelper.join( ", ", primaryKey ) )
|
||||
.append( ") " )
|
||||
.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this dialect support check constraints?
|
||||
*
|
||||
* @return {@code false} (Cache does not support check constraints)
|
||||
*/
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public boolean supportsCheck() {
|
||||
// Does this dialect support check constraints?
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
// The syntax used to add a column to a table
|
||||
return " add column";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCascadeConstraintsString() {
|
||||
// Completely optional cascading drop clause.
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dropConstraints() {
|
||||
// Do we need to drop constraints before dropping tables in this dialect?
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCascadeDelete() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSelfReferentialForeignKeyBug() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// temporary table support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public boolean supportsTemporaryTables() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateTemporaryTableName(String baseTableName) {
|
||||
String name = super.generateTemporaryTableName( baseTableName );
|
||||
final String name = super.generateTemporaryTableName( baseTableName );
|
||||
return name.length() > 25 ? name.substring( 1, 25 ) : name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateTemporaryTableString() {
|
||||
return "create global temporary table";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean performTemporaryTableDDLInIsolation() {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateTemporaryTablePostfix() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dropTemporaryTableAfterUse() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// IDENTITY support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public boolean supportsIdentityColumns() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class getNativeIdentifierGeneratorClass() {
|
||||
return IdentityGenerator.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDataTypeInIdentityColumn() {
|
||||
// Whether this dialect has an Identity clause added to the data type or a completely seperate identity
|
||||
// data type
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentityColumnString() throws MappingException {
|
||||
// The keyword used to specify an identity column, if identity column key generation is supported.
|
||||
return "identity";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentitySelectString() {
|
||||
return "SELECT LAST_IDENTITY() FROM %TSQL_sys.snf";
|
||||
}
|
||||
|
||||
// SEQUENCE support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public boolean supportsSequences() {
|
||||
return false;
|
||||
}
|
||||
@ -539,25 +548,12 @@ public boolean supportsSequences() {
|
||||
|
||||
// lock acquisition support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
public boolean supportsForUpdate() {
|
||||
// Does this dialect support the FOR UPDATE syntax?
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsForUpdateOf() {
|
||||
// Does this dialect support FOR UPDATE OF, allowing particular rows to be locked?
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsForUpdateNowait() {
|
||||
// Does this dialect support the Oracle-style FOR UPDATE NOWAIT syntax?
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsOuterJoinForUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
|
||||
// InterSystems Cache' does not current support "SELECT ... FOR UPDATE" syntax...
|
||||
// Set your transaction mode to READ_COMMITTED before using
|
||||
@ -586,28 +582,40 @@ else if ( lockMode.greaterThan( LockMode.READ ) ) {
|
||||
|
||||
// LIMIT support (ala TOP) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean supportsLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean supportsLimitOffset() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean supportsVariableLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean bindLimitParametersFirst() {
|
||||
// Does the LIMIT clause come at the start of the SELECT statement, rather than at the end?
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean useMaxForLimit() {
|
||||
// Does the LIMIT clause take a "maximum" row number instead of a total number of returned rows?
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public String getLimitString(String sql, boolean hasOffset) {
|
||||
if ( hasOffset ) {
|
||||
throw new UnsupportedOperationException( "query result offset is not supported" );
|
||||
@ -615,7 +623,7 @@ public String getLimitString(String sql, boolean hasOffset) {
|
||||
|
||||
// This does not support the Cache SQL 'DISTINCT BY (comma-list)' extensions,
|
||||
// but this extension is not supported through Hibernate anyway.
|
||||
int insertionPoint = sql.startsWith( "select distinct" ) ? 15 : 6;
|
||||
final int insertionPoint = sql.startsWith( "select distinct" ) ? 15 : 6;
|
||||
|
||||
return new StringBuilder( sql.length() + 8 )
|
||||
.append( sql )
|
||||
@ -625,53 +633,59 @@ public String getLimitString(String sql, boolean hasOffset) {
|
||||
|
||||
// callable statement support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
|
||||
return col;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getResultSet(CallableStatement ps) throws SQLException {
|
||||
ps.execute();
|
||||
return ( ResultSet ) ps.getObject( 1 );
|
||||
return (ResultSet) ps.getObject( 1 );
|
||||
}
|
||||
|
||||
// miscellaneous support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public String getLowercaseFunction() {
|
||||
// The name of the SQL function that transforms a string to lowercase
|
||||
return "lower";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNullColumnString() {
|
||||
// The keyword used to specify a nullable column.
|
||||
return " null";
|
||||
}
|
||||
|
||||
@Override
|
||||
public JoinFragment createOuterJoinFragment() {
|
||||
// Create an OuterJoinGenerator for this dialect.
|
||||
return new CacheJoinFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNoColumnsInsertString() {
|
||||
// The keyword used to insert a row without specifying
|
||||
// any column values
|
||||
return " default values";
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
|
||||
return new CacheSQLExceptionConversionDelegate( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
|
||||
return EXTRACTER;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Cache ViolatedConstraintNameExtracter.
|
||||
*/
|
||||
public static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
|
||||
/**
|
||||
* Extract the name of the violated constraint from the given SQLException.
|
||||
*
|
||||
* @param sqle The exception that was the result of the constraint violation.
|
||||
* @return The extracted constraint name.
|
||||
*/
|
||||
@Override
|
||||
public String extractConstraintName(SQLException sqle) {
|
||||
return extractUsingTemplate( "constraint (", ") violated", sqle.getMessage() );
|
||||
}
|
||||
@ -680,14 +694,17 @@ public String extractConstraintName(SQLException sqle) {
|
||||
|
||||
// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public boolean supportsEmptyInList() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areStringComparisonsCaseInsensitive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() {
|
||||
return false;
|
||||
}
|
||||
|
@ -42,6 +42,8 @@ public interface ColumnAliasExtractor {
|
||||
* @param position The column position
|
||||
*
|
||||
* @return The alias
|
||||
*
|
||||
* @throws SQLException Indicates a problem accessing the JDBC ResultSetMetaData
|
||||
*/
|
||||
public String extractColumnAlias(ResultSetMetaData metaData, int position) throws SQLException;
|
||||
|
||||
@ -58,6 +60,7 @@ public String extractColumnAlias(ResultSetMetaData metaData, int position) throw
|
||||
/**
|
||||
* An extractor which uses {@link ResultSetMetaData#getColumnName}
|
||||
*/
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public static final ColumnAliasExtractor COLUMN_NAME_EXTRACTOR = new ColumnAliasExtractor() {
|
||||
@Override
|
||||
public String extractColumnAlias(ResultSetMetaData metaData, int position) throws SQLException {
|
||||
|
@ -31,31 +31,38 @@
|
||||
* @author Kristoffer Dyrkorn
|
||||
*/
|
||||
public class DB2390Dialect extends DB2Dialect {
|
||||
|
||||
@Override
|
||||
public boolean supportsSequences() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentitySelectString() {
|
||||
return "select identity_val_local() from sysibm.sysdummy1";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean supportsLimitOffset() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useMaxForLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsVariableLimit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLimitString(String sql, int offset, int limit) {
|
||||
if ( offset > 0 ) {
|
||||
throw new UnsupportedOperationException( "query result offset is not supported" );
|
||||
@ -63,12 +70,7 @@ public String getLimitString(String sql, int offset, int limit) {
|
||||
if ( limit == 0 ) {
|
||||
return sql;
|
||||
}
|
||||
return new StringBuilder( sql.length() + 40 )
|
||||
.append( sql )
|
||||
.append( " fetch first " )
|
||||
.append( limit )
|
||||
.append( " rows only " )
|
||||
.toString();
|
||||
return sql + " fetch first " + limit + " rows only ";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,6 @@
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
|
||||
/**
|
||||
* An SQL dialect for DB2/400. This class provides support for DB2 Universal Database for iSeries,
|
||||
* also known as DB2/400.
|
||||
@ -31,31 +30,38 @@
|
||||
* @author Peter DeGregorio (pdegregorio)
|
||||
*/
|
||||
public class DB2400Dialect extends DB2Dialect {
|
||||
|
||||
@Override
|
||||
public boolean supportsSequences() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentitySelectString() {
|
||||
return "select identity_val_local() from sysibm.sysdummy1";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean supportsLimitOffset() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useMaxForLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsVariableLimit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLimitString(String sql, int offset, int limit) {
|
||||
if ( offset > 0 ) {
|
||||
throw new UnsupportedOperationException( "query result offset is not supported" );
|
||||
@ -63,15 +69,11 @@ public String getLimitString(String sql, int offset, int limit) {
|
||||
if ( limit == 0 ) {
|
||||
return sql;
|
||||
}
|
||||
return new StringBuilder( sql.length() + 40 )
|
||||
.append( sql )
|
||||
.append( " fetch first " )
|
||||
.append( limit )
|
||||
.append( " rows only " )
|
||||
.toString();
|
||||
return sql + " fetch first " + limit + " rows only ";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForUpdateString() {
|
||||
return " for update with rs";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,9 +50,11 @@
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class DB2Dialect extends Dialect {
|
||||
|
||||
private final UniqueDelegate uniqueDelegate;
|
||||
|
||||
/**
|
||||
* Constructs a DB2Dialect
|
||||
*/
|
||||
public DB2Dialect() {
|
||||
super();
|
||||
registerColumnType( Types.BIT, "smallint" );
|
||||
@ -181,117 +183,137 @@ public DB2Dialect() {
|
||||
|
||||
uniqueDelegate = new DB2UniqueDelegate( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLowercaseFunction() {
|
||||
return "lcase";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
return "add column";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dropConstraints() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsIdentityColumns() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentitySelectString() {
|
||||
return "values identity_val_local()";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentityColumnString() {
|
||||
return "generated by default as identity"; //not null ... (start with 1) is implicit
|
||||
return "generated by default as identity";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentityInsertString() {
|
||||
return "default";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSequenceNextValString(String sequenceName) {
|
||||
return "values nextval for " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateSequenceString(String sequenceName) {
|
||||
return "create sequence " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDropSequenceString(String sequenceName) {
|
||||
return "drop sequence " + sequenceName + " restrict";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPooledSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQuerySequencesString() {
|
||||
return "select seqname from sysibm.syssequences";
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean supportsLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean supportsVariableLimit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public String getLimitString(String sql, int offset, int limit) {
|
||||
if ( offset == 0 ) {
|
||||
return sql + " fetch first " + limit + " rows only";
|
||||
}
|
||||
StringBuilder pagingSelect = new StringBuilder( sql.length() + 200 )
|
||||
.append(
|
||||
"select * from ( select inner2_.*, rownumber() over(order by order of inner2_) as rownumber_ from ( "
|
||||
)
|
||||
.append( sql ) //nest the main query in an outer select
|
||||
.append( " fetch first " )
|
||||
.append( limit )
|
||||
.append( " rows only ) as inner2_ ) as inner1_ where rownumber_ > " )
|
||||
.append( offset )
|
||||
.append( " order by rownumber_" );
|
||||
return pagingSelect.toString();
|
||||
//nest the main query in an outer select
|
||||
return "select * from ( select inner2_.*, rownumber() over(order by order of inner2_) as rownumber_ from ( "
|
||||
+ sql + " fetch first " + limit + " rows only ) as inner2_ ) as inner1_ where rownumber_ > "
|
||||
+ offset + " order by rownumber_";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p/>
|
||||
*
|
||||
* DB2 does have a one-based offset, however this was actually already handled in the limit string building
|
||||
* (the '?+1' bit). To not mess up inheritors, I'll leave that part alone and not touch the offset here.
|
||||
*
|
||||
* @param zeroBasedFirstResult The user-supplied, zero-based offset
|
||||
*
|
||||
* @return zeroBasedFirstResult
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public int convertToFirstRowValue(int zeroBasedFirstResult) {
|
||||
return zeroBasedFirstResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public String getForUpdateString() {
|
||||
return " for read only with rs use and keep update locks";
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean useMaxForLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsOuterJoinForUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsExistsInSelect() {
|
||||
return false;
|
||||
}
|
||||
//as far as I know, DB2 doesn't support this
|
||||
|
||||
@Override
|
||||
public boolean supportsLockTimeouts() {
|
||||
//as far as I know, DB2 doesn't support this
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectClauseNullString(int sqlType) {
|
||||
String literal;
|
||||
@ -315,32 +337,16 @@ public String getSelectClauseNullString(int sqlType) {
|
||||
return "nullif(" + literal + ',' + literal + ')';
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println( new DB2Dialect().getLimitString( "/*foo*/ select * from foos", true ) );
|
||||
System.out.println( new DB2Dialect().getLimitString( "/*foo*/ select distinct * from foos", true ) );
|
||||
System.out
|
||||
.println(
|
||||
new DB2Dialect().getLimitString(
|
||||
"/*foo*/ select * from foos foo order by foo.bar, foo.baz",
|
||||
true
|
||||
)
|
||||
);
|
||||
System.out
|
||||
.println(
|
||||
new DB2Dialect().getLimitString(
|
||||
"/*foo*/ select distinct * from foos foo order by foo.bar, foo.baz",
|
||||
true
|
||||
)
|
||||
);
|
||||
}
|
||||
@Override
|
||||
public boolean supportsUnionAll() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
|
||||
return col;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getResultSet(CallableStatement ps) throws SQLException {
|
||||
boolean isResultSet = ps.execute();
|
||||
@ -348,39 +354,45 @@ public ResultSet getResultSet(CallableStatement ps) throws SQLException {
|
||||
while ( !isResultSet && ps.getUpdateCount() != -1 ) {
|
||||
isResultSet = ps.getMoreResults();
|
||||
}
|
||||
ResultSet rs = ps.getResultSet();
|
||||
// You may still have other ResultSets or update counts left to process here
|
||||
// but you can't do it now or the ResultSet you just got will be closed
|
||||
return rs;
|
||||
|
||||
return ps.getResultSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCommentOn() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTemporaryTables() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateTemporaryTableString() {
|
||||
return "declare global temporary table";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateTemporaryTablePostfix() {
|
||||
return "not logged";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateTemporaryTableName(String baseTableName) {
|
||||
return "session." + super.generateTemporaryTableName( baseTableName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCurrentTimestampSelection() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentTimestampSelectString() {
|
||||
return "values current timestamp";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurrentTimestampSelectStringCallable() {
|
||||
return false;
|
||||
@ -389,10 +401,8 @@ public boolean isCurrentTimestampSelectStringCallable() {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p/>
|
||||
* DB2 is know to support parameters in the <tt>SELECT</tt> clause, but only in casted form
|
||||
* NOTE : DB2 is know to support parameters in the <tt>SELECT</tt> clause, but only in casted form
|
||||
* (see {@link #requiresCastingOfParametersInSelectClause()}).
|
||||
*
|
||||
* @return True.
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsParametersInInsertSelect() {
|
||||
@ -400,38 +410,45 @@ public boolean supportsParametersInInsertSelect() {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p/>
|
||||
* DB2 in fact does require that parameters appearing in the select clause be wrapped in cast() calls
|
||||
* to tell the DB parser the type of the select value.
|
||||
*
|
||||
* @return True.
|
||||
*/
|
||||
@Override
|
||||
public boolean requiresCastingOfParametersInSelectClause() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() {
|
||||
return false;
|
||||
}
|
||||
|
||||
//DB2 v9.1 doesn't support 'cross join' syntax
|
||||
@Override
|
||||
public String getCrossJoinSeparator() {
|
||||
//DB2 v9.1 doesn't support 'cross join' syntax
|
||||
return ", ";
|
||||
}
|
||||
|
||||
|
||||
// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public boolean supportsEmptyInList() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLobValueChangePropogation() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesReadCommittedCauseWritersToBlockReaders() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTupleDistinctCounts() {
|
||||
return false;
|
||||
|
@ -22,26 +22,29 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* A Dialect for accessing Oracle through DataDirect driver
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class DataDirectOracle9Dialect extends Oracle9Dialect {
|
||||
|
||||
@Override
|
||||
public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
|
||||
return col; // sql server just returns automatically
|
||||
}
|
||||
|
||||
public ResultSet getResultSet(CallableStatement ps) throws SQLException {
|
||||
boolean isResultSet = ps.execute();
|
||||
// This assumes you will want to ignore any update counts
|
||||
while (!isResultSet && ps.getUpdateCount() != -1) {
|
||||
isResultSet = ps.getMoreResults();
|
||||
}
|
||||
ResultSet rs = ps.getResultSet();
|
||||
// You may still have other ResultSets or update counts left to process here
|
||||
// but you can't do it now or the ResultSet you just got will be closed
|
||||
return rs;
|
||||
return col;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getResultSet(CallableStatement ps) throws SQLException {
|
||||
boolean isResultSet = ps.execute();
|
||||
// This assumes you will want to ignore any update counts
|
||||
while (!isResultSet && ps.getUpdateCount() != -1) {
|
||||
isResultSet = ps.getMoreResults();
|
||||
}
|
||||
|
||||
return ps.getResultSet();
|
||||
}
|
||||
}
|
||||
|
@ -48,28 +48,36 @@
|
||||
*/
|
||||
@Deprecated
|
||||
public class DerbyDialect extends DB2Dialect {
|
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, DerbyDialect.class.getName());
|
||||
@SuppressWarnings("deprecation")
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
DerbyDialect.class.getName()
|
||||
);
|
||||
|
||||
private int driverVersionMajor;
|
||||
private int driverVersionMinor;
|
||||
|
||||
/**
|
||||
* Constructs a DerbyDialect
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public DerbyDialect() {
|
||||
super();
|
||||
if (this.getClass() == DerbyDialect.class) {
|
||||
if ( this.getClass() == DerbyDialect.class ) {
|
||||
LOG.deprecatedDerbyDialect();
|
||||
}
|
||||
|
||||
registerFunction( "concat", new DerbyConcatFunction() );
|
||||
registerFunction( "trim", new AnsiTrimFunction() );
|
||||
registerColumnType( Types.BLOB, "blob" );
|
||||
determineDriverVersion();
|
||||
registerColumnType( Types.BLOB, "blob" );
|
||||
determineDriverVersion();
|
||||
|
||||
if ( driverVersionMajor > 10 || ( driverVersionMajor == 10 && driverVersionMinor >= 7 ) ) {
|
||||
registerColumnType( Types.BOOLEAN, "boolean" );
|
||||
}
|
||||
if ( driverVersionMajor > 10 || ( driverVersionMajor == 10 && driverVersionMinor >= 7 ) ) {
|
||||
registerColumnType( Types.BOOLEAN, "boolean" );
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "UnnecessaryUnboxing" })
|
||||
@SuppressWarnings({"UnnecessaryUnboxing", "unchecked"})
|
||||
private void determineDriverVersion() {
|
||||
try {
|
||||
// locate the derby sysinfo class and query its version info
|
||||
@ -91,25 +99,22 @@ private boolean isTenPointFiveReleaseOrNewer() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCrossJoinSeparator() {
|
||||
public String getCrossJoinSeparator() {
|
||||
return ", ";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the case statement modified for Cloudscape.
|
||||
*/
|
||||
@Override
|
||||
public CaseFragment createCaseFragment() {
|
||||
public CaseFragment createCaseFragment() {
|
||||
return new DerbyCaseFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dropConstraints() {
|
||||
return true;
|
||||
public boolean dropConstraints() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSequences() {
|
||||
public boolean supportsSequences() {
|
||||
// technically sequence support was added in 10.6.1.0...
|
||||
//
|
||||
// The problem though is that I am not exactly sure how to differentiate 10.6.1.0 from any other 10.6.x release.
|
||||
@ -134,33 +139,34 @@ public String getSequenceNextValString(String sequenceName) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLimit() {
|
||||
public boolean supportsLimit() {
|
||||
return isTenPointFiveReleaseOrNewer();
|
||||
}
|
||||
|
||||
//HHH-4531
|
||||
@Override
|
||||
public boolean supportsCommentOn() {
|
||||
public boolean supportsCommentOn() {
|
||||
//HHH-4531
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLimitOffset() {
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean supportsLimitOffset() {
|
||||
return isTenPointFiveReleaseOrNewer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForUpdateString() {
|
||||
return " for update with rs";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWriteLockString(int timeout) {
|
||||
public String getForUpdateString() {
|
||||
return " for update with rs";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReadLockString(int timeout) {
|
||||
public String getWriteLockString(int timeout) {
|
||||
return " for update with rs";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReadLockString(int timeout) {
|
||||
return " for read only with rs";
|
||||
}
|
||||
|
||||
@ -179,9 +185,8 @@ public String getReadLockString(int timeout) {
|
||||
* </pre>
|
||||
*/
|
||||
@Override
|
||||
public String getLimitString(String query, final int offset, final int limit) {
|
||||
StringBuilder sb = new StringBuilder(query.length() + 50);
|
||||
|
||||
public String getLimitString(String query, final int offset, final int limit) {
|
||||
final StringBuilder sb = new StringBuilder(query.length() + 50);
|
||||
final String normalizedSelect = query.toLowerCase().trim();
|
||||
final int forUpdateIndex = normalizedSelect.lastIndexOf( "for update") ;
|
||||
|
||||
@ -215,7 +220,7 @@ else if ( hasWithClause( normalizedSelect ) ) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsVariableLimit() {
|
||||
public boolean supportsVariableLimit() {
|
||||
// we bind the limit and offset values directly into the sql...
|
||||
return false;
|
||||
}
|
||||
@ -237,20 +242,20 @@ private int getWithIndex(String querySelect) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQuerySequencesString() {
|
||||
return null ;
|
||||
public String getQuerySequencesString() {
|
||||
return null ;
|
||||
}
|
||||
|
||||
|
||||
// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public boolean supportsLobValueChangePropogation() {
|
||||
public boolean supportsLobValueChangePropogation() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsUnboundedLobLocatorMaterialization() {
|
||||
public boolean supportsUnboundedLobLocatorMaterialization() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,11 @@
|
||||
* @author Simon Johnston
|
||||
* @author Scott Marlow
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class DerbyTenFiveDialect extends DerbyDialect {
|
||||
/**
|
||||
* Constructs a DerbyTenFiveDialect
|
||||
*/
|
||||
public DerbyTenFiveDialect() {
|
||||
super();
|
||||
registerFunction( "concat", new DerbyConcatFunction() );
|
||||
|
@ -26,14 +26,21 @@
|
||||
import java.sql.Types;
|
||||
|
||||
/**
|
||||
* Dialect for Derby 10.7
|
||||
*
|
||||
* @author Strong Liu
|
||||
*/
|
||||
public class DerbyTenSevenDialect extends DerbyTenSixDialect{
|
||||
public DerbyTenSevenDialect() {
|
||||
registerColumnType( Types.BOOLEAN, "boolean" );
|
||||
}
|
||||
public class DerbyTenSevenDialect extends DerbyTenSixDialect {
|
||||
/**
|
||||
* Constructs a DerbyTenSevenDialect
|
||||
*/
|
||||
public DerbyTenSevenDialect() {
|
||||
super();
|
||||
registerColumnType( Types.BOOLEAN, "boolean" );
|
||||
}
|
||||
|
||||
public String toBooleanValueString(boolean bool) {
|
||||
return String.valueOf(bool);
|
||||
}
|
||||
@Override
|
||||
public String toBooleanValueString(boolean bool) {
|
||||
return String.valueOf( bool );
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,9 @@
|
||||
* @author Scott Marlow
|
||||
*/
|
||||
public class DerbyTenSixDialect extends DerbyTenFiveDialect {
|
||||
/**
|
||||
* Constructs a DerbyTenSixDialect
|
||||
*/
|
||||
public DerbyTenSixDialect() {
|
||||
super();
|
||||
}
|
||||
|
@ -23,14 +23,42 @@
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.sql.Blob;
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.Clob;
|
||||
import java.sql.NClob;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.NullPrecedence;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.function.*;
|
||||
import org.hibernate.dialect.lock.*;
|
||||
import org.hibernate.dialect.function.CastFunction;
|
||||
import org.hibernate.dialect.function.SQLFunction;
|
||||
import org.hibernate.dialect.function.SQLFunctionTemplate;
|
||||
import org.hibernate.dialect.function.StandardAnsiSqlAggregationFunctions;
|
||||
import org.hibernate.dialect.function.StandardSQLFunction;
|
||||
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.PessimisticReadSelectLockingStrategy;
|
||||
import org.hibernate.dialect.lock.PessimisticWriteSelectLockingStrategy;
|
||||
import org.hibernate.dialect.lock.SelectLockingStrategy;
|
||||
import org.hibernate.dialect.pagination.LegacyLimitHandler;
|
||||
import org.hibernate.dialect.pagination.LimitHandler;
|
||||
import org.hibernate.dialect.unique.DefaultUniqueDelegate;
|
||||
@ -52,39 +80,47 @@
|
||||
import org.hibernate.internal.util.io.StreamCopier;
|
||||
import org.hibernate.mapping.Column;
|
||||
import org.hibernate.persister.entity.Lockable;
|
||||
import org.hibernate.sql.*;
|
||||
import org.hibernate.sql.ANSICaseFragment;
|
||||
import org.hibernate.sql.ANSIJoinFragment;
|
||||
import org.hibernate.sql.CaseFragment;
|
||||
import org.hibernate.sql.ForUpdateFragment;
|
||||
import org.hibernate.sql.JoinFragment;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.descriptor.sql.ClobTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Represents a dialect of SQL implemented by a particular RDBMS.
|
||||
* Subclasses implement Hibernate compatibility with different systems.<br>
|
||||
* <br>
|
||||
* Subclasses should provide a public default constructor that <tt>register()</tt>
|
||||
* a set of type mappings and default Hibernate properties.<br>
|
||||
* <br>
|
||||
* Subclasses should be immutable.
|
||||
* Represents a dialect of SQL implemented by a particular RDBMS. Subclasses implement Hibernate compatibility
|
||||
* with different systems. Subclasses should provide a public default constructor that register a set of type
|
||||
* mappings and default Hibernate properties. Subclasses should be immutable.
|
||||
*
|
||||
* @author Gavin King, David Channon
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract class Dialect implements ConversionContext {
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
Dialect.class.getName()
|
||||
);
|
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, Dialect.class.getName());
|
||||
|
||||
/**
|
||||
* Defines a default batch size constant
|
||||
*/
|
||||
public static final String DEFAULT_BATCH_SIZE = "15";
|
||||
|
||||
/**
|
||||
* Defines a "no batching" batch size constant
|
||||
*/
|
||||
public static final String NO_BATCH = "0";
|
||||
|
||||
/**
|
||||
* Characters used for quoting SQL identifiers
|
||||
* Characters used as opening for quoting SQL identifiers
|
||||
*/
|
||||
public static final String QUOTE = "`\"[";
|
||||
|
||||
/**
|
||||
* Characters used as closing for quoting SQL identifiers
|
||||
*/
|
||||
public static final String CLOSED_QUOTE = "`\"]";
|
||||
|
||||
private final TypeNames typeNames = new TypeNames();
|
||||
@ -93,7 +129,7 @@ public abstract class Dialect implements ConversionContext {
|
||||
private final Properties properties = new Properties();
|
||||
private final Map<String, SQLFunction> sqlFunctions = new HashMap<String, SQLFunction>();
|
||||
private final Set<String> sqlKeywords = new HashSet<String>();
|
||||
|
||||
|
||||
private final UniqueDelegate uniqueDelegate;
|
||||
|
||||
|
||||
@ -158,14 +194,14 @@ protected Dialect() {
|
||||
registerColumnType( Types.LONGNVARCHAR, "nvarchar($l)" );
|
||||
registerColumnType( Types.NCLOB, "nclob" );
|
||||
|
||||
// register hibernate types for default use in scalar sqlquery type auto detection
|
||||
// register hibernate types for default use in scalar sqlquery type auto detection
|
||||
registerHibernateType( Types.BIGINT, StandardBasicTypes.BIG_INTEGER.getName() );
|
||||
registerHibernateType( Types.BINARY, StandardBasicTypes.BINARY.getName() );
|
||||
registerHibernateType( Types.BIT, StandardBasicTypes.BOOLEAN.getName() );
|
||||
registerHibernateType( Types.BOOLEAN, StandardBasicTypes.BOOLEAN.getName() );
|
||||
registerHibernateType( Types.CHAR, StandardBasicTypes.CHARACTER.getName() );
|
||||
registerHibernateType( Types.CHAR, 1, StandardBasicTypes.CHARACTER.getName() );
|
||||
registerHibernateType( Types.CHAR, 255, StandardBasicTypes.STRING.getName() );
|
||||
registerHibernateType( Types.CHAR, 1, StandardBasicTypes.CHARACTER.getName() );
|
||||
registerHibernateType( Types.CHAR, 255, StandardBasicTypes.STRING.getName() );
|
||||
registerHibernateType( Types.DATE, StandardBasicTypes.DATE.getName() );
|
||||
registerHibernateType( Types.DOUBLE, StandardBasicTypes.DOUBLE.getName() );
|
||||
registerHibernateType( Types.FLOAT, StandardBasicTypes.FLOAT.getName() );
|
||||
@ -183,7 +219,7 @@ protected Dialect() {
|
||||
registerHibernateType( Types.BLOB, StandardBasicTypes.BLOB.getName() );
|
||||
registerHibernateType( Types.CLOB, StandardBasicTypes.CLOB.getName() );
|
||||
registerHibernateType( Types.REAL, StandardBasicTypes.FLOAT.getName() );
|
||||
|
||||
|
||||
uniqueDelegate = new DefaultUniqueDelegate( this );
|
||||
}
|
||||
|
||||
@ -194,8 +230,7 @@ protected Dialect() {
|
||||
* @throws HibernateException If no dialect was specified, or if it could not be instantiated.
|
||||
*/
|
||||
public static Dialect getDialect() throws HibernateException {
|
||||
String dialectName = Environment.getProperties().getProperty( Environment.DIALECT );
|
||||
return instantiateDialect( dialectName );
|
||||
return instantiateDialect( Environment.getProperties().getProperty( Environment.DIALECT ) );
|
||||
}
|
||||
|
||||
|
||||
@ -208,7 +243,7 @@ public static Dialect getDialect() throws HibernateException {
|
||||
* @throws HibernateException If no dialect was specified, or if it could not be instantiated.
|
||||
*/
|
||||
public static Dialect getDialect(Properties props) throws HibernateException {
|
||||
String dialectName = props.getProperty( Environment.DIALECT );
|
||||
final String dialectName = props.getProperty( Environment.DIALECT );
|
||||
if ( dialectName == null ) {
|
||||
return getDialect();
|
||||
}
|
||||
@ -220,7 +255,7 @@ private static Dialect instantiateDialect(String dialectName) throws HibernateEx
|
||||
throw new HibernateException( "The dialect was not set. Set the property hibernate.dialect." );
|
||||
}
|
||||
try {
|
||||
return ( Dialect ) ReflectHelper.classForName( dialectName ).newInstance();
|
||||
return (Dialect) ReflectHelper.classForName( dialectName ).newInstance();
|
||||
}
|
||||
catch ( ClassNotFoundException cnfe ) {
|
||||
throw new HibernateException( "Dialect class not found: " + dialectName );
|
||||
@ -240,7 +275,7 @@ public final Properties getDefaultProperties() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
public String toString() {
|
||||
return getClass().getName();
|
||||
}
|
||||
|
||||
@ -256,7 +291,7 @@ public String toString() {
|
||||
* @throws HibernateException If no mapping was specified for that type.
|
||||
*/
|
||||
public String getTypeName(int code) throws HibernateException {
|
||||
String result = typeNames.get( code );
|
||||
final String result = typeNames.get( code );
|
||||
if ( result == null ) {
|
||||
throw new HibernateException( "No default type mapping for (java.sql.Types) " + code );
|
||||
}
|
||||
@ -276,9 +311,11 @@ public String getTypeName(int code) throws HibernateException {
|
||||
* @throws HibernateException If no mapping was specified for that type.
|
||||
*/
|
||||
public String getTypeName(int code, long length, int precision, int scale) throws HibernateException {
|
||||
String result = typeNames.get( code, length, precision, scale );
|
||||
final String result = typeNames.get( code, length, precision, scale );
|
||||
if ( result == null ) {
|
||||
throw new HibernateException(String.format( "No type mapping for java.sql.Types code: %s, length: %s", code, length ));
|
||||
throw new HibernateException(
|
||||
String.format( "No type mapping for java.sql.Types code: %s, length: %s", code, length )
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -294,6 +331,17 @@ public String getCastTypeName(int code) {
|
||||
return getTypeName( code, Column.DEFAULT_LENGTH, Column.DEFAULT_PRECISION, Column.DEFAULT_SCALE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an expression casting the value to the specified type
|
||||
*
|
||||
* @param value The value to cast
|
||||
* @param jdbcTypeCode The JDBC type code to cast to
|
||||
* @param length The type length
|
||||
* @param precision The type precision
|
||||
* @param scale The type scale
|
||||
*
|
||||
* @return The cast expression
|
||||
*/
|
||||
public String cast(String value, int jdbcTypeCode, int length, int precision, int scale) {
|
||||
if ( jdbcTypeCode == Types.CHAR ) {
|
||||
return "cast(" + value + " as char(" + length + "))";
|
||||
@ -303,10 +351,32 @@ public String cast(String value, int jdbcTypeCode, int length, int precision, in
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an expression casting the value to the specified type. Simply calls
|
||||
* {@link #cast(String, int, int, int, int)} passing {@link Column#DEFAULT_PRECISION} and
|
||||
* {@link Column#DEFAULT_SCALE} as the precision/scale.
|
||||
*
|
||||
* @param value The value to cast
|
||||
* @param jdbcTypeCode The JDBC type code to cast to
|
||||
* @param length The type length
|
||||
*
|
||||
* @return The cast expression
|
||||
*/
|
||||
public String cast(String value, int jdbcTypeCode, int length) {
|
||||
return cast( value, jdbcTypeCode, length, Column.DEFAULT_PRECISION, Column.DEFAULT_SCALE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an expression casting the value to the specified type. Simply calls
|
||||
* {@link #cast(String, int, int, int, int)} passing {@link Column#DEFAULT_LENGTH} as the length
|
||||
*
|
||||
* @param value The value to cast
|
||||
* @param jdbcTypeCode The JDBC type code to cast to
|
||||
* @param precision The type precision
|
||||
* @param scale The type scale
|
||||
*
|
||||
* @return The cast expression
|
||||
*/
|
||||
public String cast(String value, int jdbcTypeCode, int precision, int scale) {
|
||||
return cast( value, jdbcTypeCode, Column.DEFAULT_LENGTH, precision, scale );
|
||||
}
|
||||
@ -417,8 +487,10 @@ public NClob mergeNClob(NClob original, NClob target, SessionImplementor session
|
||||
public Blob mergeBlob(Blob original, Blob target, SessionImplementor session) {
|
||||
if ( original != target ) {
|
||||
try {
|
||||
OutputStream connectedStream = target.setBinaryStream( 1L ); // the BLOB just read during the load phase of merge
|
||||
InputStream detachedStream = original.getBinaryStream(); // the BLOB from the detached state
|
||||
// the BLOB just read during the load phase of merge
|
||||
final OutputStream connectedStream = target.setBinaryStream( 1L );
|
||||
// the BLOB from the detached state
|
||||
final InputStream detachedStream = original.getBinaryStream();
|
||||
StreamCopier.copy( detachedStream, connectedStream );
|
||||
return target;
|
||||
}
|
||||
@ -435,8 +507,10 @@ public Blob mergeBlob(Blob original, Blob target, SessionImplementor session) {
|
||||
public Clob mergeClob(Clob original, Clob target, SessionImplementor session) {
|
||||
if ( original != target ) {
|
||||
try {
|
||||
OutputStream connectedStream = target.setAsciiStream( 1L ); // the CLOB just read during the load phase of merge
|
||||
InputStream detachedStream = original.getAsciiStream(); // the CLOB from the detached state
|
||||
// the CLOB just read during the load phase of merge
|
||||
final OutputStream connectedStream = target.setAsciiStream( 1L );
|
||||
// the CLOB from the detached state
|
||||
final InputStream detachedStream = original.getAsciiStream();
|
||||
StreamCopier.copy( detachedStream, connectedStream );
|
||||
return target;
|
||||
}
|
||||
@ -453,8 +527,10 @@ public Clob mergeClob(Clob original, Clob target, SessionImplementor session) {
|
||||
public NClob mergeNClob(NClob original, NClob target, SessionImplementor session) {
|
||||
if ( original != target ) {
|
||||
try {
|
||||
OutputStream connectedStream = target.setAsciiStream( 1L ); // the NCLOB just read during the load phase of merge
|
||||
InputStream detachedStream = original.getAsciiStream(); // the NCLOB from the detached state
|
||||
// the NCLOB just read during the load phase of merge
|
||||
final OutputStream connectedStream = target.setAsciiStream( 1L );
|
||||
// the NCLOB from the detached state
|
||||
final InputStream detachedStream = original.getAsciiStream();
|
||||
StreamCopier.copy( detachedStream, connectedStream );
|
||||
return target;
|
||||
}
|
||||
@ -478,7 +554,7 @@ public Blob mergeBlob(Blob original, Blob target, SessionImplementor session) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
LobCreator lobCreator = session.getFactory().getJdbcServices().getLobCreator( session );
|
||||
final LobCreator lobCreator = session.getFactory().getJdbcServices().getLobCreator( session );
|
||||
return original == null
|
||||
? lobCreator.createBlob( ArrayHelper.EMPTY_BYTE_ARRAY )
|
||||
: lobCreator.createBlob( original.getBinaryStream(), original.length() );
|
||||
@ -494,7 +570,7 @@ public Clob mergeClob(Clob original, Clob target, SessionImplementor session) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
LobCreator lobCreator = session.getFactory().getJdbcServices().getLobCreator( session );
|
||||
final LobCreator lobCreator = session.getFactory().getJdbcServices().getLobCreator( session );
|
||||
return original == null
|
||||
? lobCreator.createClob( "" )
|
||||
: lobCreator.createClob( original.getCharacterStream(), original.length() );
|
||||
@ -510,7 +586,7 @@ public NClob mergeNClob(NClob original, NClob target, SessionImplementor session
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
LobCreator lobCreator = session.getFactory().getJdbcServices().getLobCreator( session );
|
||||
final LobCreator lobCreator = session.getFactory().getJdbcServices().getLobCreator( session );
|
||||
return original == null
|
||||
? lobCreator.createNClob( "" )
|
||||
: lobCreator.createNClob( original.getCharacterStream(), original.length() );
|
||||
@ -538,7 +614,7 @@ public LobMergeStrategy getLobMergeStrategy() {
|
||||
*/
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
public String getHibernateTypeName(int code) throws HibernateException {
|
||||
String result = hibernateTypeNames.get( code );
|
||||
final String result = hibernateTypeNames.get( code );
|
||||
if ( result == null ) {
|
||||
throw new HibernateException( "No Hibernate type mapping for java.sql.Types code: " + code );
|
||||
}
|
||||
@ -558,13 +634,14 @@ public String getHibernateTypeName(int code) throws HibernateException {
|
||||
* @throws HibernateException If no mapping was specified for that type.
|
||||
*/
|
||||
public String getHibernateTypeName(int code, int length, int precision, int scale) throws HibernateException {
|
||||
String result = hibernateTypeNames.get( code, length, precision, scale );
|
||||
final String result = hibernateTypeNames.get( code, length, precision, scale );
|
||||
if ( result == null ) {
|
||||
throw new HibernateException(
|
||||
"No Hibernate type mapping for java.sql.Types code: " +
|
||||
code +
|
||||
", length: " +
|
||||
length
|
||||
String.format(
|
||||
"No Hibernate type mapping for type [code=%s, length=%s]",
|
||||
code,
|
||||
length
|
||||
)
|
||||
);
|
||||
}
|
||||
return result;
|
||||
@ -813,7 +890,7 @@ public String getSelectSequenceNextValString(String sequenceName) throws Mapping
|
||||
* @deprecated Use {@link #getCreateSequenceString(String, int, int)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public String[] getCreateSequenceStrings(String sequenceName) throws MappingException {
|
||||
public String[] getCreateSequenceStrings(String sequenceName) throws MappingException {
|
||||
return new String[] { getCreateSequenceString( sequenceName ) };
|
||||
}
|
||||
|
||||
@ -1130,20 +1207,20 @@ public boolean isLockTimeoutParameterized() {
|
||||
* @since 3.2
|
||||
*/
|
||||
public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
|
||||
switch ( lockMode ) {
|
||||
case PESSIMISTIC_FORCE_INCREMENT:
|
||||
return new PessimisticForceIncrementLockingStrategy( lockable, lockMode );
|
||||
case PESSIMISTIC_WRITE:
|
||||
return new PessimisticWriteSelectLockingStrategy( lockable, lockMode );
|
||||
case PESSIMISTIC_READ:
|
||||
return new PessimisticReadSelectLockingStrategy( lockable, lockMode );
|
||||
case OPTIMISTIC:
|
||||
return new OptimisticLockingStrategy( lockable, lockMode );
|
||||
case OPTIMISTIC_FORCE_INCREMENT:
|
||||
return new OptimisticForceIncrementLockingStrategy( lockable, lockMode );
|
||||
default:
|
||||
return new SelectLockingStrategy( lockable, lockMode );
|
||||
}
|
||||
switch ( lockMode ) {
|
||||
case PESSIMISTIC_FORCE_INCREMENT:
|
||||
return new PessimisticForceIncrementLockingStrategy( lockable, lockMode );
|
||||
case PESSIMISTIC_WRITE:
|
||||
return new PessimisticWriteSelectLockingStrategy( lockable, lockMode );
|
||||
case PESSIMISTIC_READ:
|
||||
return new PessimisticReadSelectLockingStrategy( lockable, lockMode );
|
||||
case OPTIMISTIC:
|
||||
return new OptimisticLockingStrategy( lockable, lockMode );
|
||||
case OPTIMISTIC_FORCE_INCREMENT:
|
||||
return new OptimisticForceIncrementLockingStrategy( lockable, lockMode );
|
||||
default:
|
||||
return new SelectLockingStrategy( lockable, lockMode );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1153,29 +1230,29 @@ public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode)
|
||||
* @return The appropriate for update fragment.
|
||||
*/
|
||||
public String getForUpdateString(LockOptions lockOptions) {
|
||||
LockMode lockMode = lockOptions.getLockMode();
|
||||
return getForUpdateString( lockMode, lockOptions.getTimeOut() );
|
||||
final LockMode lockMode = lockOptions.getLockMode();
|
||||
return getForUpdateString( lockMode, lockOptions.getTimeOut() );
|
||||
}
|
||||
|
||||
@SuppressWarnings( {"deprecation"})
|
||||
@SuppressWarnings( {"deprecation"})
|
||||
private String getForUpdateString(LockMode lockMode, int timeout){
|
||||
switch ( lockMode ) {
|
||||
case UPGRADE:
|
||||
return getForUpdateString();
|
||||
case PESSIMISTIC_READ:
|
||||
return getReadLockString( timeout );
|
||||
case PESSIMISTIC_WRITE:
|
||||
return getWriteLockString( timeout );
|
||||
case UPGRADE_NOWAIT:
|
||||
case FORCE:
|
||||
case PESSIMISTIC_FORCE_INCREMENT:
|
||||
return getForUpdateNowaitString();
|
||||
case UPGRADE_SKIPLOCKED:
|
||||
return getForUpdateSkipLockedString();
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
switch ( lockMode ) {
|
||||
case UPGRADE:
|
||||
return getForUpdateString();
|
||||
case PESSIMISTIC_READ:
|
||||
return getReadLockString( timeout );
|
||||
case PESSIMISTIC_WRITE:
|
||||
return getWriteLockString( timeout );
|
||||
case UPGRADE_NOWAIT:
|
||||
case FORCE:
|
||||
case PESSIMISTIC_FORCE_INCREMENT:
|
||||
return getForUpdateNowaitString();
|
||||
case UPGRADE_SKIPLOCKED:
|
||||
return getForUpdateSkipLockedString();
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a lock mode, determine the appropriate for update fragment to use.
|
||||
@ -1267,12 +1344,12 @@ public String getForUpdateString(String aliases) {
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
public String getForUpdateString(String aliases, LockOptions lockOptions) {
|
||||
LockMode lockMode = lockOptions.getLockMode();
|
||||
Iterator<Map.Entry<String, LockMode>> itr = lockOptions.getAliasLockIterator();
|
||||
final Iterator<Map.Entry<String, LockMode>> itr = lockOptions.getAliasLockIterator();
|
||||
while ( itr.hasNext() ) {
|
||||
// seek the highest lock mode
|
||||
final Map.Entry<String, LockMode>entry = itr.next();
|
||||
final LockMode lm = entry.getValue();
|
||||
if ( lm.greaterThan(lockMode) ) {
|
||||
if ( lm.greaterThan( lockMode ) ) {
|
||||
lockMode = lm;
|
||||
}
|
||||
}
|
||||
@ -1291,10 +1368,10 @@ public String getForUpdateNowaitString() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the <tt>FOR UPDATE SKIP LOCKED</tt> syntax specific to this dialect.
|
||||
*
|
||||
* @return The appropriate <tt>FOR UPDATE SKIP LOCKED</tt> clause string.
|
||||
*/
|
||||
* Retrieves the <tt>FOR UPDATE SKIP LOCKED</tt> syntax specific to this dialect.
|
||||
*
|
||||
* @return The appropriate <tt>FOR UPDATE SKIP LOCKED</tt> clause string.
|
||||
*/
|
||||
public String getForUpdateSkipLockedString() {
|
||||
// by default we report no support for SKIP_LOCKED lock semantics
|
||||
return getForUpdateString();
|
||||
@ -1311,7 +1388,7 @@ public String getForUpdateNowaitString(String aliases) {
|
||||
return getForUpdateString( aliases );
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get the <tt>FOR UPDATE OF column_list SKIP LOCKED</tt> fragment appropriate
|
||||
* for this dialect given the aliases of the columns to be write locked.
|
||||
*
|
||||
@ -1498,8 +1575,8 @@ public boolean dropTemporaryTableAfterUse() {
|
||||
public int registerResultSetOutParameter(CallableStatement statement, int position) throws SQLException {
|
||||
throw new UnsupportedOperationException(
|
||||
getClass().getName() +
|
||||
" does not support resultsets via stored procedures"
|
||||
);
|
||||
" does not support resultsets via stored procedures"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1531,9 +1608,8 @@ public int registerResultSetOutParameter(CallableStatement statement, String nam
|
||||
*/
|
||||
public ResultSet getResultSet(CallableStatement statement) throws SQLException {
|
||||
throw new UnsupportedOperationException(
|
||||
getClass().getName() +
|
||||
" does not support resultsets via stored procedures"
|
||||
);
|
||||
getClass().getName() + " does not support resultsets via stored procedures"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1549,8 +1625,7 @@ public ResultSet getResultSet(CallableStatement statement) throws SQLException {
|
||||
*/
|
||||
public ResultSet getResultSet(CallableStatement statement, int position) throws SQLException {
|
||||
throw new UnsupportedOperationException(
|
||||
getClass().getName() +
|
||||
" does not support resultsets via stored procedures"
|
||||
getClass().getName() + " does not support resultsets via stored procedures"
|
||||
);
|
||||
}
|
||||
|
||||
@ -1567,8 +1642,7 @@ public ResultSet getResultSet(CallableStatement statement, int position) throws
|
||||
*/
|
||||
public ResultSet getResultSet(CallableStatement statement, String name) throws SQLException {
|
||||
throw new UnsupportedOperationException(
|
||||
getClass().getName() +
|
||||
" does not support resultsets via stored procedures"
|
||||
getClass().getName() + " does not support resultsets via stored procedures"
|
||||
);
|
||||
}
|
||||
|
||||
@ -1677,6 +1751,8 @@ public SQLExceptionConverter buildSQLExceptionConverter() {
|
||||
* the a vendor-specific ErrorCode rather than the SQLState.
|
||||
* <p/>
|
||||
* Specific Dialects may override to return whatever is most appropriate for that vendor.
|
||||
*
|
||||
* @return The SQLExceptionConversionDelegate for this dialect
|
||||
*/
|
||||
public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
|
||||
return null;
|
||||
@ -1767,6 +1843,7 @@ public String getLowercaseFunction() {
|
||||
|
||||
/**
|
||||
* The name of the SQL function that can do case insensitive <b>like</b> comparison.
|
||||
*
|
||||
* @return The dialect-specific "case insensitive" like function.
|
||||
*/
|
||||
public String getCaseInsensitiveLike(){
|
||||
@ -1774,8 +1851,10 @@ public String getCaseInsensitiveLike(){
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if the underlying Database supports case insensitive like comparison, {@code false} otherwise.
|
||||
* The default is {@code false}.
|
||||
* Does this dialect support case insensitive LIKE restrictions?
|
||||
*
|
||||
* @return {@code true} if the underlying database supports case insensitive like comparison,
|
||||
* {@code false} otherwise. The default is {@code false}.
|
||||
*/
|
||||
public boolean supportsCaseInsensitiveLike(){
|
||||
return false;
|
||||
@ -1949,7 +2028,7 @@ public String getAddForeignKeyConstraintString(
|
||||
String referencedTable,
|
||||
String[] primaryKey,
|
||||
boolean referencesPrimaryKey) {
|
||||
StringBuilder res = new StringBuilder( 30 );
|
||||
final StringBuilder res = new StringBuilder( 30 );
|
||||
|
||||
res.append( " add constraint " )
|
||||
.append( constraintName )
|
||||
@ -1977,6 +2056,11 @@ public String getAddPrimaryKeyConstraintString(String constraintName) {
|
||||
return " add constraint " + constraintName + " primary key ";
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the database/driver have bug in deleting rows that refer to other rows being deleted in the same query?
|
||||
*
|
||||
* @return {@code true} if the database/driver has this bug
|
||||
*/
|
||||
public boolean hasSelfReferentialForeignKeyBug() {
|
||||
return false;
|
||||
}
|
||||
@ -1990,28 +2074,68 @@ public String getNullColumnString() {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this dialect/database support commenting on tables, columns, etc?
|
||||
*
|
||||
* @return {@code true} if commenting is supported
|
||||
*/
|
||||
public boolean supportsCommentOn() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the comment into a form supported for table definition.
|
||||
*
|
||||
* @param comment The comment to apply
|
||||
*
|
||||
* @return The comment fragment
|
||||
*/
|
||||
public String getTableComment(String comment) {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the comment into a form supported for column definition.
|
||||
*
|
||||
* @param comment The comment to apply
|
||||
*
|
||||
* @return The comment fragment
|
||||
*/
|
||||
public String getColumnComment(String comment) {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* For dropping a table, can the phrase "if exists" be applied before the table name?
|
||||
* <p/>
|
||||
* NOTE : Only one or the other (or neither) of this and {@link #supportsIfExistsAfterTableName} should return true
|
||||
*
|
||||
* @return {@code true} if the "if exists" can be applied before the table name
|
||||
*/
|
||||
public boolean supportsIfExistsBeforeTableName() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* For dropping a table, can the phrase "if exists" be applied after the table name?
|
||||
* <p/>
|
||||
* NOTE : Only one or the other (or neither) of this and {@link #supportsIfExistsBeforeTableName} should return true
|
||||
*
|
||||
* @return {@code true} if the "if exists" can be applied after the table name
|
||||
*/
|
||||
public boolean supportsIfExistsAfterTableName() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getDropTableString( String tableName ) {
|
||||
StringBuilder buf = new StringBuilder( "drop table " );
|
||||
|
||||
/**
|
||||
* Generate a DROP TABLE statement
|
||||
*
|
||||
* @param tableName The name of the table to drop
|
||||
*
|
||||
* @return The DROP TABLE command
|
||||
*/
|
||||
public String getDropTableString(String tableName) {
|
||||
final StringBuilder buf = new StringBuilder( "drop table " );
|
||||
if ( supportsIfExistsBeforeTableName() ) {
|
||||
buf.append( "if exists " );
|
||||
}
|
||||
@ -2042,6 +2166,11 @@ public boolean supportsTableCheck() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this dialect support cascaded delete on foreign key definitions?
|
||||
*
|
||||
* @return {@code true} indicates that the dialect does support cascaded delete on foreign keys.
|
||||
*/
|
||||
public boolean supportsCascadeDelete() {
|
||||
return true;
|
||||
}
|
||||
@ -2056,12 +2185,13 @@ public String getCascadeConstraintsString() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the separator to use for defining cross joins when translating HQL queries.
|
||||
* Returns the separator to use for defining cross joins when translating HQL queries.
|
||||
* <p/>
|
||||
* Typically this will be either [<tt> cross join </tt>] or [<tt>, </tt>]
|
||||
* <p/>
|
||||
* Note that the spaces are important!
|
||||
*
|
||||
* @return The cross join separator
|
||||
*/
|
||||
public String getCrossJoinSeparator() {
|
||||
return " cross join ";
|
||||
@ -2165,6 +2295,8 @@ public boolean replaceResultVariableInOrderByClauseWithPosition() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders an ordering fragment
|
||||
*
|
||||
* @param expression The SQL order expression. In case of {@code @OrderBy} annotation user receives property placeholder
|
||||
* (e.g. attribute name enclosed in '{' and '}' signs).
|
||||
* @param collation Collation string in format {@code collate IDENTIFIER}, or {@code null}
|
||||
@ -2379,11 +2511,11 @@ public boolean supportsTupleCounts() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this dialect support `count(distinct a,b)`?
|
||||
*
|
||||
* @return True if the database supports counting distinct tuples; false otherwise.
|
||||
*/
|
||||
/**
|
||||
* Does this dialect support `count(distinct a,b)`?
|
||||
*
|
||||
* @return True if the database supports counting distinct tuples; false otherwise.
|
||||
*/
|
||||
public boolean supportsTupleDistinctCounts() {
|
||||
// oddly most database in fact seem to, so true is the default.
|
||||
return true;
|
||||
@ -2392,17 +2524,17 @@ public boolean supportsTupleDistinctCounts() {
|
||||
/**
|
||||
* Return the limit that the underlying database places on the number elements in an {@code IN} predicate.
|
||||
* If the database defines no such limits, simply return zero or less-than-zero.
|
||||
*
|
||||
*
|
||||
* @return int The limit, or zero-or-less to indicate no limit.
|
||||
*/
|
||||
public int getInExpressionCountLimit() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* HHH-4635
|
||||
* Oracle expects all Lob values to be last in inserts and updates.
|
||||
*
|
||||
*
|
||||
* @return boolean True of Lob values should be last, false if it
|
||||
* does not matter.
|
||||
*/
|
||||
@ -2421,20 +2553,32 @@ public boolean forceLobAsLastValue() {
|
||||
public boolean useFollowOnLocking() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public UniqueDelegate getUniqueDelegate() {
|
||||
return uniqueDelegate;
|
||||
|
||||
/**
|
||||
* Negate an expression
|
||||
*
|
||||
* @param expression The expression to negate
|
||||
*
|
||||
* @return The negated expression
|
||||
*/
|
||||
public String getNotExpression(String expression) {
|
||||
return "not " + expression;
|
||||
}
|
||||
|
||||
public String getNotExpression( String expression ) {
|
||||
return "not " + expression;
|
||||
/**
|
||||
* Get the UniqueDelegate supported by this dialect
|
||||
*
|
||||
* @return The UniqueDelegate
|
||||
*/
|
||||
public UniqueDelegate getUniqueDelegate() {
|
||||
return uniqueDelegate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this dialect support the <tt>UNIQUE</tt> column syntax?
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
*
|
||||
* @deprecated {@link #getUniqueDelegate()} should be overridden instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@ -2442,32 +2586,36 @@ public boolean supportsUnique() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this dialect support adding Unique constraints via create and alter table ?
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @deprecated {@link #getUniqueDelegate()} should be overridden instead.
|
||||
*/
|
||||
/**
|
||||
* Does this dialect support adding Unique constraints via create and alter table ?
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @deprecated {@link #getUniqueDelegate()} should be overridden instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean supportsUniqueConstraintInCreateAlterTable() {
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The syntax used to add a unique constraint to a table.
|
||||
*
|
||||
* @param constraintName The name of the unique constraint.
|
||||
* @return The "add unique" fragment
|
||||
*
|
||||
* @deprecated {@link #getUniqueDelegate()} should be overridden instead.
|
||||
*/
|
||||
/**
|
||||
* The syntax used to add a unique constraint to a table.
|
||||
*
|
||||
* @param constraintName The name of the unique constraint.
|
||||
* @return The "add unique" fragment
|
||||
*
|
||||
* @deprecated {@link #getUniqueDelegate()} should be overridden instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public String getAddUniqueConstraintString(String constraintName) {
|
||||
return " add constraint " + constraintName + " unique ";
|
||||
}
|
||||
return " add constraint " + constraintName + " unique ";
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the combination of not-null and unique supported?
|
||||
*
|
||||
* @return deprecated
|
||||
*
|
||||
* @deprecated {@link #getUniqueDelegate()} should be overridden instead.
|
||||
*/
|
||||
@Deprecated
|
||||
|
@ -23,18 +23,18 @@
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
|
||||
/**
|
||||
* An SQL dialect for Firebird.
|
||||
*
|
||||
* @author Reha CENANI
|
||||
*/
|
||||
public class FirebirdDialect extends InterbaseDialect {
|
||||
|
||||
@Override
|
||||
public String getDropSequenceString(String sequenceName) {
|
||||
return "drop generator " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLimitString(String sql, boolean hasOffset) {
|
||||
return new StringBuilder( sql.length() + 20 )
|
||||
.append( sql )
|
||||
@ -42,12 +42,13 @@ public String getLimitString(String sql, boolean hasOffset) {
|
||||
.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean bindLimitParametersFirst() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean bindLimitParametersInReverseOrder() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -53,6 +53,9 @@
|
||||
*/
|
||||
public class FrontBaseDialect extends Dialect {
|
||||
|
||||
/**
|
||||
* Constructs a FrontBaseDialect
|
||||
*/
|
||||
public FrontBaseDialect() {
|
||||
super();
|
||||
|
||||
@ -74,37 +77,43 @@ public FrontBaseDialect() {
|
||||
registerColumnType( Types.CLOB, "clob" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
return "add column";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCascadeConstraintsString() {
|
||||
return " cascade";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dropConstraints() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this dialect support the <tt>FOR UPDATE</tt> syntax. No!
|
||||
*
|
||||
* @return false always. FrontBase doesn't support this syntax,
|
||||
* which was dropped with SQL92
|
||||
* FrontBase doesn't support this syntax, which was dropped with SQL92.
|
||||
* <p/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getForUpdateString() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getCurrentTimestampCallString() {
|
||||
@Override
|
||||
public String getCurrentTimestampSelectString() {
|
||||
// TODO : not sure this is correct, could not find docs on how to do this.
|
||||
return "{?= call current_timestamp}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurrentTimestampSelectStringCallable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
|
||||
// Frontbase has no known variation of a "SELECT ... FOR UPDATE" syntax...
|
||||
if ( lockMode==LockMode.PESSIMISTIC_FORCE_INCREMENT) {
|
||||
|
@ -50,11 +50,16 @@
|
||||
* @author Thomas Mueller
|
||||
*/
|
||||
public class H2Dialect extends Dialect {
|
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, H2Dialect.class.getName());
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
H2Dialect.class.getName()
|
||||
);
|
||||
|
||||
private final String querySequenceString;
|
||||
|
||||
/**
|
||||
* Constructs a H2Dialect
|
||||
*/
|
||||
public H2Dialect() {
|
||||
super();
|
||||
|
||||
@ -62,13 +67,13 @@ public H2Dialect() {
|
||||
try {
|
||||
// HHH-2300
|
||||
final Class h2ConstantsClass = ReflectHelper.classForName( "org.h2.engine.Constants" );
|
||||
final int majorVersion = ( Integer ) h2ConstantsClass.getDeclaredField( "VERSION_MAJOR" ).get( null );
|
||||
final int minorVersion = ( Integer ) h2ConstantsClass.getDeclaredField( "VERSION_MINOR" ).get( null );
|
||||
final int buildId = ( Integer ) h2ConstantsClass.getDeclaredField( "BUILD_ID" ).get( null );
|
||||
final int majorVersion = (Integer) h2ConstantsClass.getDeclaredField( "VERSION_MAJOR" ).get( null );
|
||||
final int minorVersion = (Integer) h2ConstantsClass.getDeclaredField( "VERSION_MINOR" ).get( null );
|
||||
final int buildId = (Integer) h2ConstantsClass.getDeclaredField( "BUILD_ID" ).get( null );
|
||||
if ( buildId < 32 ) {
|
||||
querySequenceString = "select name from information_schema.sequences";
|
||||
}
|
||||
if ( ! ( majorVersion > 1 || minorVersion > 2 || buildId >= 139 ) ) {
|
||||
if ( ! ( majorVersion > 1 || minorVersion > 2 || buildId >= 139 ) ) {
|
||||
LOG.unsupportedMultiTableBulkHqlJpaql( majorVersion, minorVersion, buildId );
|
||||
}
|
||||
}
|
||||
@ -190,89 +195,107 @@ public H2Dialect() {
|
||||
registerFunction( "user", new NoArgSQLFunction( "user", StandardBasicTypes.STRING ) );
|
||||
|
||||
getDefaultProperties().setProperty( AvailableSettings.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
|
||||
getDefaultProperties().setProperty( AvailableSettings.NON_CONTEXTUAL_LOB_CREATION, "true" ); // http://code.google.com/p/h2database/issues/detail?id=235
|
||||
// http://code.google.com/p/h2database/issues/detail?id=235
|
||||
getDefaultProperties().setProperty( AvailableSettings.NON_CONTEXTUAL_LOB_CREATION, "true" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
return "add column";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsIdentityColumns() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentityColumnString() {
|
||||
return "generated by default as identity"; // not null is implicit
|
||||
// not null is implicit
|
||||
return "generated by default as identity";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentitySelectString() {
|
||||
return "call identity()";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentityInsertString() {
|
||||
return "null";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForUpdateString() {
|
||||
return " for update";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLimitString(String sql, boolean hasOffset) {
|
||||
return new StringBuilder( sql.length() + 20 )
|
||||
.append( sql )
|
||||
.append( hasOffset ? " limit ? offset ?" : " limit ?" )
|
||||
.toString();
|
||||
return sql + (hasOffset ? " limit ? offset ?" : " limit ?");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean bindLimitParametersInReverseOrder() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean bindLimitParametersFirst() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsIfExistsAfterTableName() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPooledSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateSequenceString(String sequenceName) {
|
||||
return "create sequence " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDropSequenceString(String sequenceName) {
|
||||
return "drop sequence " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectSequenceNextValString(String sequenceName) {
|
||||
return "next value for " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSequenceNextValString(String sequenceName) {
|
||||
return "call next value for " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQuerySequencesString() {
|
||||
return querySequenceString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
|
||||
return EXTRACTER;
|
||||
}
|
||||
|
||||
private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
|
||||
private static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
|
||||
/**
|
||||
* Extract the name of the violated constraint from the given SQLException.
|
||||
*
|
||||
@ -285,7 +308,7 @@ public String extractConstraintName(SQLException sqle) {
|
||||
// 23001: Unique index or primary key violation: {0}
|
||||
if ( sqle.getSQLState().startsWith( "23" ) ) {
|
||||
final String message = sqle.getMessage();
|
||||
int idx = message.indexOf( "violation: " );
|
||||
final int idx = message.indexOf( "violation: " );
|
||||
if ( idx > 0 ) {
|
||||
constraintName = message.substring( idx + "violation: ".length() );
|
||||
}
|
||||
@ -293,34 +316,33 @@ public String extractConstraintName(SQLException sqle) {
|
||||
return constraintName;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@Override
|
||||
public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
|
||||
SQLExceptionConversionDelegate delegate = super.buildSQLExceptionConversionDelegate();
|
||||
if (delegate == null) {
|
||||
delegate = new SQLExceptionConversionDelegate() {
|
||||
|
||||
@Override
|
||||
public JDBCException convert(SQLException sqlException, String message, String sql) {
|
||||
JDBCException exception = null;
|
||||
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqlException );
|
||||
|
||||
int errorCode = JdbcExceptionHelper.extractErrorCode(sqlException);
|
||||
if (40001 == errorCode) {
|
||||
// DEADLOCK DETECTED
|
||||
return new LockAcquisitionException(message, sqlException, sql);
|
||||
}
|
||||
|
||||
if (40001 == errorCode) { // DEADLOCK DETECTED
|
||||
exception = new LockAcquisitionException(message, sqlException, sql);
|
||||
}
|
||||
|
||||
if (50200 == errorCode) { // LOCK NOT AVAILABLE
|
||||
exception = new PessimisticLockException(message, sqlException, sql);
|
||||
}
|
||||
if (50200 == errorCode) {
|
||||
// LOCK NOT AVAILABLE
|
||||
return new PessimisticLockException(message, sqlException, sql);
|
||||
}
|
||||
|
||||
if ( 90006 == errorCode ) {
|
||||
// NULL not allowed for column [90006-145]
|
||||
final String constraintName = getViolatedConstraintNameExtracter().extractConstraintName( sqlException );
|
||||
exception = new ConstraintViolationException( message, sqlException, sql, constraintName );
|
||||
return new ConstraintViolationException( message, sqlException, sql, constraintName );
|
||||
}
|
||||
|
||||
return exception;
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -356,18 +378,22 @@ public boolean dropTemporaryTableAfterUse() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCurrentTimestampSelection() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurrentTimestampSelectStringCallable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentTimestampSelectString() {
|
||||
return "call current_timestamp()";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsUnionAll() {
|
||||
return true;
|
||||
}
|
||||
|
@ -66,8 +66,10 @@
|
||||
* @author Fred Toussi
|
||||
*/
|
||||
public class HSQLDialect extends Dialect {
|
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, HSQLDialect.class.getName());
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
HSQLDialect.class.getName()
|
||||
);
|
||||
|
||||
/**
|
||||
* version is 18 for 1.8 or 20 for 2.0
|
||||
@ -75,12 +77,15 @@ public class HSQLDialect extends Dialect {
|
||||
private int hsqldbVersion = 18;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a HSQLDialect
|
||||
*/
|
||||
public HSQLDialect() {
|
||||
super();
|
||||
|
||||
try {
|
||||
Class props = ReflectHelper.classForName( "org.hsqldb.persist.HsqlDatabaseProperties" );
|
||||
String versionString = (String) props.getDeclaredField( "THIS_VERSION" ).get( null );
|
||||
final Class props = ReflectHelper.classForName( "org.hsqldb.persist.HsqlDatabaseProperties" );
|
||||
final String versionString = (String) props.getDeclaredField( "THIS_VERSION" ).get( null );
|
||||
|
||||
hsqldbVersion = Integer.parseInt( versionString.substring( 0, 1 ) ) * 10;
|
||||
hsqldbVersion += Integer.parseInt( versionString.substring( 2, 3 ) );
|
||||
@ -92,7 +97,7 @@ public HSQLDialect() {
|
||||
registerColumnType( Types.BIGINT, "bigint" );
|
||||
registerColumnType( Types.BINARY, "binary($l)" );
|
||||
registerColumnType( Types.BIT, "bit" );
|
||||
registerColumnType( Types.BOOLEAN, "boolean" );
|
||||
registerColumnType( Types.BOOLEAN, "boolean" );
|
||||
registerColumnType( Types.CHAR, "char($l)" );
|
||||
registerColumnType( Types.DATE, "date" );
|
||||
|
||||
@ -152,9 +157,9 @@ public HSQLDialect() {
|
||||
|
||||
// datetime functions
|
||||
if ( hsqldbVersion < 20 ) {
|
||||
registerFunction( "sysdate", new NoArgSQLFunction( "sysdate", StandardBasicTypes.DATE, false ) );
|
||||
registerFunction( "sysdate", new NoArgSQLFunction( "sysdate", StandardBasicTypes.DATE, false ) );
|
||||
} else {
|
||||
registerFunction( "sysdate", new NoArgSQLFunction( "sysdate", StandardBasicTypes.TIMESTAMP, false ) );
|
||||
registerFunction( "sysdate", new NoArgSQLFunction( "sysdate", StandardBasicTypes.TIMESTAMP, false ) );
|
||||
}
|
||||
registerFunction( "current_date", new NoArgSQLFunction( "current_date", StandardBasicTypes.DATE, false ) );
|
||||
registerFunction( "curdate", new NoArgSQLFunction( "curdate", StandardBasicTypes.DATE ) );
|
||||
@ -208,8 +213,7 @@ public HSQLDialect() {
|
||||
// special functions
|
||||
// from v. 2.2.0 ROWNUM() is supported in all modes as the equivalent of Oracle ROWNUM
|
||||
if ( hsqldbVersion > 21 ) {
|
||||
registerFunction("rownum",
|
||||
new NoArgSQLFunction("rownum", StandardBasicTypes.INTEGER));
|
||||
registerFunction( "rownum", new NoArgSQLFunction( "rownum", StandardBasicTypes.INTEGER ) );
|
||||
}
|
||||
|
||||
// function templates
|
||||
@ -218,30 +222,38 @@ public HSQLDialect() {
|
||||
getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
return "add column";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsIdentityColumns() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentityColumnString() {
|
||||
return "generated by default as identity (start with 1)"; //not null is implicit
|
||||
//not null is implicit
|
||||
return "generated by default as identity (start with 1)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentitySelectString() {
|
||||
return "call identity()";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentityInsertString() {
|
||||
return hsqldbVersion < 20 ? "null" : "default";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLockTimeouts() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForUpdateString() {
|
||||
if ( hsqldbVersion >= 20 ) {
|
||||
return " for update";
|
||||
@ -251,10 +263,12 @@ public String getForUpdateString() {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLimitString(String sql, boolean hasOffset) {
|
||||
if ( hsqldbVersion < 20 ) {
|
||||
return new StringBuilder( sql.length() + 10 )
|
||||
@ -266,70 +280,72 @@ public String getLimitString(String sql, boolean hasOffset) {
|
||||
.toString();
|
||||
}
|
||||
else {
|
||||
return new StringBuilder( sql.length() + 20 )
|
||||
.append( sql )
|
||||
.append( hasOffset ? " offset ? limit ?" : " limit ?" )
|
||||
.toString();
|
||||
return sql + (hasOffset ? " offset ? limit ?" : " limit ?");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean bindLimitParametersFirst() {
|
||||
return hsqldbVersion < 20;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsIfExistsAfterTableName() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsColumnCheck() {
|
||||
return hsqldbVersion >= 20;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPooledSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCreateSequenceString(String sequenceName) {
|
||||
return "create sequence " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDropSequenceString(String sequenceName) {
|
||||
return "drop sequence " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectSequenceNextValString(String sequenceName) {
|
||||
return "next value for " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSequenceNextValString(String sequenceName) {
|
||||
return "call next value for " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQuerySequencesString() {
|
||||
// this assumes schema support, which is present in 1.8.0 and later...
|
||||
return "select sequence_name from information_schema.system_sequences";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
|
||||
return hsqldbVersion < 20 ? EXTRACTER_18 : EXTRACTER_20;
|
||||
}
|
||||
|
||||
private static ViolatedConstraintNameExtracter EXTRACTER_18 = new TemplatedViolatedConstraintNameExtracter() {
|
||||
|
||||
/**
|
||||
* Extract the name of the violated constraint from the given SQLException.
|
||||
*
|
||||
* @param sqle The exception that was the result of the constraint violation.
|
||||
* @return The extracted constraint name.
|
||||
*/
|
||||
private static final ViolatedConstraintNameExtracter EXTRACTER_18 = new TemplatedViolatedConstraintNameExtracter() {
|
||||
@Override
|
||||
public String extractConstraintName(SQLException sqle) {
|
||||
String constraintName = null;
|
||||
|
||||
int errorCode = JdbcExceptionHelper.extractErrorCode( sqle );
|
||||
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqle );
|
||||
|
||||
if ( errorCode == -8 ) {
|
||||
constraintName = extractUsingTemplate(
|
||||
@ -361,12 +377,12 @@ else if ( errorCode == -177 ) {
|
||||
* HSQLDB 2.0 messages have changed
|
||||
* messages may be localized - therefore use the common, non-locale element " table: "
|
||||
*/
|
||||
private static ViolatedConstraintNameExtracter EXTRACTER_20 = new TemplatedViolatedConstraintNameExtracter() {
|
||||
|
||||
private static final ViolatedConstraintNameExtracter EXTRACTER_20 = new TemplatedViolatedConstraintNameExtracter() {
|
||||
@Override
|
||||
public String extractConstraintName(SQLException sqle) {
|
||||
String constraintName = null;
|
||||
|
||||
int errorCode = JdbcExceptionHelper.extractErrorCode( sqle );
|
||||
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqle );
|
||||
|
||||
if ( errorCode == -8 ) {
|
||||
constraintName = extractUsingTemplate(
|
||||
@ -392,23 +408,24 @@ else if ( errorCode == -177 ) {
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public String getSelectClauseNullString(int sqlType) {
|
||||
String literal;
|
||||
switch ( sqlType ) {
|
||||
case Types.LONGVARCHAR:
|
||||
case Types.LONGVARCHAR:
|
||||
case Types.VARCHAR:
|
||||
case Types.CHAR:
|
||||
literal = "cast(null as varchar(100))";
|
||||
break;
|
||||
case Types.LONGVARBINARY:
|
||||
case Types.VARBINARY:
|
||||
case Types.BINARY:
|
||||
case Types.LONGVARBINARY:
|
||||
case Types.VARBINARY:
|
||||
case Types.BINARY:
|
||||
literal = "cast(null as varbinary(100))";
|
||||
break;
|
||||
case Types.CLOB:
|
||||
case Types.CLOB:
|
||||
literal = "cast(null as clob)";
|
||||
break;
|
||||
case Types.BLOB:
|
||||
case Types.BLOB:
|
||||
literal = "cast(null as blob)";
|
||||
break;
|
||||
case Types.DATE:
|
||||
@ -417,10 +434,10 @@ public String getSelectClauseNullString(int sqlType) {
|
||||
case Types.TIMESTAMP:
|
||||
literal = "cast(null as timestamp)";
|
||||
break;
|
||||
case Types.BOOLEAN:
|
||||
case Types.BOOLEAN:
|
||||
literal = "cast(null as boolean)";
|
||||
break;
|
||||
case Types.BIT:
|
||||
case Types.BIT:
|
||||
literal = "cast(null as bit)";
|
||||
break;
|
||||
case Types.TIME:
|
||||
@ -432,11 +449,13 @@ public String getSelectClauseNullString(int sqlType) {
|
||||
return literal;
|
||||
}
|
||||
|
||||
public boolean supportsUnionAll() {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean supportsUnionAll() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// temporary table support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// Hibernate uses this information for temporary tables that it uses for its own operations
|
||||
// therefore the appropriate strategy is taken with different versions of HSQLDB
|
||||
|
||||
@ -446,37 +465,24 @@ public boolean supportsUnionAll() {
|
||||
// the definition and data is private to the session and table declaration
|
||||
// can happen in the middle of a transaction
|
||||
|
||||
/**
|
||||
* Does this dialect support temporary tables?
|
||||
*
|
||||
* @return True if temp tables are supported; false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsTemporaryTables() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* With HSQLDB 2.0, the table name is qualified with MODULE to assist the drop
|
||||
* statement (in-case there is a global name beginning with HT_)
|
||||
*
|
||||
* @param baseTableName The table name from which to base the temp table name.
|
||||
*
|
||||
* @return The generated temp table name.
|
||||
*/
|
||||
@Override
|
||||
public String generateTemporaryTableName(String baseTableName) {
|
||||
if ( hsqldbVersion < 20 ) {
|
||||
return "HT_" + baseTableName;
|
||||
}
|
||||
else {
|
||||
// With HSQLDB 2.0, the table name is qualified with MODULE to assist the drop
|
||||
// statement (in-case there is a global name beginning with HT_)
|
||||
return "MODULE.HT_" + baseTableName;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Command used to create a temporary table.
|
||||
*
|
||||
* @return The command used to create a temporary table.
|
||||
*/
|
||||
@Override
|
||||
public String getCreateTemporaryTableString() {
|
||||
if ( hsqldbVersion < 20 ) {
|
||||
return "create global temporary table";
|
||||
@ -486,40 +492,19 @@ public String getCreateTemporaryTableString() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* No fragment is needed if data is not needed beyond commit, otherwise
|
||||
* should add "on commit preserve rows"
|
||||
*
|
||||
* @return Any required postfix.
|
||||
*/
|
||||
@Override
|
||||
public String getCreateTemporaryTablePostfix() {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Command used to drop a temporary table.
|
||||
*
|
||||
* @return The command used to drop a temporary table.
|
||||
*/
|
||||
@Override
|
||||
public String getDropTemporaryTableString() {
|
||||
return "drop table";
|
||||
}
|
||||
|
||||
/**
|
||||
* Different behavior for GLOBAL TEMPORARY (1.8) and LOCAL TEMPORARY (2.0)
|
||||
* <p/>
|
||||
* Possible return values and their meanings:<ul>
|
||||
* <li>{@link Boolean#TRUE} - Unequivocally, perform the temporary table DDL
|
||||
* in isolation.</li>
|
||||
* <li>{@link Boolean#FALSE} - Unequivocally, do <b>not</b> perform the
|
||||
* temporary table DDL in isolation.</li>
|
||||
* <li><i>null</i> - defer to the JDBC driver response in regards to
|
||||
* {@link java.sql.DatabaseMetaData#dataDefinitionCausesTransactionCommit()}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @return see the result matrix above.
|
||||
*/
|
||||
@Override
|
||||
public Boolean performTemporaryTableDDLInIsolation() {
|
||||
// Different behavior for GLOBAL TEMPORARY (1.8) and LOCAL TEMPORARY (2.0)
|
||||
if ( hsqldbVersion < 20 ) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
@ -528,20 +513,13 @@ public Boolean performTemporaryTableDDLInIsolation() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do we need to drop the temporary table after use?
|
||||
*
|
||||
* todo - clarify usage by Hibernate
|
||||
*
|
||||
* Version 1.8 GLOBAL TEMPORARY table definitions persist beyond the end
|
||||
* of the session (by default, data is cleared at commit).<p>
|
||||
*
|
||||
* Version 2.x LOCAL TEMPORARY table definitions do not persist beyond
|
||||
* the end of the session (by default, data is cleared at commit).
|
||||
*
|
||||
* @return True if the table should be dropped.
|
||||
*/
|
||||
@Override
|
||||
public boolean dropTemporaryTableAfterUse() {
|
||||
// Version 1.8 GLOBAL TEMPORARY table definitions persist beyond the end
|
||||
// of the session (by default, data is cleared at commit).<p>
|
||||
//
|
||||
// Version 2.x LOCAL TEMPORARY table definitions do not persist beyond
|
||||
// the end of the session (by default, data is cleared at commit).
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -552,44 +530,25 @@ public boolean dropTemporaryTableAfterUse() {
|
||||
* be treated as a callable statement. It is equivalent to
|
||||
* "select current_timestamp from dual" in some databases.
|
||||
* HSQLDB 2.0 also supports VALUES CURRENT_TIMESTAMP
|
||||
*
|
||||
* @return True if the current timestamp can be retrieved; false otherwise.
|
||||
* <p/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsCurrentTimestampSelection() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the value returned by {@link #getCurrentTimestampSelectString}
|
||||
* be treated as callable. Typically this indicates that JDBC escape
|
||||
* syntax is being used...<p>
|
||||
*
|
||||
* CALL CURRENT_TIMESTAMP is used but this should not
|
||||
* be treated as a callable statement.
|
||||
*
|
||||
* @return True if the {@link #getCurrentTimestampSelectString} return
|
||||
* is callable; false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean isCurrentTimestampSelectStringCallable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the command used to retrieve the current timestamp from the
|
||||
* database.
|
||||
*
|
||||
* @return The command.
|
||||
*/
|
||||
@Override
|
||||
public String getCurrentTimestampSelectString() {
|
||||
return "call current_timestamp";
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the database-specific SQL function for retrieving the
|
||||
* current timestamp.
|
||||
*
|
||||
* @return The function name.
|
||||
*/
|
||||
@Override
|
||||
public String getCurrentTimestampSQLFunctionName() {
|
||||
// the standard SQL function name is current_timestamp...
|
||||
return "current_timestamp";
|
||||
@ -598,14 +557,10 @@ public String getCurrentTimestampSQLFunctionName() {
|
||||
/**
|
||||
* For HSQLDB 2.0, this is a copy of the base class implementation.
|
||||
* For HSQLDB 1.8, only READ_UNCOMMITTED is supported.
|
||||
*
|
||||
* @param lockable The persister for the entity to be locked.
|
||||
* @param lockMode The type of lock to be acquired.
|
||||
*
|
||||
* @return The appropriate locking strategy.
|
||||
*
|
||||
* @since 3.2
|
||||
* <p/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
|
||||
if ( lockMode == LockMode.PESSIMISTIC_FORCE_INCREMENT ) {
|
||||
return new PessimisticForceIncrementLockingStrategy( lockable, lockMode );
|
||||
@ -631,7 +586,7 @@ else if ( lockMode == LockMode.OPTIMISTIC_FORCE_INCREMENT ) {
|
||||
}
|
||||
}
|
||||
|
||||
public static class ReadUncommittedLockingStrategy extends SelectLockingStrategy {
|
||||
private static class ReadUncommittedLockingStrategy extends SelectLockingStrategy {
|
||||
public ReadUncommittedLockingStrategy(Lockable lockable, LockMode lockMode) {
|
||||
super( lockable, lockMode );
|
||||
}
|
||||
@ -645,6 +600,7 @@ public void lock(Serializable id, Object version, Object object, int timeout, Se
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCommentOn() {
|
||||
return hsqldbVersion >= 20;
|
||||
}
|
||||
@ -656,54 +612,32 @@ public boolean supportsEmptyInList() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* todo - needs usage clarification
|
||||
*
|
||||
* If the SELECT statement is always part of a UNION, then the type of
|
||||
* parameter is resolved by v. 2.0, but not v. 1.8 (assuming the other
|
||||
* SELECT in the UNION has a column reference in the same position and
|
||||
* can be type-resolved).
|
||||
*
|
||||
* On the other hand if the SELECT statement is isolated, all versions of
|
||||
* HSQLDB require casting for "select ? from .." to work.
|
||||
*
|
||||
* @return True if select clause parameter must be cast()ed
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
@Override
|
||||
public boolean requiresCastingOfParametersInSelectClause() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* For the underlying database, is READ_COMMITTED isolation implemented by
|
||||
* forcing readers to wait for write locks to be released?
|
||||
*
|
||||
* @return True if writers block readers to achieve READ_COMMITTED; false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean doesReadCommittedCauseWritersToBlockReaders() {
|
||||
return hsqldbVersion >= 20;
|
||||
}
|
||||
|
||||
/**
|
||||
* For the underlying database, is REPEATABLE_READ isolation implemented by
|
||||
* forcing writers to wait for read locks to be released?
|
||||
*
|
||||
* @return True if readers block writers to achieve REPEATABLE_READ; false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean doesRepeatableReadCauseReadersToBlockWriters() {
|
||||
return hsqldbVersion >= 20;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean supportsLobValueChangePropogation() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toBooleanValueString(boolean bool) {
|
||||
return String.valueOf( bool );
|
||||
}
|
||||
@Override
|
||||
public String toBooleanValueString(boolean bool) {
|
||||
return String.valueOf( bool );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTupleDistinctCounts() {
|
||||
return false;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
@ -49,68 +50,78 @@ public class InformixDialect extends Dialect {
|
||||
public InformixDialect() {
|
||||
super();
|
||||
|
||||
registerColumnType(Types.BIGINT, "int8");
|
||||
registerColumnType(Types.BINARY, "byte");
|
||||
registerColumnType(Types.BIT, "smallint"); // Informix doesn't have a bit type
|
||||
registerColumnType(Types.CHAR, "char($l)");
|
||||
registerColumnType(Types.DATE, "date");
|
||||
registerColumnType(Types.DECIMAL, "decimal");
|
||||
registerColumnType(Types.DOUBLE, "float");
|
||||
registerColumnType(Types.FLOAT, "smallfloat");
|
||||
registerColumnType(Types.INTEGER, "integer");
|
||||
registerColumnType(Types.LONGVARBINARY, "blob"); // or BYTE
|
||||
registerColumnType(Types.LONGVARCHAR, "clob"); // or TEXT?
|
||||
registerColumnType(Types.NUMERIC, "decimal"); // or MONEY
|
||||
registerColumnType(Types.REAL, "smallfloat");
|
||||
registerColumnType(Types.SMALLINT, "smallint");
|
||||
registerColumnType(Types.TIMESTAMP, "datetime year to fraction(5)");
|
||||
registerColumnType(Types.TIME, "datetime hour to second");
|
||||
registerColumnType(Types.TINYINT, "smallint");
|
||||
registerColumnType(Types.VARBINARY, "byte");
|
||||
registerColumnType(Types.VARCHAR, "varchar($l)");
|
||||
registerColumnType(Types.VARCHAR, 255, "varchar($l)");
|
||||
registerColumnType(Types.VARCHAR, 32739, "lvarchar($l)");
|
||||
registerColumnType( Types.BIGINT, "int8" );
|
||||
registerColumnType( Types.BINARY, "byte" );
|
||||
// Informix doesn't have a bit type
|
||||
registerColumnType( Types.BIT, "smallint" );
|
||||
registerColumnType( Types.CHAR, "char($l)" );
|
||||
registerColumnType( Types.DATE, "date" );
|
||||
registerColumnType( Types.DECIMAL, "decimal" );
|
||||
registerColumnType( Types.DOUBLE, "float" );
|
||||
registerColumnType( Types.FLOAT, "smallfloat" );
|
||||
registerColumnType( Types.INTEGER, "integer" );
|
||||
// or BYTE
|
||||
registerColumnType( Types.LONGVARBINARY, "blob" );
|
||||
// or TEXT?
|
||||
registerColumnType( Types.LONGVARCHAR, "clob" );
|
||||
// or MONEY
|
||||
registerColumnType( Types.NUMERIC, "decimal" );
|
||||
registerColumnType( Types.REAL, "smallfloat" );
|
||||
registerColumnType( Types.SMALLINT, "smallint" );
|
||||
registerColumnType( Types.TIMESTAMP, "datetime year to fraction(5)" );
|
||||
registerColumnType( Types.TIME, "datetime hour to second" );
|
||||
registerColumnType( Types.TINYINT, "smallint" );
|
||||
registerColumnType( Types.VARBINARY, "byte" );
|
||||
registerColumnType( Types.VARCHAR, "varchar($l)" );
|
||||
registerColumnType( Types.VARCHAR, 255, "varchar($l)" );
|
||||
registerColumnType( Types.VARCHAR, 32739, "lvarchar($l)" );
|
||||
|
||||
registerFunction( "concat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "(", "||", ")" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
return "add";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsIdentityColumns() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getIdentitySelectString(String table, String column, int type)
|
||||
throws MappingException {
|
||||
return type==Types.BIGINT ?
|
||||
"select dbinfo('serial8') from informix.systables where tabid=1" :
|
||||
"select dbinfo('sqlca.sqlerrd1') from informix.systables where tabid=1";
|
||||
@Override
|
||||
public String getIdentitySelectString(String table, String column, int type)
|
||||
throws MappingException {
|
||||
return type == Types.BIGINT
|
||||
? "select dbinfo('serial8') from informix.systables where tabid=1"
|
||||
: "select dbinfo('sqlca.sqlerrd1') from informix.systables where tabid=1";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentityColumnString(int type) throws MappingException {
|
||||
return type==Types.BIGINT ?
|
||||
"serial8 not null" :
|
||||
"serial not null";
|
||||
return type == Types.BIGINT ?
|
||||
"serial8 not null" :
|
||||
"serial not null";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDataTypeInIdentityColumn() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The syntax used to add a foreign key constraint to a table.
|
||||
* Informix constraint name must be at the end.
|
||||
* @return String
|
||||
* <p/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getAddForeignKeyConstraintString(
|
||||
String constraintName,
|
||||
String[] foreignKey,
|
||||
String referencedTable,
|
||||
String[] primaryKey,
|
||||
boolean referencesPrimaryKey) {
|
||||
StringBuilder result = new StringBuilder( 30 )
|
||||
final StringBuilder result = new StringBuilder( 30 )
|
||||
.append( " add constraint " )
|
||||
.append( " foreign key (" )
|
||||
.append( StringHelper.join( ", ", foreignKey ) )
|
||||
@ -129,53 +140,66 @@ public String getAddForeignKeyConstraintString(
|
||||
}
|
||||
|
||||
/**
|
||||
* The syntax used to add a primary key constraint to a table.
|
||||
* Informix constraint name must be at the end.
|
||||
* @return String
|
||||
* <p/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getAddPrimaryKeyConstraintString(String constraintName) {
|
||||
return " add constraint primary key constraint " + constraintName + " ";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateSequenceString(String sequenceName) {
|
||||
return "create sequence " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDropSequenceString(String sequenceName) {
|
||||
return "drop sequence " + sequenceName + " restrict";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSequenceNextValString(String sequenceName) {
|
||||
return "select " + getSelectSequenceNextValString( sequenceName ) + " from informix.systables where tabid=1";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectSequenceNextValString(String sequenceName) {
|
||||
return sequenceName + ".nextval";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPooledSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQuerySequencesString() {
|
||||
return "select tabname from informix.systables where tabtype='Q'";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useMaxForLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLimitOffset() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLimitString(String querySelect, int offset, int limit) {
|
||||
if ( offset > 0 ) {
|
||||
throw new UnsupportedOperationException( "query result offset is not supported" );
|
||||
@ -186,41 +210,45 @@ public String getLimitString(String querySelect, int offset, int limit) {
|
||||
.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsVariableLimit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
|
||||
return EXTRACTER;
|
||||
return EXTRACTER;
|
||||
}
|
||||
|
||||
private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
|
||||
|
||||
/**
|
||||
* Extract the name of the violated constraint from the given SQLException.
|
||||
*
|
||||
* @param sqle The exception that was the result of the constraint violation.
|
||||
* @return The extracted constraint name.
|
||||
*/
|
||||
private static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
|
||||
@Override
|
||||
public String extractConstraintName(SQLException sqle) {
|
||||
String constraintName = null;
|
||||
|
||||
int errorCode = JdbcExceptionHelper.extractErrorCode( sqle );
|
||||
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqle );
|
||||
|
||||
if ( errorCode == -268 ) {
|
||||
constraintName = extractUsingTemplate( "Unique constraint (", ") violated.", sqle.getMessage() );
|
||||
}
|
||||
else if ( errorCode == -691 ) {
|
||||
constraintName = extractUsingTemplate( "Missing key in referenced table for referential constraint (", ").", sqle.getMessage() );
|
||||
constraintName = extractUsingTemplate(
|
||||
"Missing key in referenced table for referential constraint (",
|
||||
").",
|
||||
sqle.getMessage()
|
||||
);
|
||||
}
|
||||
else if ( errorCode == -692 ) {
|
||||
constraintName = extractUsingTemplate( "Key value for constraint (", ") is still being referenced.", sqle.getMessage() );
|
||||
constraintName = extractUsingTemplate(
|
||||
"Key value for constraint (",
|
||||
") is still being referenced.",
|
||||
sqle.getMessage()
|
||||
);
|
||||
}
|
||||
|
||||
if (constraintName != null) {
|
||||
|
||||
if ( constraintName != null ) {
|
||||
// strip table-owner because Informix always returns constraint names as "<table-owner>.<constraint-name>"
|
||||
int i = constraintName.indexOf('.');
|
||||
if (i != -1) {
|
||||
constraintName = constraintName.substring(i + 1);
|
||||
final int i = constraintName.indexOf( '.' );
|
||||
if ( i != -1 ) {
|
||||
constraintName = constraintName.substring( i + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
@ -229,46 +257,33 @@ else if ( errorCode == -692 ) {
|
||||
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean supportsCurrentTimestampSelection() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurrentTimestampSelectStringCallable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentTimestampSelectString() {
|
||||
return "select distinct current timestamp from informix.systables";
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides {@link Dialect#supportsTemporaryTables()} to return
|
||||
* {@code true} when invoked.
|
||||
*
|
||||
* @return {@code true} when invoked
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsTemporaryTables() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides {@link Dialect#getCreateTemporaryTableString()} to
|
||||
* return "{@code create temp table}" when invoked.
|
||||
*
|
||||
* @return "{@code create temp table}" when invoked
|
||||
*/
|
||||
@Override
|
||||
public String getCreateTemporaryTableString() {
|
||||
return "create temp table";
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides {@link Dialect#getCreateTemporaryTablePostfix()} to
|
||||
* return "{@code with no log}" when invoked.
|
||||
*
|
||||
* @return "{@code with no log}" when invoked
|
||||
*/
|
||||
@Override
|
||||
public String getCreateTemporaryTablePostfix() {
|
||||
return "with no log";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.Types;
|
||||
import java.util.Properties;
|
||||
|
||||
@ -39,62 +40,62 @@
|
||||
* @author Raymond Fan
|
||||
*/
|
||||
public class Ingres10Dialect extends Ingres9Dialect {
|
||||
public Ingres10Dialect() {
|
||||
super();
|
||||
registerBooleanSupport();
|
||||
}
|
||||
/**
|
||||
* Constructs a Ingres10Dialect
|
||||
*/
|
||||
public Ingres10Dialect() {
|
||||
super();
|
||||
registerBooleanSupport();
|
||||
registerDefaultProperties();
|
||||
}
|
||||
|
||||
// Boolean column type support
|
||||
protected void registerBooleanSupport() {
|
||||
// Boolean type (mapping/BooleanType) mapping maps SQL BIT to Java
|
||||
// Boolean. In order to create a boolean column, BIT needs to be mapped
|
||||
// to boolean as well, similar to H2Dialect.
|
||||
registerColumnType( Types.BIT, "boolean" );
|
||||
registerColumnType( Types.BOOLEAN, "boolean" );
|
||||
}
|
||||
|
||||
/**
|
||||
* The SQL literal value to which this database maps boolean values.
|
||||
*
|
||||
* @param bool The boolean value
|
||||
* @return The appropriate SQL literal.
|
||||
*/
|
||||
public String toBooleanValueString(boolean bool) {
|
||||
return bool ? "true" : "false";
|
||||
}
|
||||
|
||||
protected void registerBooleanSupport() {
|
||||
// Column type
|
||||
|
||||
// Boolean type (mapping/BooleanType) mapping maps SQL BIT to Java
|
||||
// Boolean. In order to create a boolean column, BIT needs to be mapped
|
||||
// to boolean as well, similar to H2Dialect.
|
||||
registerColumnType( Types.BIT, "boolean" );
|
||||
registerColumnType( Types.BOOLEAN, "boolean" );
|
||||
|
||||
// Functions
|
||||
|
||||
// true, false and unknown are now valid values
|
||||
// Remove the query substitutions previously added in IngresDialect.
|
||||
Properties properties = getDefaultProperties();
|
||||
String querySubst = properties.getProperty(Environment.QUERY_SUBSTITUTIONS);
|
||||
if (querySubst != null) {
|
||||
String newQuerySubst = querySubst.replace("true=1,false=0","");
|
||||
properties.setProperty(Environment.QUERY_SUBSTITUTIONS, newQuerySubst);
|
||||
}
|
||||
}
|
||||
private void registerDefaultProperties() {
|
||||
// true, false and unknown are now valid values
|
||||
// Remove the query substitutions previously added in IngresDialect.
|
||||
final Properties properties = getDefaultProperties();
|
||||
final String querySubst = properties.getProperty( Environment.QUERY_SUBSTITUTIONS );
|
||||
if ( querySubst != null ) {
|
||||
final String newQuerySubst = querySubst.replace( "true=1,false=0", "" );
|
||||
properties.setProperty( Environment.QUERY_SUBSTITUTIONS, newQuerySubst );
|
||||
}
|
||||
}
|
||||
|
||||
// IDENTITY support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public String toBooleanValueString(boolean bool) {
|
||||
return bool ? "true" : "false";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsIdentityColumns() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDataTypeInIdentityColumn() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentitySelectString() {
|
||||
return "select last_identity()";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentityColumnString() {
|
||||
return "not null generated by default as identity";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentityInsertString() {
|
||||
return "default";
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.dialect.function.NoArgSQLFunction;
|
||||
@ -30,7 +31,7 @@
|
||||
|
||||
/**
|
||||
* A SQL dialect for Ingres 9.3 and later versions.
|
||||
* <p />
|
||||
* <p/>
|
||||
* Changes:
|
||||
* <ul>
|
||||
* <li>Support for the SQL functions current_time, current_timestamp and current_date added</li>
|
||||
@ -41,212 +42,143 @@
|
||||
* <li>Added getIdentitySelectString</li>
|
||||
* <li>Modified concatination operator</li>
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* @author Enrico Schenk
|
||||
* @author Raymond Fan
|
||||
*/
|
||||
public class Ingres9Dialect extends IngresDialect {
|
||||
public Ingres9Dialect() {
|
||||
super();
|
||||
registerDateTimeFunctions();
|
||||
registerDateTimeColumnTypes();
|
||||
registerFunction( "concat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "(", "||", ")" ) );
|
||||
}
|
||||
/**
|
||||
* Constructs a Ingres9Dialect
|
||||
*/
|
||||
public Ingres9Dialect() {
|
||||
super();
|
||||
registerDateTimeFunctions();
|
||||
registerDateTimeColumnTypes();
|
||||
registerFunction( "concat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "(", "||", ")" ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register functions current_time, current_timestamp, current_date
|
||||
*/
|
||||
protected void registerDateTimeFunctions() {
|
||||
registerFunction("current_time", new NoArgSQLFunction("current_time", StandardBasicTypes.TIME, false));
|
||||
registerFunction("current_timestamp", new NoArgSQLFunction("current_timestamp", StandardBasicTypes.TIMESTAMP, false));
|
||||
registerFunction("current_date", new NoArgSQLFunction("current_date", StandardBasicTypes.DATE, false));
|
||||
registerFunction( "current_time", new NoArgSQLFunction( "current_time", StandardBasicTypes.TIME, false ) );
|
||||
registerFunction(
|
||||
"current_timestamp", new NoArgSQLFunction(
|
||||
"current_timestamp",
|
||||
StandardBasicTypes.TIMESTAMP,
|
||||
false
|
||||
)
|
||||
);
|
||||
registerFunction( "current_date", new NoArgSQLFunction( "current_date", StandardBasicTypes.DATE, false ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register column types date, time, timestamp
|
||||
*/
|
||||
protected void registerDateTimeColumnTypes() {
|
||||
registerColumnType(Types.DATE, "ansidate");
|
||||
registerColumnType(Types.TIMESTAMP, "timestamp(9) with time zone");
|
||||
registerColumnType( Types.DATE, "ansidate" );
|
||||
registerColumnType( Types.TIMESTAMP, "timestamp(9) with time zone" );
|
||||
}
|
||||
|
||||
// lock acquisition support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
* Does this dialect support <tt>FOR UPDATE</tt> in conjunction with outer
|
||||
* joined rows?
|
||||
*
|
||||
* @return True if outer joined rows can be locked via <tt>FOR UPDATE</tt>.
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsOuterJoinForUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is <tt>FOR UPDATE OF</tt> syntax supported?
|
||||
*
|
||||
* @return True if the database supports <tt>FOR UPDATE OF</tt> syntax;
|
||||
* false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean forUpdateOfColumns() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// SEQUENCE support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
* Get the select command used to retrieve the last generated sequence
|
||||
* value.
|
||||
*
|
||||
* @return Statement to retrieve last generated sequence value
|
||||
*/
|
||||
public String getIdentitySelectString() {
|
||||
return "select last_identity()";
|
||||
}
|
||||
@Override
|
||||
public String getIdentitySelectString() {
|
||||
return "select last_identity()";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the select command used retrieve the names of all sequences.
|
||||
*
|
||||
* @return The select command; or null if sequences are not supported.
|
||||
* @see org.hibernate.tool.hbm2ddl.SchemaUpdate
|
||||
*/
|
||||
@Override
|
||||
public String getQuerySequencesString() {
|
||||
return "select seq_name from iisequences";
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this dialect support "pooled" sequences. Not aware of a better name
|
||||
* for this. Essentially can we specify the initial and increment values?
|
||||
*
|
||||
* @return True if such "pooled" sequences are supported; false otherwise.
|
||||
* @see #getCreateSequenceStrings(String, int, int)
|
||||
* @see #getCreateSequenceString(String, int, int)
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsPooledSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// current timestamp support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
* Should the value returned by {@link #getCurrentTimestampSelectString} be
|
||||
* treated as callable. Typically this indicates that JDBC escape sytnax is
|
||||
* being used...
|
||||
*
|
||||
* @return True if the {@link #getCurrentTimestampSelectString} return is
|
||||
* callable; false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean isCurrentTimestampSelectStringCallable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this dialect support a way to retrieve the database's current
|
||||
* timestamp value?
|
||||
*
|
||||
* @return True if the current timestamp can be retrieved; false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsCurrentTimestampSelection() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the command used to retrieve the current timestammp from the
|
||||
* database.
|
||||
*
|
||||
* @return The command.
|
||||
*/
|
||||
@Override
|
||||
public String getCurrentTimestampSelectString() {
|
||||
return "select current_timestamp";
|
||||
}
|
||||
|
||||
/**
|
||||
* Expression for current_timestamp
|
||||
*/
|
||||
@Override
|
||||
public String getCurrentTimestampSQLFunctionName() {
|
||||
return "current_timestamp";
|
||||
}
|
||||
|
||||
// union subclass support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
* Does this dialect support UNION ALL, which is generally a faster variant
|
||||
* of UNION?
|
||||
*
|
||||
* @return True if UNION ALL is supported; false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsUnionAll() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
* For the underlying database, is READ_COMMITTED isolation implemented by
|
||||
* forcing readers to wait for write locks to be released?
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean doesReadCommittedCauseWritersToBlockReaders() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* For the underlying database, is REPEATABLE_READ isolation implemented by
|
||||
* forcing writers to wait for read locks to be released?
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean doesRepeatableReadCauseReadersToBlockWriters() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// limit/offset support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
* Does this dialect's LIMIT support (if any) additionally support
|
||||
* specifying an offset?
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsLimitOffset() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this dialect support bind variables (i.e., prepared statememnt
|
||||
* parameters) for its limit/offset?
|
||||
*
|
||||
* @return false
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsVariableLimit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the <tt>LIMIT</tt> clause take a "maximum" row number instead
|
||||
* of a total number of returned rows?
|
||||
*/
|
||||
@Override
|
||||
public boolean useMaxForLimit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a <tt>LIMIT</tt> clause to the given SQL <tt>SELECT</tt>
|
||||
*
|
||||
* @return the modified SQL
|
||||
*/
|
||||
@Override
|
||||
public String getLimitString(String querySelect, int offset, int limit) {
|
||||
StringBuilder soff = new StringBuilder(" offset " + offset);
|
||||
StringBuilder slim = new StringBuilder(" fetch first " + limit + " rows only");
|
||||
StringBuilder sb = new StringBuilder(querySelect.length() +
|
||||
soff.length() + slim.length()).append(querySelect);
|
||||
if (offset > 0) {
|
||||
sb.append(soff);
|
||||
final StringBuilder soff = new StringBuilder( " offset " + offset );
|
||||
final StringBuilder slim = new StringBuilder( " fetch first " + limit + " rows only" );
|
||||
final StringBuilder sb = new StringBuilder( querySelect.length() + soff.length() + slim.length() )
|
||||
.append( querySelect );
|
||||
if ( offset > 0 ) {
|
||||
sb.append( soff );
|
||||
}
|
||||
if ( limit > 0 ) {
|
||||
sb.append( slim );
|
||||
}
|
||||
if (limit > 0) {
|
||||
sb.append(slim);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.cfg.Environment;
|
||||
@ -34,12 +35,20 @@
|
||||
/**
|
||||
* An SQL dialect for Ingres 9.2.
|
||||
* <p/>
|
||||
* Known limitations:
|
||||
* <ul>
|
||||
* <li> Only supports simple constants or columns on the left side of an IN, making (1,2,3) in (...) or (<subselect>) in (...) non-supported.
|
||||
* <li> Supports only 39 digits in decimal.
|
||||
* <li> Explicitly set USE_GET_GENERATED_KEYS property to false.
|
||||
* <li> Perform string casts to varchar; removes space padding.
|
||||
* Known limitations: <ul>
|
||||
* <li>
|
||||
* Only supports simple constants or columns on the left side of an IN,
|
||||
* making {@code (1,2,3) in (...)} or {@code (subselect) in (...)} non-supported.
|
||||
* </li>
|
||||
* <li>
|
||||
* Supports only 39 digits in decimal.
|
||||
* </li>
|
||||
* <li>
|
||||
* Explicitly set USE_GET_GENERATED_KEYS property to false.
|
||||
* </li>
|
||||
* <li>
|
||||
* Perform string casts to varchar; removes space padding.
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Ian Booth
|
||||
@ -47,8 +56,11 @@
|
||||
* @author Max Rydahl Andersen
|
||||
* @author Raymond Fan
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class IngresDialect extends Dialect {
|
||||
|
||||
/**
|
||||
* Constructs a IngresDialect
|
||||
*/
|
||||
public IngresDialect() {
|
||||
super();
|
||||
registerColumnType( Types.BIT, "tinyint" );
|
||||
@ -145,145 +157,89 @@ public IngresDialect() {
|
||||
// maximum width of a value for that return type. Casting to varchar
|
||||
// does not introduce space padding.
|
||||
registerFunction( "str", new SQLFunctionTemplate(StandardBasicTypes.STRING, "cast(?1 as varchar)") );
|
||||
// Ingres driver supports getGeneratedKeys but only in the following
|
||||
// form:
|
||||
// The Ingres DBMS returns only a single table key or a single object
|
||||
// key per insert statement. Ingres does not return table and object
|
||||
// keys for INSERT AS SELECT statements. Depending on the keys that are
|
||||
// produced by the statement executed, auto-generated key parameters in
|
||||
// execute(), executeUpdate(), and prepareStatement() methods are
|
||||
// ignored and getGeneratedKeys() returns a result-set containing no
|
||||
// rows, a single row with one column, or a single row with two columns.
|
||||
// Ingres JDBC Driver returns table and object keys as BINARY values.
|
||||
getDefaultProperties().setProperty(Environment.USE_GET_GENERATED_KEYS, "false");
|
||||
// There is no support for a native boolean type that accepts values
|
||||
// of true, false or unknown. Using the tinyint type requires
|
||||
// substitions of true and false.
|
||||
getDefaultProperties().setProperty(Environment.QUERY_SUBSTITUTIONS, "true=1,false=0");
|
||||
// Ingres driver supports getGeneratedKeys but only in the following
|
||||
// form:
|
||||
// The Ingres DBMS returns only a single table key or a single object
|
||||
// key per insert statement. Ingres does not return table and object
|
||||
// keys for INSERT AS SELECT statements. Depending on the keys that are
|
||||
// produced by the statement executed, auto-generated key parameters in
|
||||
// execute(), executeUpdate(), and prepareStatement() methods are
|
||||
// ignored and getGeneratedKeys() returns a result-set containing no
|
||||
// rows, a single row with one column, or a single row with two columns.
|
||||
// Ingres JDBC Driver returns table and object keys as BINARY values.
|
||||
getDefaultProperties().setProperty( Environment.USE_GET_GENERATED_KEYS, "false" );
|
||||
// There is no support for a native boolean type that accepts values
|
||||
// of true, false or unknown. Using the tinyint type requires
|
||||
// substitions of true and false.
|
||||
getDefaultProperties().setProperty( Environment.QUERY_SUBSTITUTIONS, "true=1,false=0" );
|
||||
}
|
||||
/**
|
||||
* Expression for created UUID string
|
||||
*/
|
||||
|
||||
@Override
|
||||
public String getSelectGUIDString() {
|
||||
return "select uuid_to_char(uuid_create())";
|
||||
}
|
||||
/**
|
||||
* Do we need to drop constraints before dropping tables in this dialect?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean dropConstraints() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this dialect support <tt>FOR UPDATE OF</tt>, allowing
|
||||
* particular rows to be locked?
|
||||
*
|
||||
* @return True (Ingres does support "for update of" syntax...)
|
||||
*/
|
||||
public boolean supportsForUpdateOf() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The syntax used to add a column to a table (optional).
|
||||
*/
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
return "add column";
|
||||
}
|
||||
|
||||
/**
|
||||
* The keyword used to specify a nullable column.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
@Override
|
||||
public String getNullColumnString() {
|
||||
return " with null";
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this dialect support sequences?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The syntax that fetches the next value of a sequence, if sequences are supported.
|
||||
*
|
||||
* @param sequenceName the name of the sequence
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
@Override
|
||||
public String getSequenceNextValString(String sequenceName) {
|
||||
return "select nextval for " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectSequenceNextValString(String sequenceName) {
|
||||
return sequenceName + ".nextval";
|
||||
}
|
||||
|
||||
/**
|
||||
* The syntax used to create a sequence, if sequences are supported.
|
||||
*
|
||||
* @param sequenceName the name of the sequence
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
@Override
|
||||
public String getCreateSequenceString(String sequenceName) {
|
||||
return "create sequence " + sequenceName;
|
||||
}
|
||||
|
||||
/**
|
||||
* The syntax used to drop a sequence, if sequences are supported.
|
||||
*
|
||||
* @param sequenceName the name of the sequence
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
@Override
|
||||
public String getDropSequenceString(String sequenceName) {
|
||||
return "drop sequence " + sequenceName + " restrict";
|
||||
}
|
||||
|
||||
/**
|
||||
* A query used to find all sequences
|
||||
*/
|
||||
@Override
|
||||
public String getQuerySequencesString() {
|
||||
return "select seq_name from iisequence";
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the SQL function that transforms a string to
|
||||
* lowercase
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
@Override
|
||||
public String getLowercaseFunction() {
|
||||
return "lowercase";
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this <tt>Dialect</tt> have some kind of <tt>LIMIT</tt> syntax?
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this dialect support an offset?
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsLimitOffset() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a <tt>LIMIT</tt> clause to the given SQL <tt>SELECT</tt>
|
||||
*
|
||||
* @return the modified SQL
|
||||
*/
|
||||
@Override
|
||||
public String getLimitString(String querySelect, int offset, int limit) {
|
||||
if ( offset > 0 ) {
|
||||
throw new UnsupportedOperationException( "query result offset is not supported" );
|
||||
@ -294,64 +250,59 @@ public String getLimitString(String querySelect, int offset, int limit) {
|
||||
.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsVariableLimit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the <tt>LIMIT</tt> clause take a "maximum" row number instead
|
||||
* of a total number of returned rows?
|
||||
*/
|
||||
@Override
|
||||
public boolean useMaxForLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this dialect support temporary tables?
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsTemporaryTables() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateTemporaryTableString() {
|
||||
return "declare global temporary table";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateTemporaryTablePostfix() {
|
||||
return "on commit preserve rows with norecovery";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateTemporaryTableName(String baseTableName) {
|
||||
return "session." + super.generateTemporaryTableName( baseTableName );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Expression for current_timestamp
|
||||
*/
|
||||
@Override
|
||||
public String getCurrentTimestampSQLFunctionName() {
|
||||
return "date(now)";
|
||||
}
|
||||
|
||||
// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public boolean supportsSubselectAsInPredicateLHS() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsEmptyInList() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsExpectedLobUsagePattern () {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ingres does not support the syntax `count(distinct a,b)`?
|
||||
*
|
||||
* @return False, not supported.
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsTupleDistinctCounts() {
|
||||
return false;
|
||||
}
|
||||
|
@ -34,8 +34,12 @@
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class InterbaseDialect extends Dialect {
|
||||
|
||||
/**
|
||||
* Constructs a InterbaseDialect
|
||||
*/
|
||||
public InterbaseDialect() {
|
||||
super();
|
||||
registerColumnType( Types.BIT, "smallint" );
|
||||
@ -56,63 +60,78 @@ public InterbaseDialect() {
|
||||
registerColumnType( Types.CLOB, "blob sub_type 1" );
|
||||
|
||||
registerFunction( "concat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "(","||",")" ) );
|
||||
registerFunction("current_date", new NoArgSQLFunction("current_date", StandardBasicTypes.DATE, false) );
|
||||
registerFunction( "current_date", new NoArgSQLFunction( "current_date", StandardBasicTypes.DATE, false ) );
|
||||
|
||||
getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH);
|
||||
getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, NO_BATCH );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
return "add";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSequenceNextValString(String sequenceName) {
|
||||
return "select " + getSelectSequenceNextValString( sequenceName ) + " from RDB$DATABASE";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectSequenceNextValString(String sequenceName) {
|
||||
return "gen_id( " + sequenceName + ", 1 )";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateSequenceString(String sequenceName) {
|
||||
return "create generator " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDropSequenceString(String sequenceName) {
|
||||
return "delete from RDB$GENERATORS where RDB$GENERATOR_NAME = '" + sequenceName.toUpperCase() + "'";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQuerySequencesString() {
|
||||
return "select RDB$GENERATOR_NAME from RDB$GENERATORS";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getForUpdateString() {
|
||||
return " with lock";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForUpdateString(String aliases) {
|
||||
return " for update of " + aliases + " with lock";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLimitString(String sql, boolean hasOffset) {
|
||||
return hasOffset ? sql + " rows ? to ?" : sql + " rows ?";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean bindLimitParametersFirst() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean bindLimitParametersInReverseOrder() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getCurrentTimestampCallString() {
|
||||
@Override
|
||||
public String getCurrentTimestampSelectString() {
|
||||
// TODO : not sure which (either?) is correct, could not find docs on how to do this.
|
||||
// did find various blogs and forums mentioning that select CURRENT_TIMESTAMP
|
||||
// does not work...
|
||||
@ -120,7 +139,8 @@ public String getCurrentTimestampCallString() {
|
||||
// return "select CURRENT_TIMESTAMP from RDB$DATABASE";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurrentTimestampSelectStringCallable() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,17 +22,17 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.cfg.Environment;
|
||||
|
||||
/**
|
||||
* A <tt>Dialect</tt> for JDataStore.
|
||||
* A Dialect for JDataStore.
|
||||
*
|
||||
* @author Vishy Kasar
|
||||
*/
|
||||
public class JDataStoreDialect extends Dialect {
|
||||
|
||||
/**
|
||||
* Creates new JDataStoreDialect
|
||||
*/
|
||||
@ -60,38 +60,48 @@ public JDataStoreDialect() {
|
||||
getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
return "add";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dropConstraints() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCascadeConstraintsString() {
|
||||
return " cascade";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsIdentityColumns() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentitySelectString() {
|
||||
return null; // NOT_SUPPORTED_SHOULD_USE_JDBC3_PreparedStatement.getGeneratedKeys_method
|
||||
// NOT_SUPPORTED_SHOULD_USE_JDBC3_PreparedStatement.getGeneratedKeys_method
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentityColumnString() {
|
||||
return "autoincrement";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNoColumnsInsertString() {
|
||||
return "default values";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsColumnCheck() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTableCheck() {
|
||||
return false;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
@ -47,6 +48,9 @@
|
||||
* @author Gabe Hicks
|
||||
*/
|
||||
public class MckoiDialect extends Dialect {
|
||||
/**
|
||||
* Constructs a MckoiDialect
|
||||
*/
|
||||
public MckoiDialect() {
|
||||
super();
|
||||
registerColumnType( Types.BIT, "bit" );
|
||||
@ -78,41 +82,50 @@ public MckoiDialect() {
|
||||
registerFunction( "user", new StandardSQLFunction( "user", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "concat", new StandardSQLFunction( "concat", StandardBasicTypes.STRING ) );
|
||||
|
||||
getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH);
|
||||
getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, NO_BATCH );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
return "add column";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSequenceNextValString(String sequenceName) {
|
||||
return "select " + getSelectSequenceNextValString( sequenceName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectSequenceNextValString(String sequenceName) {
|
||||
return "nextval('" + sequenceName + "')";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateSequenceString(String sequenceName) {
|
||||
return "create sequence " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDropSequenceString(String sequenceName) {
|
||||
return "drop sequence " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForUpdateString() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CaseFragment createCaseFragment() {
|
||||
return new MckoiCaseFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
|
||||
// Mckoi has no known variation of a "SELECT ... FOR UPDATE" syntax...
|
||||
if ( lockMode==LockMode.PESSIMISTIC_FORCE_INCREMENT) {
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
/**
|
||||
@ -30,19 +31,15 @@
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class MySQL5Dialect extends MySQLDialect {
|
||||
@Override
|
||||
protected void registerVarcharTypes() {
|
||||
registerColumnType( Types.VARCHAR, "longtext" );
|
||||
// registerColumnType( Types.VARCHAR, 16777215, "mediumtext" );
|
||||
registerColumnType( Types.VARCHAR, 65535, "varchar($l)" );
|
||||
registerColumnType( Types.LONGVARCHAR, "longtext" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this dialect support column-level check constraints?
|
||||
*
|
||||
* @return True if column-level CHECK constraints are supported; false
|
||||
* otherwise.
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean supportsColumnCheck() {
|
||||
return false;
|
||||
}
|
||||
|
@ -23,22 +23,24 @@
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
|
||||
/**
|
||||
* @author Gavin King, Scott Marlow
|
||||
/** A Dialect for MySQL 5 using InnoDB engine
|
||||
*
|
||||
* @author Gavin King,
|
||||
* @author Scott Marlow
|
||||
*/
|
||||
public class MySQL5InnoDBDialect extends MySQL5Dialect {
|
||||
|
||||
@Override
|
||||
public boolean supportsCascadeDelete() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getTableTypeString() {
|
||||
return " ENGINE=InnoDB";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSelfReferentialForeignKeyBug() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -45,8 +45,12 @@
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class MySQLDialect extends Dialect {
|
||||
|
||||
/**
|
||||
* Constructs a MySQLDialect
|
||||
*/
|
||||
public MySQLDialect() {
|
||||
super();
|
||||
registerColumnType( Types.BIT, "bit" );
|
||||
@ -64,7 +68,7 @@ public MySQLDialect() {
|
||||
registerColumnType( Types.VARBINARY, 16777215, "mediumblob" );
|
||||
registerColumnType( Types.VARBINARY, 65535, "blob" );
|
||||
registerColumnType( Types.VARBINARY, 255, "tinyblob" );
|
||||
registerColumnType( Types.BINARY, "binary($l)" );
|
||||
registerColumnType( Types.BINARY, "binary($l)" );
|
||||
registerColumnType( Types.LONGVARBINARY, "longblob" );
|
||||
registerColumnType( Types.LONGVARBINARY, 16777215, "mediumblob" );
|
||||
registerColumnType( Types.NUMERIC, "decimal($p,$s)" );
|
||||
@ -76,111 +80,111 @@ public MySQLDialect() {
|
||||
// registerColumnType( Types.CLOB, 65535, "text" );
|
||||
registerVarcharTypes();
|
||||
|
||||
registerFunction("ascii", new StandardSQLFunction("ascii", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("bin", new StandardSQLFunction("bin", StandardBasicTypes.STRING) );
|
||||
registerFunction("char_length", new StandardSQLFunction("char_length", StandardBasicTypes.LONG) );
|
||||
registerFunction("character_length", new StandardSQLFunction("character_length", StandardBasicTypes.LONG) );
|
||||
registerFunction("lcase", new StandardSQLFunction("lcase") );
|
||||
registerFunction("lower", new StandardSQLFunction("lower") );
|
||||
registerFunction("ltrim", new StandardSQLFunction("ltrim") );
|
||||
registerFunction("ord", new StandardSQLFunction("ord", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("quote", new StandardSQLFunction("quote") );
|
||||
registerFunction("reverse", new StandardSQLFunction("reverse") );
|
||||
registerFunction("rtrim", new StandardSQLFunction("rtrim") );
|
||||
registerFunction("soundex", new StandardSQLFunction("soundex") );
|
||||
registerFunction("space", new StandardSQLFunction("space", StandardBasicTypes.STRING) );
|
||||
registerFunction("ucase", new StandardSQLFunction("ucase") );
|
||||
registerFunction("upper", new StandardSQLFunction("upper") );
|
||||
registerFunction("unhex", new StandardSQLFunction("unhex", StandardBasicTypes.STRING) );
|
||||
registerFunction( "ascii", new StandardSQLFunction( "ascii", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "bin", new StandardSQLFunction( "bin", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "char_length", new StandardSQLFunction( "char_length", StandardBasicTypes.LONG ) );
|
||||
registerFunction( "character_length", new StandardSQLFunction( "character_length", StandardBasicTypes.LONG ) );
|
||||
registerFunction( "lcase", new StandardSQLFunction( "lcase" ) );
|
||||
registerFunction( "lower", new StandardSQLFunction( "lower" ) );
|
||||
registerFunction( "ltrim", new StandardSQLFunction( "ltrim" ) );
|
||||
registerFunction( "ord", new StandardSQLFunction( "ord", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "quote", new StandardSQLFunction( "quote" ) );
|
||||
registerFunction( "reverse", new StandardSQLFunction( "reverse" ) );
|
||||
registerFunction( "rtrim", new StandardSQLFunction( "rtrim" ) );
|
||||
registerFunction( "soundex", new StandardSQLFunction( "soundex" ) );
|
||||
registerFunction( "space", new StandardSQLFunction( "space", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "ucase", new StandardSQLFunction( "ucase" ) );
|
||||
registerFunction( "upper", new StandardSQLFunction( "upper" ) );
|
||||
registerFunction( "unhex", new StandardSQLFunction( "unhex", StandardBasicTypes.STRING ) );
|
||||
|
||||
registerFunction("abs", new StandardSQLFunction("abs") );
|
||||
registerFunction("sign", new StandardSQLFunction("sign", StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "abs", new StandardSQLFunction( "abs" ) );
|
||||
registerFunction( "sign", new StandardSQLFunction( "sign", StandardBasicTypes.INTEGER ) );
|
||||
|
||||
registerFunction("acos", new StandardSQLFunction("acos", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("asin", new StandardSQLFunction("asin", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("atan", new StandardSQLFunction("atan", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("cos", new StandardSQLFunction("cos", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("cot", new StandardSQLFunction("cot", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("crc32", new StandardSQLFunction("crc32", StandardBasicTypes.LONG) );
|
||||
registerFunction("exp", new StandardSQLFunction("exp", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("ln", new StandardSQLFunction("ln", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("log", new StandardSQLFunction("log", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("log2", new StandardSQLFunction("log2", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("log10", new StandardSQLFunction("log10", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("pi", new NoArgSQLFunction("pi", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("rand", new NoArgSQLFunction("rand", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("sin", new StandardSQLFunction("sin", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("sqrt", new StandardSQLFunction("sqrt", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("tan", new StandardSQLFunction("tan", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "acos", new StandardSQLFunction( "acos", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "asin", new StandardSQLFunction( "asin", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "atan", new StandardSQLFunction( "atan", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "cos", new StandardSQLFunction( "cos", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "cot", new StandardSQLFunction( "cot", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "crc32", new StandardSQLFunction( "crc32", StandardBasicTypes.LONG ) );
|
||||
registerFunction( "exp", new StandardSQLFunction( "exp", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "ln", new StandardSQLFunction( "ln", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "log", new StandardSQLFunction( "log", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "log2", new StandardSQLFunction( "log2", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "log10", new StandardSQLFunction( "log10", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "pi", new NoArgSQLFunction( "pi", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "rand", new NoArgSQLFunction( "rand", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "sin", new StandardSQLFunction( "sin", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "sqrt", new StandardSQLFunction( "sqrt", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "tan", new StandardSQLFunction( "tan", StandardBasicTypes.DOUBLE ) );
|
||||
|
||||
registerFunction("radians", new StandardSQLFunction("radians", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("degrees", new StandardSQLFunction("degrees", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "radians", new StandardSQLFunction( "radians", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "degrees", new StandardSQLFunction( "degrees", StandardBasicTypes.DOUBLE ) );
|
||||
|
||||
registerFunction("ceiling", new StandardSQLFunction("ceiling", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("ceil", new StandardSQLFunction("ceil", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("floor", new StandardSQLFunction("floor", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("round", new StandardSQLFunction("round") );
|
||||
registerFunction( "ceiling", new StandardSQLFunction( "ceiling", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "ceil", new StandardSQLFunction( "ceil", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "floor", new StandardSQLFunction( "floor", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "round", new StandardSQLFunction( "round" ) );
|
||||
|
||||
registerFunction("datediff", new StandardSQLFunction("datediff", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("timediff", new StandardSQLFunction("timediff", StandardBasicTypes.TIME) );
|
||||
registerFunction("date_format", new StandardSQLFunction("date_format", StandardBasicTypes.STRING) );
|
||||
registerFunction( "datediff", new StandardSQLFunction( "datediff", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "timediff", new StandardSQLFunction( "timediff", StandardBasicTypes.TIME ) );
|
||||
registerFunction( "date_format", new StandardSQLFunction( "date_format", StandardBasicTypes.STRING ) );
|
||||
|
||||
registerFunction("curdate", new NoArgSQLFunction("curdate", StandardBasicTypes.DATE) );
|
||||
registerFunction("curtime", new NoArgSQLFunction("curtime", StandardBasicTypes.TIME) );
|
||||
registerFunction("current_date", new NoArgSQLFunction("current_date", StandardBasicTypes.DATE, false) );
|
||||
registerFunction("current_time", new NoArgSQLFunction("current_time", StandardBasicTypes.TIME, false) );
|
||||
registerFunction("current_timestamp", new NoArgSQLFunction("current_timestamp", StandardBasicTypes.TIMESTAMP, false) );
|
||||
registerFunction("date", new StandardSQLFunction("date", StandardBasicTypes.DATE) );
|
||||
registerFunction("day", new StandardSQLFunction("day", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("dayofmonth", new StandardSQLFunction("dayofmonth", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("dayname", new StandardSQLFunction("dayname", StandardBasicTypes.STRING) );
|
||||
registerFunction("dayofweek", new StandardSQLFunction("dayofweek", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("dayofyear", new StandardSQLFunction("dayofyear", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("from_days", new StandardSQLFunction("from_days", StandardBasicTypes.DATE) );
|
||||
registerFunction("from_unixtime", new StandardSQLFunction("from_unixtime", StandardBasicTypes.TIMESTAMP) );
|
||||
registerFunction("hour", new StandardSQLFunction("hour", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("last_day", new StandardSQLFunction("last_day", StandardBasicTypes.DATE) );
|
||||
registerFunction("localtime", new NoArgSQLFunction("localtime", StandardBasicTypes.TIMESTAMP) );
|
||||
registerFunction("localtimestamp", new NoArgSQLFunction("localtimestamp", StandardBasicTypes.TIMESTAMP) );
|
||||
registerFunction("microseconds", new StandardSQLFunction("microseconds", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("minute", new StandardSQLFunction("minute", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("month", new StandardSQLFunction("month", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("monthname", new StandardSQLFunction("monthname", StandardBasicTypes.STRING) );
|
||||
registerFunction("now", new NoArgSQLFunction("now", StandardBasicTypes.TIMESTAMP) );
|
||||
registerFunction("quarter", new StandardSQLFunction("quarter", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("second", new StandardSQLFunction("second", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("sec_to_time", new StandardSQLFunction("sec_to_time", StandardBasicTypes.TIME) );
|
||||
registerFunction("sysdate", new NoArgSQLFunction("sysdate", StandardBasicTypes.TIMESTAMP) );
|
||||
registerFunction("time", new StandardSQLFunction("time", StandardBasicTypes.TIME) );
|
||||
registerFunction("timestamp", new StandardSQLFunction("timestamp", StandardBasicTypes.TIMESTAMP) );
|
||||
registerFunction("time_to_sec", new StandardSQLFunction("time_to_sec", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("to_days", new StandardSQLFunction("to_days", StandardBasicTypes.LONG) );
|
||||
registerFunction("unix_timestamp", new StandardSQLFunction("unix_timestamp", StandardBasicTypes.LONG) );
|
||||
registerFunction("utc_date", new NoArgSQLFunction("utc_date", StandardBasicTypes.STRING) );
|
||||
registerFunction("utc_time", new NoArgSQLFunction("utc_time", StandardBasicTypes.STRING) );
|
||||
registerFunction("utc_timestamp", new NoArgSQLFunction("utc_timestamp", StandardBasicTypes.STRING) );
|
||||
registerFunction("week", new StandardSQLFunction("week", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("weekday", new StandardSQLFunction("weekday", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("weekofyear", new StandardSQLFunction("weekofyear", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("year", new StandardSQLFunction("year", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("yearweek", new StandardSQLFunction("yearweek", StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "curdate", new NoArgSQLFunction( "curdate", StandardBasicTypes.DATE ) );
|
||||
registerFunction( "curtime", new NoArgSQLFunction( "curtime", StandardBasicTypes.TIME ) );
|
||||
registerFunction( "current_date", new NoArgSQLFunction( "current_date", StandardBasicTypes.DATE, false ) );
|
||||
registerFunction( "current_time", new NoArgSQLFunction( "current_time", StandardBasicTypes.TIME, false ) );
|
||||
registerFunction( "current_timestamp", new NoArgSQLFunction( "current_timestamp", StandardBasicTypes.TIMESTAMP, false ) );
|
||||
registerFunction( "date", new StandardSQLFunction( "date", StandardBasicTypes.DATE ) );
|
||||
registerFunction( "day", new StandardSQLFunction( "day", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "dayofmonth", new StandardSQLFunction( "dayofmonth", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "dayname", new StandardSQLFunction( "dayname", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "dayofweek", new StandardSQLFunction( "dayofweek", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "dayofyear", new StandardSQLFunction( "dayofyear", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "from_days", new StandardSQLFunction( "from_days", StandardBasicTypes.DATE ) );
|
||||
registerFunction( "from_unixtime", new StandardSQLFunction( "from_unixtime", StandardBasicTypes.TIMESTAMP ) );
|
||||
registerFunction( "hour", new StandardSQLFunction( "hour", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "last_day", new StandardSQLFunction( "last_day", StandardBasicTypes.DATE ) );
|
||||
registerFunction( "localtime", new NoArgSQLFunction( "localtime", StandardBasicTypes.TIMESTAMP ) );
|
||||
registerFunction( "localtimestamp", new NoArgSQLFunction( "localtimestamp", StandardBasicTypes.TIMESTAMP ) );
|
||||
registerFunction( "microseconds", new StandardSQLFunction( "microseconds", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "minute", new StandardSQLFunction( "minute", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "month", new StandardSQLFunction( "month", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "monthname", new StandardSQLFunction( "monthname", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "now", new NoArgSQLFunction( "now", StandardBasicTypes.TIMESTAMP ) );
|
||||
registerFunction( "quarter", new StandardSQLFunction( "quarter", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "second", new StandardSQLFunction( "second", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "sec_to_time", new StandardSQLFunction( "sec_to_time", StandardBasicTypes.TIME ) );
|
||||
registerFunction( "sysdate", new NoArgSQLFunction( "sysdate", StandardBasicTypes.TIMESTAMP ) );
|
||||
registerFunction( "time", new StandardSQLFunction( "time", StandardBasicTypes.TIME ) );
|
||||
registerFunction( "timestamp", new StandardSQLFunction( "timestamp", StandardBasicTypes.TIMESTAMP ) );
|
||||
registerFunction( "time_to_sec", new StandardSQLFunction( "time_to_sec", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "to_days", new StandardSQLFunction( "to_days", StandardBasicTypes.LONG ) );
|
||||
registerFunction( "unix_timestamp", new StandardSQLFunction( "unix_timestamp", StandardBasicTypes.LONG ) );
|
||||
registerFunction( "utc_date", new NoArgSQLFunction( "utc_date", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "utc_time", new NoArgSQLFunction( "utc_time", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "utc_timestamp", new NoArgSQLFunction( "utc_timestamp", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "week", new StandardSQLFunction( "week", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "weekday", new StandardSQLFunction( "weekday", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "weekofyear", new StandardSQLFunction( "weekofyear", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "year", new StandardSQLFunction( "year", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "yearweek", new StandardSQLFunction( "yearweek", StandardBasicTypes.INTEGER ) );
|
||||
|
||||
registerFunction("hex", new StandardSQLFunction("hex", StandardBasicTypes.STRING) );
|
||||
registerFunction("oct", new StandardSQLFunction("oct", StandardBasicTypes.STRING) );
|
||||
registerFunction( "hex", new StandardSQLFunction( "hex", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "oct", new StandardSQLFunction( "oct", StandardBasicTypes.STRING ) );
|
||||
|
||||
registerFunction("octet_length", new StandardSQLFunction("octet_length", StandardBasicTypes.LONG) );
|
||||
registerFunction("bit_length", new StandardSQLFunction("bit_length", StandardBasicTypes.LONG) );
|
||||
registerFunction( "octet_length", new StandardSQLFunction( "octet_length", StandardBasicTypes.LONG ) );
|
||||
registerFunction( "bit_length", new StandardSQLFunction( "bit_length", StandardBasicTypes.LONG ) );
|
||||
|
||||
registerFunction("bit_count", new StandardSQLFunction("bit_count", StandardBasicTypes.LONG) );
|
||||
registerFunction("encrypt", new StandardSQLFunction("encrypt", StandardBasicTypes.STRING) );
|
||||
registerFunction("md5", new StandardSQLFunction("md5", StandardBasicTypes.STRING) );
|
||||
registerFunction("sha1", new StandardSQLFunction("sha1", StandardBasicTypes.STRING) );
|
||||
registerFunction("sha", new StandardSQLFunction("sha", StandardBasicTypes.STRING) );
|
||||
registerFunction( "bit_count", new StandardSQLFunction( "bit_count", StandardBasicTypes.LONG ) );
|
||||
registerFunction( "encrypt", new StandardSQLFunction( "encrypt", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "md5", new StandardSQLFunction( "md5", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "sha1", new StandardSQLFunction( "sha1", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "sha", new StandardSQLFunction( "sha", StandardBasicTypes.STRING ) );
|
||||
|
||||
registerFunction( "concat", new StandardSQLFunction( "concat", StandardBasicTypes.STRING ) );
|
||||
|
||||
getDefaultProperties().setProperty(Environment.MAX_FETCH_DEPTH, "2");
|
||||
getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);
|
||||
getDefaultProperties().setProperty( Environment.MAX_FETCH_DEPTH, "2" );
|
||||
getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
|
||||
}
|
||||
|
||||
protected void registerVarcharTypes() {
|
||||
@ -191,110 +195,127 @@ protected void registerVarcharTypes() {
|
||||
registerColumnType( Types.LONGVARCHAR, "longtext" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
return "add column";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean qualifyIndexName() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsIdentityColumns() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getIdentitySelectString() {
|
||||
return "select last_insert_id()";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentityColumnString() {
|
||||
return "not null auto_increment"; //starts with 1, implicitly
|
||||
//starts with 1, implicitly
|
||||
return "not null auto_increment";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddForeignKeyConstraintString(
|
||||
String constraintName,
|
||||
String[] foreignKey,
|
||||
String referencedTable,
|
||||
String[] primaryKey, boolean referencesPrimaryKey
|
||||
) {
|
||||
String cols = StringHelper.join(", ", foreignKey);
|
||||
return new StringBuilder(30)
|
||||
.append(" add index ")
|
||||
.append(constraintName)
|
||||
.append(" (")
|
||||
.append(cols)
|
||||
.append("), add constraint ")
|
||||
.append(constraintName)
|
||||
.append(" foreign key (")
|
||||
.append(cols)
|
||||
.append(") references ")
|
||||
.append(referencedTable)
|
||||
.append(" (")
|
||||
.append( StringHelper.join(", ", primaryKey) )
|
||||
.append(')')
|
||||
.toString();
|
||||
String constraintName,
|
||||
String[] foreignKey,
|
||||
String referencedTable,
|
||||
String[] primaryKey,
|
||||
boolean referencesPrimaryKey) {
|
||||
final String cols = StringHelper.join( ", ", foreignKey );
|
||||
final String referencedCols = StringHelper.join( ", ", primaryKey );
|
||||
return String.format(
|
||||
" add index %s (%s), add constraint %s foreign key (%s) references %s (%s)",
|
||||
constraintName,
|
||||
cols,
|
||||
constraintName,
|
||||
cols,
|
||||
referencedTable,
|
||||
referencedCols
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getDropForeignKeyString() {
|
||||
return " drop foreign key ";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLimitString(String sql, boolean hasOffset) {
|
||||
return sql + (hasOffset ? " limit ?, ?" : " limit ?");
|
||||
}
|
||||
|
||||
@Override
|
||||
public char closeQuote() {
|
||||
return '`';
|
||||
}
|
||||
|
||||
@Override
|
||||
public char openQuote() {
|
||||
return '`';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsIfExistsBeforeTableName() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectGUIDString() {
|
||||
return "select uuid()";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCascadeDelete() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getTableComment(String comment) {
|
||||
return " comment='" + comment + "'";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnComment(String comment) {
|
||||
return " comment '" + comment + "'";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTemporaryTables() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateTemporaryTableString() {
|
||||
return "create temporary table if not exists";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDropTemporaryTableString() {
|
||||
return "drop temporary table";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean performTemporaryTableDDLInIsolation() {
|
||||
// because we [drop *temporary* table...] we do not
|
||||
// have to doAfterTransactionCompletion these in isolation.
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCastTypeName(int code) {
|
||||
switch ( code ){
|
||||
switch ( code ) {
|
||||
case Types.INTEGER:
|
||||
return "signed";
|
||||
case Types.VARCHAR:
|
||||
@ -306,30 +327,36 @@ public String getCastTypeName(int code) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCurrentTimestampSelection() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurrentTimestampSelectStringCallable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentTimestampSelectString() {
|
||||
return "select now()";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
|
||||
return col;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getResultSet(CallableStatement ps) throws SQLException {
|
||||
boolean isResultSet = ps.execute();
|
||||
while (!isResultSet && ps.getUpdateCount() != -1) {
|
||||
isResultSet = ps.getMoreResults();
|
||||
}
|
||||
boolean isResultSet = ps.execute();
|
||||
while ( !isResultSet && ps.getUpdateCount() != -1 ) {
|
||||
isResultSet = ps.getMoreResults();
|
||||
}
|
||||
return ps.getResultSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsRowValueConstructorSyntax() {
|
||||
return true;
|
||||
}
|
||||
@ -355,14 +382,17 @@ public String renderOrderByElement(String expression, String collation, String o
|
||||
|
||||
// locking support
|
||||
|
||||
@Override
|
||||
public String getForUpdateString() {
|
||||
return " for update";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWriteLockString(int timeout) {
|
||||
return " for update";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReadLockString(int timeout) {
|
||||
return " lock in share mode";
|
||||
}
|
||||
@ -370,19 +400,23 @@ public String getReadLockString(int timeout) {
|
||||
|
||||
// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public boolean supportsEmptyInList() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areStringComparisonsCaseInsensitive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLobValueChangePropogation() {
|
||||
// note: at least my local MySQL 5.1 install shows this not working...
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSubqueryOnMutatingTable() {
|
||||
return false;
|
||||
}
|
||||
@ -415,9 +449,9 @@ public JDBCException convert(SQLException sqlException, String message, String s
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getNotExpression( String expression ) {
|
||||
public String getNotExpression(String expression) {
|
||||
return "not (" + expression + ")";
|
||||
}
|
||||
}
|
||||
|
@ -23,22 +23,24 @@
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
|
||||
/**
|
||||
* A Dialect for MySQL using InnoDB engine
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class MySQLInnoDBDialect extends MySQLDialect {
|
||||
|
||||
@Override
|
||||
public boolean supportsCascadeDelete() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getTableTypeString() {
|
||||
return " type=InnoDB";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSelfReferentialForeignKeyBug() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,18 +23,19 @@
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
|
||||
/**
|
||||
* A Dialect for MySQL using the MyISAM engine
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class MySQLMyISAMDialect extends MySQLDialect {
|
||||
|
||||
@Override
|
||||
public String getTableTypeString() {
|
||||
return " type=MyISAM";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dropConstraints() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,31 +22,33 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.sql.ANSIJoinFragment;
|
||||
import org.hibernate.sql.JoinFragment;
|
||||
|
||||
|
||||
/**
|
||||
* A dialect specifically for use with Oracle 10g.
|
||||
* <p/>
|
||||
* The main difference between this dialect and {@link Oracle9iDialect}
|
||||
* is the use of "ANSI join syntax". This dialect also retires the use
|
||||
* of the <tt>oracle.jdbc.driver</tt> package in favor of
|
||||
* <tt>oracle.jdbc</tt>.
|
||||
* is the use of "ANSI join syntax".
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class Oracle10gDialect extends Oracle9iDialect {
|
||||
|
||||
/**
|
||||
* Constructs a Oracle10gDialect
|
||||
*/
|
||||
public Oracle10gDialect() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JoinFragment createOuterJoinFragment() {
|
||||
return new ANSIJoinFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWriteLockString(int timeout) {
|
||||
if ( timeout == LockOptions.SKIP_LOCKED ) {
|
||||
return getForUpdateSkipLockedString();
|
||||
@ -56,10 +58,12 @@ public String getWriteLockString(int timeout) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForUpdateSkipLockedString() {
|
||||
return " for update skip locked";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForUpdateSkipLockedString(String aliases) {
|
||||
return getForUpdateString() + " of " + aliases + " skip locked";
|
||||
}
|
||||
|
@ -58,10 +58,13 @@
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class Oracle8iDialect extends Dialect {
|
||||
|
||||
private static final int PARAM_LIST_SIZE_LIMIT = 1000;
|
||||
|
||||
/**
|
||||
* Constructs a Oracle8iDialect
|
||||
*/
|
||||
public Oracle8iDialect() {
|
||||
super();
|
||||
registerCharacterTypeMappings();
|
||||
@ -91,7 +94,7 @@ protected void registerNumericTypeMappings() {
|
||||
registerColumnType( Types.NUMERIC, "number($p,$s)" );
|
||||
registerColumnType( Types.DECIMAL, "number($p,$s)" );
|
||||
|
||||
registerColumnType( Types.BOOLEAN, "number(1,0)" );
|
||||
registerColumnType( Types.BOOLEAN, "number(1,0)" );
|
||||
}
|
||||
|
||||
protected void registerDateTimeTypeMappings() {
|
||||
@ -217,19 +220,11 @@ protected SqlTypeDescriptor getSqlTypeDescriptorOverride(int sqlCode) {
|
||||
|
||||
// features which change between 8i, 9i, and 10g ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
* Support for the oracle proprietary join syntax...
|
||||
*
|
||||
* @return The orqacle join fragment
|
||||
*/
|
||||
@Override
|
||||
public JoinFragment createOuterJoinFragment() {
|
||||
return new OracleJoinFragment();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getCrossJoinSeparator() {
|
||||
return ", ";
|
||||
@ -238,35 +233,36 @@ public String getCrossJoinSeparator() {
|
||||
/**
|
||||
* Map case support to the Oracle DECODE function. Oracle did not
|
||||
* add support for CASE until 9i.
|
||||
*
|
||||
* @return The oracle CASE -> DECODE fragment
|
||||
* <p/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public CaseFragment createCaseFragment() {
|
||||
return new DecodeCaseFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLimitString(String sql, boolean hasOffset) {
|
||||
sql = sql.trim();
|
||||
boolean isForUpdate = false;
|
||||
if ( sql.toLowerCase().endsWith(" for update") ) {
|
||||
if ( sql.toLowerCase().endsWith( " for update" ) ) {
|
||||
sql = sql.substring( 0, sql.length()-11 );
|
||||
isForUpdate = true;
|
||||
}
|
||||
|
||||
StringBuilder pagingSelect = new StringBuilder( sql.length()+100 );
|
||||
final StringBuilder pagingSelect = new StringBuilder( sql.length()+100 );
|
||||
if (hasOffset) {
|
||||
pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
|
||||
pagingSelect.append( "select * from ( select row_.*, rownum rownum_ from ( " );
|
||||
}
|
||||
else {
|
||||
pagingSelect.append("select * from ( ");
|
||||
}
|
||||
pagingSelect.append(sql);
|
||||
pagingSelect.append( sql );
|
||||
if (hasOffset) {
|
||||
pagingSelect.append(" ) row_ ) where rownum_ <= ? and rownum_ > ?");
|
||||
pagingSelect.append( " ) row_ ) where rownum_ <= ? and rownum_ > ?" );
|
||||
}
|
||||
else {
|
||||
pagingSelect.append(" ) where rownum <= ?");
|
||||
pagingSelect.append( " ) where rownum <= ?" );
|
||||
}
|
||||
|
||||
if ( isForUpdate ) {
|
||||
@ -286,6 +282,7 @@ public String getLimitString(String sql, boolean hasOffset) {
|
||||
public String getBasicSelectClauseNullString(int sqlType) {
|
||||
return super.getSelectClauseNullString( sqlType );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectClauseNullString(int sqlType) {
|
||||
switch(sqlType) {
|
||||
@ -300,10 +297,12 @@ public String getSelectClauseNullString(int sqlType) {
|
||||
return "to_number(null)";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentTimestampSelectString() {
|
||||
return "select sysdate from dual";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentTimestampSQLFunctionName() {
|
||||
return "sysdate";
|
||||
@ -311,70 +310,88 @@ public String getCurrentTimestampSQLFunctionName() {
|
||||
|
||||
|
||||
// features which remain constant across 8i, 9i, and 10g ~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
return "add";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSequenceNextValString(String sequenceName) {
|
||||
return "select " + getSelectSequenceNextValString( sequenceName ) + " from dual";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectSequenceNextValString(String sequenceName) {
|
||||
return sequenceName + ".nextval";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateSequenceString(String sequenceName) {
|
||||
return "create sequence " + sequenceName; //starts with 1, implicitly
|
||||
//starts with 1, implicitly
|
||||
return "create sequence " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDropSequenceString(String sequenceName) {
|
||||
return "drop sequence " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCascadeConstraintsString() {
|
||||
return " cascade constraints";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dropConstraints() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForUpdateNowaitString() {
|
||||
return " for update nowait";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPooledSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForUpdateString(String aliases) {
|
||||
return getForUpdateString() + " of " + aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForUpdateNowaitString(String aliases) {
|
||||
return getForUpdateString() + " of " + aliases + " nowait";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean bindLimitParametersInReverseOrder() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useMaxForLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean forUpdateOfColumns() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQuerySequencesString() {
|
||||
return " select sequence_name from all_sequences"
|
||||
@ -384,16 +401,18 @@ public String getQuerySequencesString() {
|
||||
+ " where asq.sequence_name = us.table_name"
|
||||
+ " and asq.sequence_owner = us.table_owner";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectGUIDString() {
|
||||
return "select rawtohex(sys_guid()) from dual";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
|
||||
return EXTRACTER;
|
||||
return EXTRACTER;
|
||||
}
|
||||
|
||||
private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
|
||||
private static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
|
||||
|
||||
/**
|
||||
* Extract the name of the violated constraint from the given SQLException.
|
||||
@ -402,7 +421,7 @@ public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
|
||||
* @return The extracted constraint name.
|
||||
*/
|
||||
public String extractConstraintName(SQLException sqle) {
|
||||
int errorCode = JdbcExceptionHelper.extractErrorCode( sqle );
|
||||
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqle );
|
||||
if ( errorCode == 1 || errorCode == 2291 || errorCode == 2292 ) {
|
||||
return extractUsingTemplate( "(", ")", sqle.getMessage() );
|
||||
}
|
||||
@ -476,88 +495,61 @@ else if ( 4020 == errorCode ) {
|
||||
};
|
||||
}
|
||||
|
||||
public static final String ORACLE_TYPES_CLASS_NAME = "oracle.jdbc.OracleTypes";
|
||||
public static final String DEPRECATED_ORACLE_TYPES_CLASS_NAME = "oracle.jdbc.driver.OracleTypes";
|
||||
|
||||
public static final int INIT_ORACLETYPES_CURSOR_VALUE = -99;
|
||||
|
||||
// not final-static to avoid possible classcast exceptions if using different oracle drivers.
|
||||
private int oracleCursorTypeSqlType = INIT_ORACLETYPES_CURSOR_VALUE;
|
||||
|
||||
public int getOracleCursorTypeSqlType() {
|
||||
if ( oracleCursorTypeSqlType == INIT_ORACLETYPES_CURSOR_VALUE ) {
|
||||
// todo : is there really any reason to kkeep trying if this fails once?
|
||||
oracleCursorTypeSqlType = extractOracleCursorTypeValue();
|
||||
}
|
||||
return oracleCursorTypeSqlType;
|
||||
}
|
||||
|
||||
protected int extractOracleCursorTypeValue() {
|
||||
Class oracleTypesClass;
|
||||
try {
|
||||
oracleTypesClass = ReflectHelper.classForName( ORACLE_TYPES_CLASS_NAME );
|
||||
}
|
||||
catch ( ClassNotFoundException cnfe ) {
|
||||
try {
|
||||
oracleTypesClass = ReflectHelper.classForName( DEPRECATED_ORACLE_TYPES_CLASS_NAME );
|
||||
}
|
||||
catch ( ClassNotFoundException e ) {
|
||||
throw new HibernateException( "Unable to locate OracleTypes class", e );
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return oracleTypesClass.getField( "CURSOR" ).getInt( null );
|
||||
}
|
||||
catch ( Exception se ) {
|
||||
throw new HibernateException( "Unable to access OracleTypes.CURSOR value", se );
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
|
||||
// register the type of the out param - an Oracle specific type
|
||||
statement.registerOutParameter( col, getOracleCursorTypeSqlType() );
|
||||
statement.registerOutParameter( col, OracleTypesHelper.INSTANCE.getOracleCursorTypeSqlType() );
|
||||
col++;
|
||||
return col;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getResultSet(CallableStatement ps) throws SQLException {
|
||||
ps.execute();
|
||||
return ( ResultSet ) ps.getObject( 1 );
|
||||
return (ResultSet) ps.getObject( 1 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsUnionAll() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCommentOn() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTemporaryTables() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateTemporaryTableName(String baseTableName) {
|
||||
String name = super.generateTemporaryTableName(baseTableName);
|
||||
final String name = super.generateTemporaryTableName( baseTableName );
|
||||
return name.length() > 30 ? name.substring( 1, 30 ) : name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateTemporaryTableString() {
|
||||
return "create global temporary table";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateTemporaryTablePostfix() {
|
||||
return "on commit delete rows";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dropTemporaryTableAfterUse() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCurrentTimestampSelection() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurrentTimestampSelectStringCallable() {
|
||||
return false;
|
||||
@ -573,9 +565,6 @@ public boolean supportsExistsInSelect() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.hibernate.dialect.Dialect#getInExpressionCountLimit()
|
||||
*/
|
||||
@Override
|
||||
public int getInExpressionCountLimit() {
|
||||
return PARAM_LIST_SIZE_LIMIT;
|
||||
|
@ -30,7 +30,6 @@
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.function.NoArgSQLFunction;
|
||||
import org.hibernate.dialect.function.NvlFunction;
|
||||
@ -41,22 +40,30 @@
|
||||
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.JdbcExceptionHelper;
|
||||
import org.hibernate.internal.util.ReflectHelper;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
|
||||
/**
|
||||
* An SQL dialect for Oracle 9 (uses ANSI-style syntax where possible).
|
||||
*
|
||||
* @author Gavin King
|
||||
* @author David Channon
|
||||
*
|
||||
* @deprecated Use either Oracle9iDialect or Oracle10gDialect instead
|
||||
* @author Gavin King, David Channon
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
public class Oracle9Dialect extends Dialect {
|
||||
|
||||
|
||||
private static final int PARAM_LIST_SIZE_LIMIT = 1000;
|
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, Oracle9Dialect.class.getName());
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
Oracle9Dialect.class.getName()
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructs a Oracle9Dialect
|
||||
*/
|
||||
public Oracle9Dialect() {
|
||||
super();
|
||||
LOG.deprecatedOracle9Dialect();
|
||||
@ -84,68 +91,74 @@ public Oracle9Dialect() {
|
||||
// support the version taking an array of the names of the columns to
|
||||
// be returned (via its RETURNING clause). No other driver seems to
|
||||
// support this overloaded version.
|
||||
getDefaultProperties().setProperty(Environment.USE_GET_GENERATED_KEYS, "false");
|
||||
getDefaultProperties().setProperty(Environment.USE_STREAMS_FOR_BINARY, "true");
|
||||
getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);
|
||||
getDefaultProperties().setProperty( Environment.USE_GET_GENERATED_KEYS, "false" );
|
||||
getDefaultProperties().setProperty( Environment.USE_STREAMS_FOR_BINARY, "true" );
|
||||
getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
|
||||
|
||||
registerFunction( "abs", new StandardSQLFunction("abs") );
|
||||
registerFunction( "sign", new StandardSQLFunction("sign", StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "abs", new StandardSQLFunction( "abs" ) );
|
||||
registerFunction( "sign", new StandardSQLFunction( "sign", StandardBasicTypes.INTEGER ) );
|
||||
|
||||
registerFunction( "acos", new StandardSQLFunction("acos", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "asin", new StandardSQLFunction("asin", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "atan", new StandardSQLFunction("atan", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "cos", new StandardSQLFunction("cos", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "cosh", new StandardSQLFunction("cosh", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "exp", new StandardSQLFunction("exp", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "ln", new StandardSQLFunction("ln", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "sin", new StandardSQLFunction("sin", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "sinh", new StandardSQLFunction("sinh", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "stddev", new StandardSQLFunction("stddev", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "sqrt", new StandardSQLFunction("sqrt", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "tan", new StandardSQLFunction("tan", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "tanh", new StandardSQLFunction("tanh", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "variance", new StandardSQLFunction("variance", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "acos", new StandardSQLFunction( "acos", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "asin", new StandardSQLFunction( "asin", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "atan", new StandardSQLFunction( "atan", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "cos", new StandardSQLFunction( "cos", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "cosh", new StandardSQLFunction( "cosh", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "exp", new StandardSQLFunction( "exp", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "ln", new StandardSQLFunction( "ln", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "sin", new StandardSQLFunction( "sin", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "sinh", new StandardSQLFunction( "sinh", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "stddev", new StandardSQLFunction( "stddev", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "sqrt", new StandardSQLFunction( "sqrt", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "tan", new StandardSQLFunction( "tan", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "tanh", new StandardSQLFunction( "tanh", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "variance", new StandardSQLFunction( "variance", StandardBasicTypes.DOUBLE ) );
|
||||
|
||||
registerFunction( "round", new StandardSQLFunction("round") );
|
||||
registerFunction( "trunc", new StandardSQLFunction("trunc") );
|
||||
registerFunction( "ceil", new StandardSQLFunction("ceil") );
|
||||
registerFunction( "floor", new StandardSQLFunction("floor") );
|
||||
registerFunction( "round", new StandardSQLFunction( "round" ) );
|
||||
registerFunction( "trunc", new StandardSQLFunction( "trunc" ) );
|
||||
registerFunction( "ceil", new StandardSQLFunction( "ceil" ) );
|
||||
registerFunction( "floor", new StandardSQLFunction( "floor" ) );
|
||||
|
||||
registerFunction( "chr", new StandardSQLFunction("chr", StandardBasicTypes.CHARACTER) );
|
||||
registerFunction( "initcap", new StandardSQLFunction("initcap") );
|
||||
registerFunction( "lower", new StandardSQLFunction("lower") );
|
||||
registerFunction( "ltrim", new StandardSQLFunction("ltrim") );
|
||||
registerFunction( "rtrim", new StandardSQLFunction("rtrim") );
|
||||
registerFunction( "soundex", new StandardSQLFunction("soundex") );
|
||||
registerFunction( "upper", new StandardSQLFunction("upper") );
|
||||
registerFunction( "ascii", new StandardSQLFunction("ascii", StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "chr", new StandardSQLFunction( "chr", StandardBasicTypes.CHARACTER ) );
|
||||
registerFunction( "initcap", new StandardSQLFunction( "initcap" ) );
|
||||
registerFunction( "lower", new StandardSQLFunction( "lower" ) );
|
||||
registerFunction( "ltrim", new StandardSQLFunction( "ltrim" ) );
|
||||
registerFunction( "rtrim", new StandardSQLFunction( "rtrim" ) );
|
||||
registerFunction( "soundex", new StandardSQLFunction( "soundex" ) );
|
||||
registerFunction( "upper", new StandardSQLFunction( "upper" ) );
|
||||
registerFunction( "ascii", new StandardSQLFunction( "ascii", StandardBasicTypes.INTEGER ) );
|
||||
|
||||
registerFunction( "to_char", new StandardSQLFunction("to_char", StandardBasicTypes.STRING) );
|
||||
registerFunction( "to_date", new StandardSQLFunction("to_date", StandardBasicTypes.TIMESTAMP) );
|
||||
registerFunction( "to_char", new StandardSQLFunction( "to_char", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "to_date", new StandardSQLFunction( "to_date", StandardBasicTypes.TIMESTAMP ) );
|
||||
|
||||
registerFunction( "current_date", new NoArgSQLFunction("current_date", StandardBasicTypes.DATE, false) );
|
||||
registerFunction( "current_time", new NoArgSQLFunction("current_timestamp", StandardBasicTypes.TIME, false) );
|
||||
registerFunction( "current_timestamp", new NoArgSQLFunction("current_timestamp", StandardBasicTypes.TIMESTAMP, false) );
|
||||
registerFunction( "current_date", new NoArgSQLFunction( "current_date", StandardBasicTypes.DATE, false ) );
|
||||
registerFunction( "current_time", new NoArgSQLFunction( "current_timestamp", StandardBasicTypes.TIME, false ) );
|
||||
registerFunction(
|
||||
"current_timestamp", new NoArgSQLFunction(
|
||||
"current_timestamp",
|
||||
StandardBasicTypes.TIMESTAMP,
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
registerFunction( "last_day", new StandardSQLFunction("last_day", StandardBasicTypes.DATE) );
|
||||
registerFunction( "sysdate", new NoArgSQLFunction("sysdate", StandardBasicTypes.DATE, false) );
|
||||
registerFunction( "systimestamp", new NoArgSQLFunction("systimestamp", StandardBasicTypes.TIMESTAMP, false) );
|
||||
registerFunction( "uid", new NoArgSQLFunction("uid", StandardBasicTypes.INTEGER, false) );
|
||||
registerFunction( "user", new NoArgSQLFunction("user", StandardBasicTypes.STRING, false) );
|
||||
registerFunction( "last_day", new StandardSQLFunction( "last_day", StandardBasicTypes.DATE ) );
|
||||
registerFunction( "sysdate", new NoArgSQLFunction( "sysdate", StandardBasicTypes.DATE, false ) );
|
||||
registerFunction( "systimestamp", new NoArgSQLFunction( "systimestamp", StandardBasicTypes.TIMESTAMP, false ) );
|
||||
registerFunction( "uid", new NoArgSQLFunction( "uid", StandardBasicTypes.INTEGER, false ) );
|
||||
registerFunction( "user", new NoArgSQLFunction( "user", StandardBasicTypes.STRING, false ) );
|
||||
|
||||
registerFunction( "rowid", new NoArgSQLFunction("rowid", StandardBasicTypes.LONG, false) );
|
||||
registerFunction( "rownum", new NoArgSQLFunction("rownum", StandardBasicTypes.LONG, false) );
|
||||
registerFunction( "rowid", new NoArgSQLFunction( "rowid", StandardBasicTypes.LONG, false ) );
|
||||
registerFunction( "rownum", new NoArgSQLFunction( "rownum", StandardBasicTypes.LONG, false ) );
|
||||
|
||||
// Multi-param string dialect functions...
|
||||
registerFunction( "concat", new VarArgsSQLFunction(StandardBasicTypes.STRING, "", "||", "") );
|
||||
registerFunction( "instr", new StandardSQLFunction("instr", StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "instrb", new StandardSQLFunction("instrb", StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "lpad", new StandardSQLFunction("lpad", StandardBasicTypes.STRING) );
|
||||
registerFunction( "replace", new StandardSQLFunction("replace", StandardBasicTypes.STRING) );
|
||||
registerFunction( "rpad", new StandardSQLFunction("rpad", StandardBasicTypes.STRING) );
|
||||
registerFunction( "substr", new StandardSQLFunction("substr", StandardBasicTypes.STRING) );
|
||||
registerFunction( "substrb", new StandardSQLFunction("substrb", StandardBasicTypes.STRING) );
|
||||
registerFunction( "translate", new StandardSQLFunction("translate", StandardBasicTypes.STRING) );
|
||||
registerFunction( "concat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "", "||", "" ) );
|
||||
registerFunction( "instr", new StandardSQLFunction( "instr", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "instrb", new StandardSQLFunction( "instrb", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "lpad", new StandardSQLFunction( "lpad", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "replace", new StandardSQLFunction( "replace", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "rpad", new StandardSQLFunction( "rpad", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "substr", new StandardSQLFunction( "substr", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "substrb", new StandardSQLFunction( "substrb", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "translate", new StandardSQLFunction( "translate", StandardBasicTypes.STRING ) );
|
||||
|
||||
registerFunction( "substring", new StandardSQLFunction( "substr", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "locate", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "instr(?2,?1)" ) );
|
||||
@ -153,87 +166,100 @@ public Oracle9Dialect() {
|
||||
registerFunction( "coalesce", new NvlFunction() );
|
||||
|
||||
// Multi-param numeric dialect functions...
|
||||
registerFunction( "atan2", new StandardSQLFunction("atan2", StandardBasicTypes.FLOAT) );
|
||||
registerFunction( "log", new StandardSQLFunction("log", StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "mod", new StandardSQLFunction("mod", StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "nvl", new StandardSQLFunction("nvl") );
|
||||
registerFunction( "nvl2", new StandardSQLFunction("nvl2") );
|
||||
registerFunction( "power", new StandardSQLFunction("power", StandardBasicTypes.FLOAT) );
|
||||
registerFunction( "atan2", new StandardSQLFunction( "atan2", StandardBasicTypes.FLOAT ) );
|
||||
registerFunction( "log", new StandardSQLFunction( "log", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "mod", new StandardSQLFunction( "mod", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "nvl", new StandardSQLFunction( "nvl" ) );
|
||||
registerFunction( "nvl2", new StandardSQLFunction( "nvl2" ) );
|
||||
registerFunction( "power", new StandardSQLFunction( "power", StandardBasicTypes.FLOAT ) );
|
||||
|
||||
// Multi-param date dialect functions...
|
||||
registerFunction( "add_months", new StandardSQLFunction("add_months", StandardBasicTypes.DATE) );
|
||||
registerFunction( "months_between", new StandardSQLFunction("months_between", StandardBasicTypes.FLOAT) );
|
||||
registerFunction( "next_day", new StandardSQLFunction("next_day", StandardBasicTypes.DATE) );
|
||||
registerFunction( "add_months", new StandardSQLFunction( "add_months", StandardBasicTypes.DATE ) );
|
||||
registerFunction( "months_between", new StandardSQLFunction( "months_between", StandardBasicTypes.FLOAT ) );
|
||||
registerFunction( "next_day", new StandardSQLFunction( "next_day", StandardBasicTypes.DATE ) );
|
||||
|
||||
registerFunction( "str", new StandardSQLFunction("to_char", StandardBasicTypes.STRING) );
|
||||
registerFunction( "str", new StandardSQLFunction( "to_char", StandardBasicTypes.STRING ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
return "add";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSequenceNextValString(String sequenceName) {
|
||||
return "select " + getSelectSequenceNextValString( sequenceName ) + " from dual";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectSequenceNextValString(String sequenceName) {
|
||||
return sequenceName + ".nextval";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateSequenceString(String sequenceName) {
|
||||
return "create sequence " + sequenceName; //starts with 1, implicitly
|
||||
//starts with 1, implicitly
|
||||
return "create sequence " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDropSequenceString(String sequenceName) {
|
||||
return "drop sequence " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCascadeConstraintsString() {
|
||||
return " cascade constraints";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dropConstraints() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForUpdateNowaitString() {
|
||||
return " for update nowait";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPooledSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLimitString(String sql, boolean hasOffset) {
|
||||
|
||||
sql = sql.trim();
|
||||
boolean isForUpdate = false;
|
||||
if ( sql.toLowerCase().endsWith(" for update") ) {
|
||||
sql = sql.substring( 0, sql.length()-11 );
|
||||
if ( sql.toLowerCase().endsWith( " for update" ) ) {
|
||||
sql = sql.substring( 0, sql.length() - 11 );
|
||||
isForUpdate = true;
|
||||
}
|
||||
|
||||
StringBuilder pagingSelect = new StringBuilder( sql.length()+100 );
|
||||
if (hasOffset) {
|
||||
pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
|
||||
final StringBuilder pagingSelect = new StringBuilder( sql.length() + 100 );
|
||||
if ( hasOffset ) {
|
||||
pagingSelect.append( "select * from ( select row_.*, rownum rownum_ from ( " );
|
||||
}
|
||||
else {
|
||||
pagingSelect.append("select * from ( ");
|
||||
pagingSelect.append( "select * from ( " );
|
||||
}
|
||||
pagingSelect.append(sql);
|
||||
if (hasOffset) {
|
||||
pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?");
|
||||
pagingSelect.append( sql );
|
||||
if ( hasOffset ) {
|
||||
pagingSelect.append( " ) row_ where rownum <= ?) where rownum_ > ?" );
|
||||
}
|
||||
else {
|
||||
pagingSelect.append(" ) where rownum <= ?");
|
||||
pagingSelect.append( " ) where rownum <= ?" );
|
||||
}
|
||||
|
||||
if ( isForUpdate ) {
|
||||
@ -243,48 +269,50 @@ public String getLimitString(String sql, boolean hasOffset) {
|
||||
return pagingSelect.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForUpdateString(String aliases) {
|
||||
return getForUpdateString() + " of " + aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForUpdateNowaitString(String aliases) {
|
||||
return getForUpdateString() + " of " + aliases + " nowait";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean bindLimitParametersInReverseOrder() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useMaxForLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean forUpdateOfColumns() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQuerySequencesString() {
|
||||
return "select sequence_name from user_sequences";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectGUIDString() {
|
||||
return "select rawtohex(sys_guid()) from dual";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
|
||||
return EXTRACTER;
|
||||
return EXTRACTER;
|
||||
}
|
||||
|
||||
private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
|
||||
|
||||
/**
|
||||
* Extract the name of the violated constraint from the given SQLException.
|
||||
*
|
||||
* @param sqle The exception that was the result of the constraint violation.
|
||||
* @return The extracted constraint name.
|
||||
*/
|
||||
private static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
|
||||
@Override
|
||||
public String extractConstraintName(SQLException sqle) {
|
||||
int errorCode = JdbcExceptionHelper.extractErrorCode( sqle );
|
||||
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqle );
|
||||
if ( errorCode == 1 || errorCode == 2291 || errorCode == 2292 ) {
|
||||
return extractUsingTemplate( "constraint (", ") violated", sqle.getMessage() );
|
||||
}
|
||||
@ -296,90 +324,90 @@ else if ( errorCode == 1400 ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// not final-static to avoid possible classcast exceptions if using different oracle drivers.
|
||||
int oracletypes_cursor_value = 0;
|
||||
public int registerResultSetOutParameter(java.sql.CallableStatement statement,int col) throws SQLException {
|
||||
if(oracletypes_cursor_value==0) {
|
||||
try {
|
||||
Class types = ReflectHelper.classForName("oracle.jdbc.driver.OracleTypes");
|
||||
oracletypes_cursor_value = types.getField("CURSOR").getInt(types.newInstance());
|
||||
} catch (Exception se) {
|
||||
throw new HibernateException("Problem while trying to load or access OracleTypes.CURSOR value",se);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public int registerResultSetOutParameter(java.sql.CallableStatement statement, int col) throws SQLException {
|
||||
// register the type of the out param - an Oracle specific type
|
||||
statement.registerOutParameter(col, oracletypes_cursor_value);
|
||||
statement.registerOutParameter( col, OracleTypesHelper.INSTANCE.getOracleCursorTypeSqlType() );
|
||||
col++;
|
||||
return col;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getResultSet(CallableStatement ps) throws SQLException {
|
||||
ps.execute();
|
||||
return ( ResultSet ) ps.getObject( 1 );
|
||||
return (ResultSet) ps.getObject( 1 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsUnionAll() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCommentOn() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTemporaryTables() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateTemporaryTableName(String baseTableName) {
|
||||
String name = super.generateTemporaryTableName(baseTableName);
|
||||
final String name = super.generateTemporaryTableName( baseTableName );
|
||||
return name.length() > 30 ? name.substring( 1, 30 ) : name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateTemporaryTableString() {
|
||||
return "create global temporary table";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateTemporaryTablePostfix() {
|
||||
return "on commit delete rows";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dropTemporaryTableAfterUse() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCurrentTimestampSelection() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentTimestampSelectString() {
|
||||
return "select systimestamp from dual";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurrentTimestampSelectStringCallable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsEmptyInList() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsExistsInSelect() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.hibernate.dialect.Dialect#getInExpressionCountLimit()
|
||||
*/
|
||||
@Override
|
||||
public int getInExpressionCountLimit() {
|
||||
return PARAM_LIST_SIZE_LIMIT;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getNotExpression( String expression ) {
|
||||
public String getNotExpression(String expression) {
|
||||
return "not (" + expression + ")";
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.LockOptions;
|
||||
@ -42,17 +43,20 @@ protected void registerCharacterTypeMappings() {
|
||||
registerColumnType( Types.VARCHAR, 4000, "varchar2($l char)" );
|
||||
registerColumnType( Types.VARCHAR, "long" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerDateTimeTypeMappings() {
|
||||
registerColumnType( Types.DATE, "date" );
|
||||
registerColumnType( Types.TIME, "date" );
|
||||
registerColumnType( Types.TIMESTAMP, "timestamp" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public CaseFragment createCaseFragment() {
|
||||
// Oracle did add support for ANSI CASE statements in 9i
|
||||
return new ANSICaseFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLimitString(String sql, boolean hasOffset) {
|
||||
sql = sql.trim();
|
||||
@ -66,19 +70,19 @@ public String getLimitString(String sql, boolean hasOffset) {
|
||||
isForUpdate = true;
|
||||
}
|
||||
|
||||
StringBuilder pagingSelect = new StringBuilder( sql.length() + 100 );
|
||||
final StringBuilder pagingSelect = new StringBuilder( sql.length() + 100 );
|
||||
if (hasOffset) {
|
||||
pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
|
||||
pagingSelect.append( "select * from ( select row_.*, rownum rownum_ from ( " );
|
||||
}
|
||||
else {
|
||||
pagingSelect.append("select * from ( ");
|
||||
pagingSelect.append( "select * from ( " );
|
||||
}
|
||||
pagingSelect.append(sql);
|
||||
pagingSelect.append( sql );
|
||||
if (hasOffset) {
|
||||
pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?");
|
||||
pagingSelect.append( " ) row_ where rownum <= ?) where rownum_ > ?" );
|
||||
}
|
||||
else {
|
||||
pagingSelect.append(" ) where rownum <= ?");
|
||||
pagingSelect.append( " ) where rownum <= ?" );
|
||||
}
|
||||
|
||||
if ( isForUpdate ) {
|
||||
@ -88,25 +92,28 @@ public String getLimitString(String sql, boolean hasOffset) {
|
||||
|
||||
return pagingSelect.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectClauseNullString(int sqlType) {
|
||||
return getBasicSelectClauseNullString( sqlType );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentTimestampSelectString() {
|
||||
return "select systimestamp from dual";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentTimestampSQLFunctionName() {
|
||||
// the standard SQL function name is current_timestamp...
|
||||
return "current_timestamp";
|
||||
}
|
||||
|
||||
// locking support
|
||||
@Override
|
||||
public String getForUpdateString() {
|
||||
return " for update";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWriteLockString(int timeout) {
|
||||
if ( timeout == LockOptions.NO_WAIT ) {
|
||||
@ -114,25 +121,31 @@ public String getWriteLockString(int timeout) {
|
||||
}
|
||||
else if ( timeout > 0 ) {
|
||||
// convert from milliseconds to seconds
|
||||
float seconds = timeout / 1000.0f;
|
||||
final float seconds = timeout / 1000.0f;
|
||||
timeout = Math.round(seconds);
|
||||
return " for update wait " + timeout;
|
||||
}
|
||||
else
|
||||
else {
|
||||
return " for update";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReadLockString(int timeout) {
|
||||
return getWriteLockString( timeout );
|
||||
}
|
||||
|
||||
/**
|
||||
* HHH-4907, I don't know if oracle 8 supports this syntax, so I'd think it is better add this
|
||||
* method here. Reopen this issue if you found/know 8 supports it.
|
||||
* <p/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsRowValueConstructorSyntaxInInList() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTupleDistinctCounts() {
|
||||
return false;
|
||||
|
@ -38,11 +38,17 @@
|
||||
* @deprecated Use Oracle8iDialect instead.
|
||||
* @author Gavin King
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
public class OracleDialect extends Oracle9Dialect {
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
OracleDialect.class.getName()
|
||||
);
|
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, OracleDialect.class.getName());
|
||||
|
||||
/**
|
||||
* Constructs a (DEPRECATED) Oracle9Dialect
|
||||
*/
|
||||
public OracleDialect() {
|
||||
super();
|
||||
LOG.deprecatedOracleDialect();
|
||||
@ -54,37 +60,38 @@ public OracleDialect() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JoinFragment createOuterJoinFragment() {
|
||||
public JoinFragment createOuterJoinFragment() {
|
||||
return new OracleJoinFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CaseFragment createCaseFragment() {
|
||||
public CaseFragment createCaseFragment() {
|
||||
return new DecodeCaseFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLimitString(String sql, boolean hasOffset) {
|
||||
public String getLimitString(String sql, boolean hasOffset) {
|
||||
|
||||
sql = sql.trim();
|
||||
boolean isForUpdate = false;
|
||||
if ( sql.toLowerCase().endsWith(" for update") ) {
|
||||
if ( sql.toLowerCase().endsWith( " for update" ) ) {
|
||||
sql = sql.substring( 0, sql.length()-11 );
|
||||
isForUpdate = true;
|
||||
}
|
||||
|
||||
StringBuilder pagingSelect = new StringBuilder( sql.length()+100 );
|
||||
final StringBuilder pagingSelect = new StringBuilder( sql.length()+100 );
|
||||
if (hasOffset) {
|
||||
pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
|
||||
pagingSelect.append( "select * from ( select row_.*, rownum rownum_ from ( " );
|
||||
}
|
||||
else {
|
||||
pagingSelect.append("select * from ( ");
|
||||
pagingSelect.append( "select * from ( " );
|
||||
}
|
||||
pagingSelect.append(sql);
|
||||
pagingSelect.append( sql );
|
||||
if (hasOffset) {
|
||||
pagingSelect.append(" ) row_ ) where rownum_ <= ? and rownum_ > ?");
|
||||
pagingSelect.append( " ) row_ ) where rownum_ <= ? and rownum_ > ?" );
|
||||
}
|
||||
else {
|
||||
pagingSelect.append(" ) where rownum <= ?");
|
||||
pagingSelect.append( " ) where rownum <= ?" );
|
||||
}
|
||||
|
||||
if ( isForUpdate ) {
|
||||
@ -95,7 +102,7 @@ public String getLimitString(String sql, boolean hasOffset) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectClauseNullString(int sqlType) {
|
||||
public String getSelectClauseNullString(int sqlType) {
|
||||
switch(sqlType) {
|
||||
case Types.VARCHAR:
|
||||
case Types.CHAR:
|
||||
@ -110,12 +117,12 @@ public String getSelectClauseNullString(int sqlType) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentTimestampSelectString() {
|
||||
public String getCurrentTimestampSelectString() {
|
||||
return "select sysdate from dual";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentTimestampSQLFunctionName() {
|
||||
public String getCurrentTimestampSQLFunctionName() {
|
||||
return "sysdate";
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.ReflectHelper;
|
||||
|
||||
/**
|
||||
* A Helper for dealing with the OracleTypes class
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class OracleTypesHelper {
|
||||
private static final CoreMessageLogger log = Logger.getMessageLogger( CoreMessageLogger.class, OracleTypesHelper.class.getName() );
|
||||
|
||||
/**
|
||||
* Singleton access
|
||||
*/
|
||||
public static final OracleTypesHelper INSTANCE = new OracleTypesHelper();
|
||||
|
||||
private static final String ORACLE_TYPES_CLASS_NAME = "oracle.jdbc.OracleTypes";
|
||||
private static final String DEPRECATED_ORACLE_TYPES_CLASS_NAME = "oracle.jdbc.driver.OracleTypes";
|
||||
|
||||
private final int oracleCursorTypeSqlType;
|
||||
|
||||
private OracleTypesHelper() {
|
||||
int typeCode = -99;
|
||||
try {
|
||||
typeCode = extractOracleCursorTypeValue();
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.warn( "Unable to resolve Oracle CURSOR JDBC type code", e );
|
||||
}
|
||||
oracleCursorTypeSqlType = typeCode;
|
||||
}
|
||||
|
||||
private int extractOracleCursorTypeValue() {
|
||||
try {
|
||||
return locateOracleTypesClass().getField( "CURSOR" ).getInt( null );
|
||||
}
|
||||
catch ( Exception se ) {
|
||||
throw new HibernateException( "Unable to access OracleTypes.CURSOR value", se );
|
||||
}
|
||||
}
|
||||
|
||||
private Class locateOracleTypesClass() {
|
||||
try {
|
||||
return ReflectHelper.classForName( ORACLE_TYPES_CLASS_NAME );
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
try {
|
||||
return ReflectHelper.classForName( DEPRECATED_ORACLE_TYPES_CLASS_NAME );
|
||||
}
|
||||
catch (ClassNotFoundException e2) {
|
||||
throw new HibernateException(
|
||||
String.format(
|
||||
"Unable to locate OracleTypes class using either known FQN [%s, %s]",
|
||||
ORACLE_TYPES_CLASS_NAME,
|
||||
DEPRECATED_ORACLE_TYPES_CLASS_NAME
|
||||
),
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getOracleCursorTypeSqlType() {
|
||||
return oracleCursorTypeSqlType;
|
||||
}
|
||||
|
||||
// initial code as copied from Oracle8iDialect
|
||||
//
|
||||
// private int oracleCursorTypeSqlType = INIT_ORACLETYPES_CURSOR_VALUE;
|
||||
//
|
||||
// public int getOracleCursorTypeSqlType() {
|
||||
// if ( oracleCursorTypeSqlType == INIT_ORACLETYPES_CURSOR_VALUE ) {
|
||||
// // todo : is there really any reason to keep trying if this fails once?
|
||||
// oracleCursorTypeSqlType = extractOracleCursorTypeValue();
|
||||
// }
|
||||
// return oracleCursorTypeSqlType;
|
||||
// }
|
||||
//
|
||||
// private int extractOracleCursorTypeValue() {
|
||||
// Class oracleTypesClass;
|
||||
// try {
|
||||
// oracleTypesClass = ReflectHelper.classForName( ORACLE_TYPES_CLASS_NAME );
|
||||
// }
|
||||
// catch ( ClassNotFoundException cnfe ) {
|
||||
// try {
|
||||
// oracleTypesClass = ReflectHelper.classForName( DEPRECATED_ORACLE_TYPES_CLASS_NAME );
|
||||
// }
|
||||
// catch ( ClassNotFoundException e ) {
|
||||
// throw new HibernateException( "Unable to locate OracleTypes class", e );
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// try {
|
||||
// return oracleTypesClass.getField( "CURSOR" ).getInt( null );
|
||||
// }
|
||||
// catch ( Exception se ) {
|
||||
// throw new HibernateException( "Unable to access OracleTypes.CURSOR value", se );
|
||||
// }
|
||||
// }
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
@ -36,20 +37,22 @@
|
||||
import org.hibernate.persister.entity.Lockable;
|
||||
|
||||
/**
|
||||
* A <tt>Dialect</tt> for Pointbase.
|
||||
* A Dialect for Pointbase.
|
||||
*
|
||||
* @author Ed Mackenzie
|
||||
*/
|
||||
public class PointbaseDialect extends org.hibernate.dialect.Dialect {
|
||||
|
||||
/**
|
||||
* Creates new PointbaseDialect
|
||||
*/
|
||||
public PointbaseDialect() {
|
||||
super();
|
||||
registerColumnType( Types.BIT, "smallint" ); //no pointbase BIT
|
||||
//no pointbase BIT
|
||||
registerColumnType( Types.BIT, "smallint" );
|
||||
registerColumnType( Types.BIGINT, "bigint" );
|
||||
registerColumnType( Types.SMALLINT, "smallint" );
|
||||
registerColumnType( Types.TINYINT, "smallint" ); //no pointbase TINYINT
|
||||
//no pointbase TINYINT
|
||||
registerColumnType( Types.TINYINT, "smallint" );
|
||||
registerColumnType( Types.INTEGER, "integer" );
|
||||
registerColumnType( Types.CHAR, "char(1)" );
|
||||
registerColumnType( Types.VARCHAR, "varchar($l)" );
|
||||
@ -66,22 +69,27 @@ public PointbaseDialect() {
|
||||
registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
return "add";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dropConstraints() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCascadeConstraintsString() {
|
||||
return " cascade";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForUpdateString() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
|
||||
// Pointbase has no known variation of a "SELECT ... FOR UPDATE" syntax...
|
||||
if ( lockMode==LockMode.PESSIMISTIC_FORCE_INCREMENT) {
|
||||
|
@ -57,8 +57,12 @@
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class PostgreSQL81Dialect extends Dialect {
|
||||
|
||||
/**
|
||||
* Constructs a PostgreSQL81Dialect
|
||||
*/
|
||||
public PostgreSQL81Dialect() {
|
||||
super();
|
||||
registerColumnType( Types.BIT, "bool" );
|
||||
@ -152,13 +156,10 @@ public PostgreSQL81Dialect() {
|
||||
|
||||
registerFunction( "str", new SQLFunctionTemplate(StandardBasicTypes.STRING, "cast(?1 as varchar)") );
|
||||
|
||||
getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);
|
||||
getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
|
||||
getDefaultProperties().setProperty( Environment.NON_CONTEXTUAL_LOB_CREATION, "true" );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SqlTypeDescriptor getSqlTypeDescriptorOverride(int sqlCode) {
|
||||
SqlTypeDescriptor descriptor;
|
||||
@ -183,87 +184,100 @@ public SqlTypeDescriptor getSqlTypeDescriptorOverride(int sqlCode) {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
return "add column";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSequenceNextValString(String sequenceName) {
|
||||
return "select " + getSelectSequenceNextValString( sequenceName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectSequenceNextValString(String sequenceName) {
|
||||
return "nextval ('" + sequenceName + "')";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateSequenceString(String sequenceName) {
|
||||
return "create sequence " + sequenceName; //starts with 1, implicitly
|
||||
//starts with 1, implicitly
|
||||
return "create sequence " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDropSequenceString(String sequenceName) {
|
||||
return "drop sequence " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCascadeConstraintsString() {
|
||||
return " cascade";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dropConstraints() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQuerySequencesString() {
|
||||
return "select relname from pg_class where relkind='S'";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLimitString(String sql, boolean hasOffset) {
|
||||
return new StringBuilder( sql.length()+20 )
|
||||
.append( sql )
|
||||
.append( hasOffset ? " limit ? offset ?" : " limit ?" )
|
||||
.toString();
|
||||
return sql + (hasOffset ? " limit ? offset ?" : " limit ?");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean bindLimitParametersInReverseOrder() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsIdentityColumns() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForUpdateString(String aliases) {
|
||||
return getForUpdateString() + " of " + aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentitySelectString(String table, String column, int type) {
|
||||
return new StringBuilder().append("select currval('")
|
||||
.append(table)
|
||||
.append('_')
|
||||
.append(column)
|
||||
.append("_seq')")
|
||||
.toString();
|
||||
return "select currval('" + table + '_' + column + "_seq')";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentityColumnString(int type) {
|
||||
return type==Types.BIGINT ?
|
||||
"bigserial not null" :
|
||||
"serial not null";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDataTypeInIdentityColumn() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNoColumnsInsertString() {
|
||||
return "default values";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCaseInsensitiveLike(){
|
||||
return "ilike";
|
||||
}
|
||||
@ -273,77 +287,88 @@ public boolean supportsCaseInsensitiveLike() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class getNativeIdentifierGeneratorClass() {
|
||||
return SequenceGenerator.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsOuterJoinForUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean useInputStreamToInsertBlob() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsUnionAll() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Workaround for postgres bug #1453
|
||||
* <p/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getSelectClauseNullString(int sqlType) {
|
||||
String typeName = getTypeName(sqlType, 1, 1, 0);
|
||||
String typeName = getTypeName( sqlType, 1, 1, 0 );
|
||||
//trim off the length/precision/scale
|
||||
int loc = typeName.indexOf('(');
|
||||
if (loc>-1) {
|
||||
typeName = typeName.substring(0, loc);
|
||||
final int loc = typeName.indexOf( '(' );
|
||||
if ( loc > -1 ) {
|
||||
typeName = typeName.substring( 0, loc );
|
||||
}
|
||||
return "null::" + typeName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCommentOn() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTemporaryTables() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateTemporaryTableString() {
|
||||
return "create temporary table";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateTemporaryTablePostfix() {
|
||||
return "on commit drop";
|
||||
}
|
||||
|
||||
/*public boolean dropTemporaryTableAfterUse() {
|
||||
//we have to, because postgres sets current tx
|
||||
//to rollback only after a failed create table
|
||||
return true;
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public boolean supportsCurrentTimestampSelection() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurrentTimestampSelectStringCallable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentTimestampSelectString() {
|
||||
return "select now()";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTupleDistinctCounts() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toBooleanValueString(boolean bool) {
|
||||
return bool ? "true" : "false";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
|
||||
return EXTRACTER;
|
||||
}
|
||||
@ -352,25 +377,26 @@ public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
|
||||
* Constraint-name extractor for Postgres constraint violation exceptions.
|
||||
* Orginally contributed by Denny Bartelt.
|
||||
*/
|
||||
private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
|
||||
private static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
|
||||
public String extractConstraintName(SQLException sqle) {
|
||||
try {
|
||||
int sqlState = Integer.valueOf( JdbcExceptionHelper.extractSqlState( sqle ) );
|
||||
final int sqlState = Integer.valueOf( JdbcExceptionHelper.extractSqlState( sqle ) );
|
||||
switch (sqlState) {
|
||||
// CHECK VIOLATION
|
||||
case 23514: return extractUsingTemplate("violates check constraint \"","\"", sqle.getMessage());
|
||||
case 23514: return extractUsingTemplate( "violates check constraint \"","\"", sqle.getMessage() );
|
||||
// UNIQUE VIOLATION
|
||||
case 23505: return extractUsingTemplate("violates unique constraint \"","\"", sqle.getMessage());
|
||||
case 23505: return extractUsingTemplate( "violates unique constraint \"","\"", sqle.getMessage() );
|
||||
// FOREIGN KEY VIOLATION
|
||||
case 23503: return extractUsingTemplate("violates foreign key constraint \"","\"", sqle.getMessage());
|
||||
case 23503: return extractUsingTemplate( "violates foreign key constraint \"","\"", sqle.getMessage() );
|
||||
// NOT NULL VIOLATION
|
||||
case 23502: return extractUsingTemplate("null value in column \"","\" violates not-null constraint", sqle.getMessage());
|
||||
case 23502: return extractUsingTemplate( "null value in column \"","\" violates not-null constraint", sqle.getMessage() );
|
||||
// TODO: RESTRICT VIOLATION
|
||||
case 23001: return null;
|
||||
// ALL OTHER
|
||||
default: return null;
|
||||
}
|
||||
} catch (NumberFormatException nfe) {
|
||||
}
|
||||
catch (NumberFormatException nfe) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -383,11 +409,13 @@ public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
|
||||
public JDBCException convert(SQLException sqlException, String message, String sql) {
|
||||
final String sqlState = JdbcExceptionHelper.extractSqlState( sqlException );
|
||||
|
||||
if ( "40P01".equals( sqlState ) ) { // DEADLOCK DETECTED
|
||||
if ( "40P01".equals( sqlState ) ) {
|
||||
// DEADLOCK DETECTED
|
||||
return new LockAcquisitionException( message, sqlException, sql );
|
||||
}
|
||||
|
||||
if ( "55P03".equals( sqlState ) ) { // LOCK NOT AVAILABLE
|
||||
if ( "55P03".equals( sqlState ) ) {
|
||||
// LOCK NOT AVAILABLE
|
||||
return new PessimisticLockException( message, sqlException, sql );
|
||||
}
|
||||
|
||||
@ -396,37 +424,39 @@ public JDBCException convert(SQLException sqlException, String message, String s
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
|
||||
// Register the type of the out param - PostgreSQL uses Types.OTHER
|
||||
statement.registerOutParameter(col++, Types.OTHER);
|
||||
statement.registerOutParameter( col++, Types.OTHER );
|
||||
return col;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getResultSet(CallableStatement ps) throws SQLException {
|
||||
ps.execute();
|
||||
return (ResultSet) ps.getObject(1);
|
||||
return (ResultSet) ps.getObject( 1 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPooledSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
//only necessary for postgre < 7.4
|
||||
//http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/doc/src/sgml/ref/create_sequence.sgml
|
||||
/**
|
||||
* only necessary for postgre < 7.4 See http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/doc/src/sgml/ref/create_sequence.sgml
|
||||
* <p/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected String getCreateSequenceString(String sequenceName, int initialValue, int incrementSize) {
|
||||
return getCreateSequenceString( sequenceName ) + " start " + initialValue + " increment " + incrementSize;
|
||||
}
|
||||
|
||||
// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// seems to not really...
|
||||
// public boolean supportsRowValueConstructorSyntax() {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
|
||||
public boolean supportsEmptyInList() {
|
||||
@Override
|
||||
public boolean supportsEmptyInList() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -445,25 +475,32 @@ public boolean supportsUnboundedLobLocatorMaterialization() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// locking support
|
||||
@Override
|
||||
public String getForUpdateString() {
|
||||
return " for update";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWriteLockString(int timeout) {
|
||||
if ( timeout == LockOptions.NO_WAIT )
|
||||
if ( timeout == LockOptions.NO_WAIT ) {
|
||||
return " for update nowait";
|
||||
else
|
||||
}
|
||||
else {
|
||||
return " for update";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReadLockString(int timeout) {
|
||||
if ( timeout == LockOptions.NO_WAIT )
|
||||
if ( timeout == LockOptions.NO_WAIT ) {
|
||||
return " for share nowait";
|
||||
else
|
||||
}
|
||||
else {
|
||||
return " for share";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsRowValueConstructorSyntax() {
|
||||
return true;
|
||||
}
|
||||
@ -475,6 +512,6 @@ public String getForUpdateNowaitString() {
|
||||
|
||||
@Override
|
||||
public String getForUpdateNowaitString(String aliases) {
|
||||
return getForUpdateString(aliases) + " nowait ";
|
||||
return getForUpdateString( aliases ) + " nowait ";
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@
|
||||
*/
|
||||
public class PostgreSQL82Dialect extends PostgreSQL81Dialect {
|
||||
@Override
|
||||
public boolean supportsIfExistsBeforeTableName() {
|
||||
return true;
|
||||
}
|
||||
public boolean supportsIfExistsBeforeTableName() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,6 @@
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
|
||||
/**
|
||||
* An SQL dialect for Postgres
|
||||
* <p/>
|
||||
@ -32,6 +31,7 @@
|
||||
* For the effects in regards to Hibernate see <a href="http://in.relation.to/15492.lace">http://in.relation.to/15492.lace</a>
|
||||
*
|
||||
* @author Gavin King
|
||||
*
|
||||
* @deprecated use {@link PostgreSQL82Dialect} instead
|
||||
*/
|
||||
@Deprecated
|
||||
|
@ -37,8 +37,11 @@
|
||||
*
|
||||
* @author Jim Mlodgenski
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class PostgresPlusDialect extends PostgreSQLDialect {
|
||||
|
||||
/**
|
||||
* Constructs a PostgresPlusDialect
|
||||
*/
|
||||
public PostgresPlusDialect() {
|
||||
super();
|
||||
|
||||
@ -65,25 +68,30 @@ public PostgresPlusDialect() {
|
||||
registerFunction( "next_day", new StandardSQLFunction( "next_day", StandardBasicTypes.DATE ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentTimestampSelectString() {
|
||||
return "select sysdate";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentTimestampSQLFunctionName() {
|
||||
return "sysdate";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
|
||||
statement.registerOutParameter( col, Types.REF );
|
||||
col++;
|
||||
return col;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getResultSet(CallableStatement ps) throws SQLException {
|
||||
ps.execute();
|
||||
return ( ResultSet ) ps.getObject( 1 );
|
||||
return (ResultSet) ps.getObject( 1 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectGUIDString() {
|
||||
return "select uuid_generate_v1";
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
/**
|
||||
@ -41,6 +42,9 @@
|
||||
*
|
||||
*/
|
||||
public class ProgressDialect extends Dialect {
|
||||
/**
|
||||
* Constructs a ProgressDialect
|
||||
*/
|
||||
public ProgressDialect() {
|
||||
super();
|
||||
registerColumnType( Types.BIT, "bit" );
|
||||
@ -59,14 +63,17 @@ public ProgressDialect() {
|
||||
registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAlterTable(){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
return "add column";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean qualifyIndexName() {
|
||||
return false;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
@ -48,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
* <p/>
|
||||
* Version History:
|
||||
* Also change the version displayed below in the constructor
|
||||
* 1.1
|
||||
@ -56,108 +57,114 @@
|
||||
*
|
||||
* @author Ploski and Hanson
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class RDMSOS2200Dialect extends Dialect {
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
RDMSOS2200Dialect.class.getName()
|
||||
);
|
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, RDMSOS2200Dialect.class.getName());
|
||||
|
||||
/**
|
||||
* Constructs a RDMSOS2200Dialect
|
||||
*/
|
||||
public RDMSOS2200Dialect() {
|
||||
super();
|
||||
// Display the dialect version.
|
||||
LOG.rdmsOs2200Dialect();
|
||||
|
||||
/**
|
||||
* This section registers RDMS Built-in Functions (BIFs) with Hibernate.
|
||||
* The first parameter is the 'register' function name with Hibernate.
|
||||
* The second parameter is the defined RDMS SQL Function and it's
|
||||
* characteristics. If StandardSQLFunction(...) is used, the RDMS BIF
|
||||
* name and the return type (if any) is specified. If
|
||||
* SQLFunctionTemplate(...) is used, the return type and a template
|
||||
* string is provided, plus an optional hasParenthesesIfNoArgs flag.
|
||||
*/
|
||||
registerFunction( "abs", new StandardSQLFunction("abs") );
|
||||
registerFunction( "sign", new StandardSQLFunction("sign", StandardBasicTypes.INTEGER) );
|
||||
/**
|
||||
* This section registers RDMS Built-in Functions (BIFs) with Hibernate.
|
||||
* The first parameter is the 'register' function name with Hibernate.
|
||||
* The second parameter is the defined RDMS SQL Function and it's
|
||||
* characteristics. If StandardSQLFunction(...) is used, the RDMS BIF
|
||||
* name and the return type (if any) is specified. If
|
||||
* SQLFunctionTemplate(...) is used, the return type and a template
|
||||
* string is provided, plus an optional hasParenthesesIfNoArgs flag.
|
||||
*/
|
||||
registerFunction( "abs", new StandardSQLFunction( "abs" ) );
|
||||
registerFunction( "sign", new StandardSQLFunction( "sign", StandardBasicTypes.INTEGER ) );
|
||||
|
||||
registerFunction("ascii", new StandardSQLFunction("ascii", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("char_length", new StandardSQLFunction("char_length", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("character_length", new StandardSQLFunction("character_length", StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "ascii", new StandardSQLFunction( "ascii", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "char_length", new StandardSQLFunction( "char_length", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "character_length", new StandardSQLFunction( "character_length", StandardBasicTypes.INTEGER ) );
|
||||
|
||||
// The RDMS concat() function only supports 2 parameters
|
||||
registerFunction( "concat", new SQLFunctionTemplate(StandardBasicTypes.STRING, "concat(?1, ?2)") );
|
||||
registerFunction( "instr", new StandardSQLFunction("instr", StandardBasicTypes.STRING) );
|
||||
registerFunction( "lpad", new StandardSQLFunction("lpad", StandardBasicTypes.STRING) );
|
||||
registerFunction( "replace", new StandardSQLFunction("replace", StandardBasicTypes.STRING) );
|
||||
registerFunction( "rpad", new StandardSQLFunction("rpad", StandardBasicTypes.STRING) );
|
||||
registerFunction( "substr", new StandardSQLFunction("substr", StandardBasicTypes.STRING) );
|
||||
registerFunction( "concat", new SQLFunctionTemplate( StandardBasicTypes.STRING, "concat(?1, ?2)" ) );
|
||||
registerFunction( "instr", new StandardSQLFunction( "instr", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "lpad", new StandardSQLFunction( "lpad", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "replace", new StandardSQLFunction( "replace", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "rpad", new StandardSQLFunction( "rpad", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "substr", new StandardSQLFunction( "substr", StandardBasicTypes.STRING ) );
|
||||
|
||||
registerFunction("lcase", new StandardSQLFunction("lcase") );
|
||||
registerFunction("lower", new StandardSQLFunction("lower") );
|
||||
registerFunction("ltrim", new StandardSQLFunction("ltrim") );
|
||||
registerFunction("reverse", new StandardSQLFunction("reverse") );
|
||||
registerFunction("rtrim", new StandardSQLFunction("rtrim") );
|
||||
registerFunction( "lcase", new StandardSQLFunction( "lcase" ) );
|
||||
registerFunction( "lower", new StandardSQLFunction( "lower" ) );
|
||||
registerFunction( "ltrim", new StandardSQLFunction( "ltrim" ) );
|
||||
registerFunction( "reverse", new StandardSQLFunction( "reverse" ) );
|
||||
registerFunction( "rtrim", new StandardSQLFunction( "rtrim" ) );
|
||||
|
||||
// RDMS does not directly support the trim() function, we use rtrim() and ltrim()
|
||||
registerFunction("trim", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "ltrim(rtrim(?1))" ) );
|
||||
registerFunction("soundex", new StandardSQLFunction("soundex") );
|
||||
registerFunction("space", new StandardSQLFunction("space", StandardBasicTypes.STRING) );
|
||||
registerFunction("ucase", new StandardSQLFunction("ucase") );
|
||||
registerFunction("upper", new StandardSQLFunction("upper") );
|
||||
registerFunction( "trim", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "ltrim(rtrim(?1))" ) );
|
||||
registerFunction( "soundex", new StandardSQLFunction( "soundex" ) );
|
||||
registerFunction( "space", new StandardSQLFunction( "space", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "ucase", new StandardSQLFunction( "ucase" ) );
|
||||
registerFunction( "upper", new StandardSQLFunction( "upper" ) );
|
||||
|
||||
registerFunction("acos", new StandardSQLFunction("acos", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("asin", new StandardSQLFunction("asin", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("atan", new StandardSQLFunction("atan", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("cos", new StandardSQLFunction("cos", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("cosh", new StandardSQLFunction("cosh", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("cot", new StandardSQLFunction("cot", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("exp", new StandardSQLFunction("exp", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("ln", new StandardSQLFunction("ln", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("log", new StandardSQLFunction("log", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("log10", new StandardSQLFunction("log10", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("pi", new NoArgSQLFunction("pi", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("rand", new NoArgSQLFunction("rand", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("sin", new StandardSQLFunction("sin", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("sinh", new StandardSQLFunction("sinh", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("sqrt", new StandardSQLFunction("sqrt", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("tan", new StandardSQLFunction("tan", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction("tanh", new StandardSQLFunction("tanh", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "acos", new StandardSQLFunction( "acos", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "asin", new StandardSQLFunction( "asin", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "atan", new StandardSQLFunction( "atan", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "cos", new StandardSQLFunction( "cos", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "cosh", new StandardSQLFunction( "cosh", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "cot", new StandardSQLFunction( "cot", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "exp", new StandardSQLFunction( "exp", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "ln", new StandardSQLFunction( "ln", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "log", new StandardSQLFunction( "log", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "log10", new StandardSQLFunction( "log10", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "pi", new NoArgSQLFunction( "pi", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "rand", new NoArgSQLFunction( "rand", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "sin", new StandardSQLFunction( "sin", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "sinh", new StandardSQLFunction( "sinh", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "sqrt", new StandardSQLFunction( "sqrt", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "tan", new StandardSQLFunction( "tan", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "tanh", new StandardSQLFunction( "tanh", StandardBasicTypes.DOUBLE ) );
|
||||
|
||||
registerFunction( "round", new StandardSQLFunction("round") );
|
||||
registerFunction( "trunc", new StandardSQLFunction("trunc") );
|
||||
registerFunction( "ceil", new StandardSQLFunction("ceil") );
|
||||
registerFunction( "floor", new StandardSQLFunction("floor") );
|
||||
registerFunction( "round", new StandardSQLFunction( "round" ) );
|
||||
registerFunction( "trunc", new StandardSQLFunction( "trunc" ) );
|
||||
registerFunction( "ceil", new StandardSQLFunction( "ceil" ) );
|
||||
registerFunction( "floor", new StandardSQLFunction( "floor" ) );
|
||||
|
||||
registerFunction( "chr", new StandardSQLFunction("chr", StandardBasicTypes.CHARACTER) );
|
||||
registerFunction( "initcap", new StandardSQLFunction("initcap") );
|
||||
registerFunction( "chr", new StandardSQLFunction( "chr", StandardBasicTypes.CHARACTER ) );
|
||||
registerFunction( "initcap", new StandardSQLFunction( "initcap" ) );
|
||||
|
||||
registerFunction( "user", new NoArgSQLFunction("user", StandardBasicTypes.STRING, false) );
|
||||
registerFunction( "user", new NoArgSQLFunction( "user", StandardBasicTypes.STRING, false ) );
|
||||
|
||||
registerFunction( "current_date", new NoArgSQLFunction("current_date", StandardBasicTypes.DATE, false) );
|
||||
registerFunction( "current_time", new NoArgSQLFunction("current_timestamp", StandardBasicTypes.TIME, false) );
|
||||
registerFunction( "current_timestamp", new NoArgSQLFunction("current_timestamp", StandardBasicTypes.TIMESTAMP, false) );
|
||||
registerFunction("curdate", new NoArgSQLFunction("curdate",StandardBasicTypes.DATE) );
|
||||
registerFunction("curtime", new NoArgSQLFunction("curtime",StandardBasicTypes.TIME) );
|
||||
registerFunction("days", new StandardSQLFunction("days",StandardBasicTypes.INTEGER) );
|
||||
registerFunction("dayofmonth", new StandardSQLFunction("dayofmonth",StandardBasicTypes.INTEGER) );
|
||||
registerFunction("dayname", new StandardSQLFunction("dayname",StandardBasicTypes.STRING) );
|
||||
registerFunction("dayofweek", new StandardSQLFunction("dayofweek",StandardBasicTypes.INTEGER) );
|
||||
registerFunction("dayofyear", new StandardSQLFunction("dayofyear",StandardBasicTypes.INTEGER) );
|
||||
registerFunction("hour", new StandardSQLFunction("hour",StandardBasicTypes.INTEGER) );
|
||||
registerFunction("last_day", new StandardSQLFunction("last_day",StandardBasicTypes.DATE) );
|
||||
registerFunction("microsecond", new StandardSQLFunction("microsecond",StandardBasicTypes.INTEGER) );
|
||||
registerFunction("minute", new StandardSQLFunction("minute",StandardBasicTypes.INTEGER) );
|
||||
registerFunction("month", new StandardSQLFunction("month",StandardBasicTypes.INTEGER) );
|
||||
registerFunction("monthname", new StandardSQLFunction("monthname",StandardBasicTypes.STRING) );
|
||||
registerFunction("now", new NoArgSQLFunction("now",StandardBasicTypes.TIMESTAMP) );
|
||||
registerFunction("quarter", new StandardSQLFunction("quarter",StandardBasicTypes.INTEGER) );
|
||||
registerFunction("second", new StandardSQLFunction("second",StandardBasicTypes.INTEGER) );
|
||||
registerFunction("time", new StandardSQLFunction("time",StandardBasicTypes.TIME) );
|
||||
registerFunction("timestamp", new StandardSQLFunction("timestamp",StandardBasicTypes.TIMESTAMP) );
|
||||
registerFunction("week", new StandardSQLFunction("week",StandardBasicTypes.INTEGER) );
|
||||
registerFunction("year", new StandardSQLFunction("year",StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "current_date", new NoArgSQLFunction( "current_date", StandardBasicTypes.DATE, false ) );
|
||||
registerFunction( "current_time", new NoArgSQLFunction( "current_timestamp", StandardBasicTypes.TIME, false ) );
|
||||
registerFunction( "current_timestamp", new NoArgSQLFunction( "current_timestamp", StandardBasicTypes.TIMESTAMP, false ) );
|
||||
registerFunction( "curdate", new NoArgSQLFunction( "curdate", StandardBasicTypes.DATE ) );
|
||||
registerFunction( "curtime", new NoArgSQLFunction( "curtime", StandardBasicTypes.TIME ) );
|
||||
registerFunction( "days", new StandardSQLFunction( "days", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "dayofmonth", new StandardSQLFunction( "dayofmonth", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "dayname", new StandardSQLFunction( "dayname", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "dayofweek", new StandardSQLFunction( "dayofweek", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "dayofyear", new StandardSQLFunction( "dayofyear", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "hour", new StandardSQLFunction( "hour", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "last_day", new StandardSQLFunction( "last_day", StandardBasicTypes.DATE ) );
|
||||
registerFunction( "microsecond", new StandardSQLFunction( "microsecond", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "minute", new StandardSQLFunction( "minute", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "month", new StandardSQLFunction( "month", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "monthname", new StandardSQLFunction( "monthname", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "now", new NoArgSQLFunction( "now", StandardBasicTypes.TIMESTAMP ) );
|
||||
registerFunction( "quarter", new StandardSQLFunction( "quarter", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "second", new StandardSQLFunction( "second", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "time", new StandardSQLFunction( "time", StandardBasicTypes.TIME ) );
|
||||
registerFunction( "timestamp", new StandardSQLFunction( "timestamp", StandardBasicTypes.TIMESTAMP ) );
|
||||
registerFunction( "week", new StandardSQLFunction( "week", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "year", new StandardSQLFunction( "year", StandardBasicTypes.INTEGER ) );
|
||||
|
||||
registerFunction("atan2", new StandardSQLFunction("atan2",StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "mod", new StandardSQLFunction("mod",StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "nvl", new StandardSQLFunction("nvl") );
|
||||
registerFunction( "power", new StandardSQLFunction("power", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "atan2", new StandardSQLFunction( "atan2", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "mod", new StandardSQLFunction( "mod", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "nvl", new StandardSQLFunction( "nvl" ) );
|
||||
registerFunction( "power", new StandardSQLFunction( "power", StandardBasicTypes.DOUBLE ) );
|
||||
|
||||
/**
|
||||
* For a list of column types to register, see section A-1
|
||||
@ -184,169 +191,189 @@ public RDMSOS2200Dialect() {
|
||||
* Note that $l (dollar-L) will use the length value if provided.
|
||||
* Also new for Hibernate3 is the $p percision and $s (scale) parameters
|
||||
*/
|
||||
registerColumnType(Types.BIT, "SMALLINT");
|
||||
registerColumnType(Types.TINYINT, "SMALLINT");
|
||||
registerColumnType(Types.BIGINT, "NUMERIC(21,0)");
|
||||
registerColumnType(Types.SMALLINT, "SMALLINT");
|
||||
registerColumnType(Types.CHAR, "CHARACTER(1)");
|
||||
registerColumnType(Types.DOUBLE, "DOUBLE PRECISION");
|
||||
registerColumnType(Types.FLOAT, "FLOAT");
|
||||
registerColumnType(Types.REAL, "REAL");
|
||||
registerColumnType(Types.INTEGER, "INTEGER");
|
||||
registerColumnType(Types.NUMERIC, "NUMERIC(21,$l)");
|
||||
registerColumnType(Types.DECIMAL, "NUMERIC(21,$l)");
|
||||
registerColumnType(Types.DATE, "DATE");
|
||||
registerColumnType(Types.TIME, "TIME");
|
||||
registerColumnType(Types.TIMESTAMP, "TIMESTAMP");
|
||||
registerColumnType(Types.VARCHAR, "CHARACTER($l)");
|
||||
registerColumnType(Types.BLOB, "BLOB($l)" );
|
||||
/*
|
||||
registerColumnType( Types.BIT, "SMALLINT" );
|
||||
registerColumnType( Types.TINYINT, "SMALLINT" );
|
||||
registerColumnType( Types.BIGINT, "NUMERIC(21,0)" );
|
||||
registerColumnType( Types.SMALLINT, "SMALLINT" );
|
||||
registerColumnType( Types.CHAR, "CHARACTER(1)" );
|
||||
registerColumnType( Types.DOUBLE, "DOUBLE PRECISION" );
|
||||
registerColumnType( Types.FLOAT, "FLOAT" );
|
||||
registerColumnType( Types.REAL, "REAL" );
|
||||
registerColumnType( Types.INTEGER, "INTEGER" );
|
||||
registerColumnType( Types.NUMERIC, "NUMERIC(21,$l)" );
|
||||
registerColumnType( Types.DECIMAL, "NUMERIC(21,$l)" );
|
||||
registerColumnType( Types.DATE, "DATE" );
|
||||
registerColumnType( Types.TIME, "TIME" );
|
||||
registerColumnType( Types.TIMESTAMP, "TIMESTAMP" );
|
||||
registerColumnType( Types.VARCHAR, "CHARACTER($l)" );
|
||||
registerColumnType( Types.BLOB, "BLOB($l)" );
|
||||
/*
|
||||
* The following types are not supported in RDMS/JDBC and therefore commented out.
|
||||
* However, in some cases, mapping them to CHARACTER columns works
|
||||
* for many applications, but does not work for all cases.
|
||||
*/
|
||||
// registerColumnType(Types.VARBINARY, "CHARACTER($l)");
|
||||
// registerColumnType(Types.BLOB, "CHARACTER($l)" ); // For use prior to CP 11.0
|
||||
// registerColumnType(Types.CLOB, "CHARACTER($l)" );
|
||||
// registerColumnType(Types.VARBINARY, "CHARACTER($l)");
|
||||
// registerColumnType(Types.BLOB, "CHARACTER($l)" ); // For use prior to CP 11.0
|
||||
// registerColumnType(Types.CLOB, "CHARACTER($l)" );
|
||||
}
|
||||
|
||||
|
||||
// Dialect method overrides ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
* RDMS does not support qualifing index names with the schema name.
|
||||
*/
|
||||
/**
|
||||
* RDMS does not support qualifing index names with the schema name.
|
||||
* <p/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean qualifyIndexName() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The RDMS DB supports the 'FOR UPDATE OF' clause. However, the RDMS-JDBC
|
||||
* driver does not support this feature, so a false is return.
|
||||
* The base dialect also returns a false, but we will leave this over-ride
|
||||
* in to make sure it stays false.
|
||||
* driver does not support this feature, so a false is return.
|
||||
* The base dialect also returns a false, but we will leave this over-ride
|
||||
* in to make sure it stays false.
|
||||
* <p/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean forUpdateOfColumns() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Since the RDMS-JDBC driver does not support for updates, this string is
|
||||
* set to an empty string. Whenever, the driver does support this feature,
|
||||
* the returned string should be " FOR UPDATE OF". Note that RDMS does not
|
||||
* support the string 'FOR UPDATE' string.
|
||||
* set to an empty string. Whenever, the driver does support this feature,
|
||||
* the returned string should be " FOR UPDATE OF". Note that RDMS does not
|
||||
* support the string 'FOR UPDATE' string.
|
||||
* <p/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getForUpdateString() {
|
||||
return ""; // Original Dialect.java returns " for update";
|
||||
// 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.
|
||||
*/
|
||||
public boolean supportsCascadeDelete() {
|
||||
return false; // Origial Dialect.java returns true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Currently, RDMS-JDBC does not support ForUpdate.
|
||||
* Need to review this in the future when support is provided.
|
||||
* RDMS does not support Cascade Deletes.
|
||||
* Need to review this in the future when support is provided.
|
||||
* <p/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean supportsOuterJoinForUpdate() {
|
||||
@Override
|
||||
public boolean supportsCascadeDelete() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Currently, RDMS-JDBC does not support ForUpdate.
|
||||
* Need to review this in the future when support is provided.
|
||||
* <p/>
|
||||
* {@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";
|
||||
}
|
||||
|
||||
// *** Sequence methods - start. The RDMS dialect needs these
|
||||
|
||||
// methods to make it possible to use the Native Id generator
|
||||
|
||||
@Override
|
||||
public boolean supportsSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSequenceNextValString(String sequenceName) {
|
||||
// The where clause was added to eliminate this statement from Brute Force Searches.
|
||||
return "select permuted_id('NEXT',31) from rdms.rdms_dummy where key_col = 1 ";
|
||||
// The where clause was added to eliminate this statement from Brute Force Searches.
|
||||
return "select permuted_id('NEXT',31) from rdms.rdms_dummy where key_col = 1 ";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateSequenceString(String sequenceName) {
|
||||
// We must return a valid RDMS/RSA command from this method to
|
||||
// prevent RDMS/RSA from issuing *ERROR 400
|
||||
return "";
|
||||
// We must return a valid RDMS/RSA command from this method to
|
||||
// prevent RDMS/RSA from issuing *ERROR 400
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDropSequenceString(String sequenceName) {
|
||||
// We must return a valid RDMS/RSA command from this method to
|
||||
// prevent RDMS/RSA from issuing *ERROR 400
|
||||
return "";
|
||||
// We must return a valid RDMS/RSA command from this method to
|
||||
// prevent RDMS/RSA from issuing *ERROR 400
|
||||
return "";
|
||||
}
|
||||
|
||||
// *** Sequence methods - end
|
||||
|
||||
public String getCascadeConstraintsString() {
|
||||
// Used with DROP TABLE to delete all records in the table.
|
||||
return " including contents";
|
||||
}
|
||||
@Override
|
||||
public String getCascadeConstraintsString() {
|
||||
// Used with DROP TABLE to delete all records in the table.
|
||||
return " including contents";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CaseFragment createCaseFragment() {
|
||||
return new DecodeCaseFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLimitOffset() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getLimitString(String sql, int offset, int limit) {
|
||||
@Override
|
||||
public String getLimitString(String sql, int offset, int limit) {
|
||||
if ( offset > 0 ) {
|
||||
throw new UnsupportedOperationException( "query result offset is not supported" );
|
||||
}
|
||||
return new StringBuilder( sql.length() + 40 )
|
||||
.append( sql )
|
||||
.append( " fetch first " )
|
||||
.append( limit )
|
||||
.append( " rows only " )
|
||||
.toString();
|
||||
return sql + " fetch first " + limit + " rows only ";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsVariableLimit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsUnionAll() {
|
||||
// RDMS supports the UNION ALL clause.
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
|
||||
// RDMS has no known variation of a "SELECT ... FOR UPDATE" syntax...
|
||||
if ( lockMode==LockMode.PESSIMISTIC_FORCE_INCREMENT) {
|
||||
return new PessimisticForceIncrementLockingStrategy( lockable, lockMode);
|
||||
if ( lockMode == LockMode.PESSIMISTIC_FORCE_INCREMENT ) {
|
||||
return new PessimisticForceIncrementLockingStrategy( lockable, lockMode );
|
||||
}
|
||||
else if ( lockMode==LockMode.PESSIMISTIC_WRITE) {
|
||||
return new PessimisticWriteUpdateLockingStrategy( lockable, lockMode);
|
||||
else if ( lockMode == LockMode.PESSIMISTIC_WRITE ) {
|
||||
return new PessimisticWriteUpdateLockingStrategy( lockable, lockMode );
|
||||
}
|
||||
else if ( lockMode==LockMode.PESSIMISTIC_READ) {
|
||||
return new PessimisticReadUpdateLockingStrategy( lockable, lockMode);
|
||||
else if ( lockMode == LockMode.PESSIMISTIC_READ ) {
|
||||
return new PessimisticReadUpdateLockingStrategy( lockable, lockMode );
|
||||
}
|
||||
else if ( lockMode==LockMode.OPTIMISTIC) {
|
||||
return new OptimisticLockingStrategy( lockable, lockMode);
|
||||
else if ( lockMode == LockMode.OPTIMISTIC ) {
|
||||
return new OptimisticLockingStrategy( lockable, lockMode );
|
||||
}
|
||||
else if ( lockMode==LockMode.OPTIMISTIC_FORCE_INCREMENT) {
|
||||
return new OptimisticForceIncrementLockingStrategy( lockable, lockMode);
|
||||
else if ( lockMode == LockMode.OPTIMISTIC_FORCE_INCREMENT ) {
|
||||
return new OptimisticForceIncrementLockingStrategy( lockable, lockMode );
|
||||
}
|
||||
else if ( lockMode.greaterThan( LockMode.READ ) ) {
|
||||
return new UpdateLockingStrategy( lockable, lockMode );
|
||||
|
@ -21,11 +21,7 @@
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
import java.io.ObjectStreamException;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
package org.hibernate.dialect;
|
||||
|
||||
/**
|
||||
* Defines how we need to reference columns in the group-by, having, and order-by
|
||||
@ -33,18 +29,14 @@
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ResultColumnReferenceStrategy implements Serializable {
|
||||
|
||||
private static final Map INSTANCES = new HashMap();
|
||||
|
||||
public enum ResultColumnReferenceStrategy {
|
||||
/**
|
||||
* This strategy says to reference the result columns by the qualified column name
|
||||
* found in the result source. This strategy is not strictly allowed by ANSI SQL
|
||||
* but is Hibernate's legacy behavior and is also the fastest of the strategies; thus
|
||||
* it should be used if supported by the underlying database.
|
||||
*/
|
||||
public static final ResultColumnReferenceStrategy SOURCE = new ResultColumnReferenceStrategy( "source");
|
||||
|
||||
SOURCE,
|
||||
/**
|
||||
* For databases which do not support {@link #SOURCE}, ANSI SQL defines two allowable
|
||||
* approaches. One is to reference the result column by the alias it is given in the
|
||||
@ -52,8 +44,7 @@ public class ResultColumnReferenceStrategy implements Serializable {
|
||||
* <p/>
|
||||
* The other QNSI SQL compliant approach is {@link #ORDINAL}.
|
||||
*/
|
||||
public static final ResultColumnReferenceStrategy ALIAS = new ResultColumnReferenceStrategy( "alias" );
|
||||
|
||||
ALIAS,
|
||||
/**
|
||||
* For databases which do not support {@link #SOURCE}, ANSI SQL defines two allowable
|
||||
* approaches. One is to reference the result column by the ordinal position at which
|
||||
@ -61,29 +52,25 @@ public class ResultColumnReferenceStrategy implements Serializable {
|
||||
* <p/>
|
||||
* The other QNSI SQL compliant approach is {@link #ALIAS}.
|
||||
*/
|
||||
public static final ResultColumnReferenceStrategy ORDINAL = new ResultColumnReferenceStrategy( "ordinal" );
|
||||
ORDINAL;
|
||||
|
||||
static {
|
||||
ResultColumnReferenceStrategy.INSTANCES.put( ResultColumnReferenceStrategy.SOURCE.name, ResultColumnReferenceStrategy.SOURCE );
|
||||
ResultColumnReferenceStrategy.INSTANCES.put( ResultColumnReferenceStrategy.ALIAS.name, ResultColumnReferenceStrategy.ALIAS );
|
||||
ResultColumnReferenceStrategy.INSTANCES.put( ResultColumnReferenceStrategy.ORDINAL.name, ResultColumnReferenceStrategy.ORDINAL );
|
||||
}
|
||||
|
||||
private final String name;
|
||||
|
||||
public ResultColumnReferenceStrategy(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
private Object readResolve() throws ObjectStreamException {
|
||||
return parse( name );
|
||||
}
|
||||
|
||||
public static ResultColumnReferenceStrategy parse(String name) {
|
||||
return ( ResultColumnReferenceStrategy ) ResultColumnReferenceStrategy.INSTANCES.get( name );
|
||||
/**
|
||||
* Resolves the strategy by name, in a case insensitive manner. If the name cannot be resolved, {@link #SOURCE}
|
||||
* is returned as the default.
|
||||
*
|
||||
* @param name The strategy name to resolve
|
||||
*
|
||||
* @return The resolved strategy
|
||||
*/
|
||||
public static ResultColumnReferenceStrategy resolveByName(String name) {
|
||||
if ( ALIAS.name().equalsIgnoreCase( name ) ) {
|
||||
return ALIAS;
|
||||
}
|
||||
else if ( ORDINAL.name().equalsIgnoreCase( name ) ) {
|
||||
return ORDINAL;
|
||||
}
|
||||
else {
|
||||
return SOURCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,10 +37,13 @@
|
||||
|
||||
/**
|
||||
* An SQL dialect compatible with SAP DB.
|
||||
*
|
||||
* @author Brad Clow
|
||||
*/
|
||||
public class SAPDBDialect extends Dialect {
|
||||
|
||||
/**
|
||||
* Constructs a SAPDBDialect
|
||||
*/
|
||||
public SAPDBDialect() {
|
||||
super();
|
||||
registerColumnType( Types.BIT, "boolean" );
|
||||
@ -60,160 +63,175 @@ public SAPDBDialect() {
|
||||
registerColumnType( Types.CLOB, "long varchar" );
|
||||
registerColumnType( Types.BLOB, "long byte" );
|
||||
|
||||
registerFunction( "abs", new StandardSQLFunction("abs") );
|
||||
registerFunction( "sign", new StandardSQLFunction("sign", StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "abs", new StandardSQLFunction( "abs" ) );
|
||||
registerFunction( "sign", new StandardSQLFunction( "sign", StandardBasicTypes.INTEGER ) );
|
||||
|
||||
registerFunction( "exp", new StandardSQLFunction("exp", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "ln", new StandardSQLFunction("ln", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "log", new StandardSQLFunction("ln", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "pi", new NoArgSQLFunction("pi", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "power", new StandardSQLFunction("power") );
|
||||
registerFunction( "acos", new StandardSQLFunction("acos", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "asin", new StandardSQLFunction("asin", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "atan", new StandardSQLFunction("atan", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "cos", new StandardSQLFunction("cos", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "cosh", new StandardSQLFunction("cosh", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "cot", new StandardSQLFunction("cos", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "sin", new StandardSQLFunction("sin", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "sinh", new StandardSQLFunction("sinh", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "tan", new StandardSQLFunction("tan", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "tanh", new StandardSQLFunction("tanh", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "radians", new StandardSQLFunction("radians", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "degrees", new StandardSQLFunction("degrees", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "atan2", new StandardSQLFunction("atan2", StandardBasicTypes.DOUBLE) );
|
||||
registerFunction( "exp", new StandardSQLFunction( "exp", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "ln", new StandardSQLFunction( "ln", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "log", new StandardSQLFunction( "ln", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "pi", new NoArgSQLFunction( "pi", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "power", new StandardSQLFunction( "power" ) );
|
||||
registerFunction( "acos", new StandardSQLFunction( "acos", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "asin", new StandardSQLFunction( "asin", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "atan", new StandardSQLFunction( "atan", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "cos", new StandardSQLFunction( "cos", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "cosh", new StandardSQLFunction( "cosh", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "cot", new StandardSQLFunction( "cos", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "sin", new StandardSQLFunction( "sin", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "sinh", new StandardSQLFunction( "sinh", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "tan", new StandardSQLFunction( "tan", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "tanh", new StandardSQLFunction( "tanh", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "radians", new StandardSQLFunction( "radians", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "degrees", new StandardSQLFunction( "degrees", StandardBasicTypes.DOUBLE ) );
|
||||
registerFunction( "atan2", new StandardSQLFunction( "atan2", StandardBasicTypes.DOUBLE ) );
|
||||
|
||||
registerFunction( "round", new StandardSQLFunction("round") );
|
||||
registerFunction( "trunc", new StandardSQLFunction("trunc") );
|
||||
registerFunction( "ceil", new StandardSQLFunction("ceil") );
|
||||
registerFunction( "floor", new StandardSQLFunction("floor") );
|
||||
registerFunction( "greatest", new StandardSQLFunction("greatest") );
|
||||
registerFunction( "least", new StandardSQLFunction("least") );
|
||||
registerFunction( "round", new StandardSQLFunction( "round" ) );
|
||||
registerFunction( "trunc", new StandardSQLFunction( "trunc" ) );
|
||||
registerFunction( "ceil", new StandardSQLFunction( "ceil" ) );
|
||||
registerFunction( "floor", new StandardSQLFunction( "floor" ) );
|
||||
registerFunction( "greatest", new StandardSQLFunction( "greatest" ) );
|
||||
registerFunction( "least", new StandardSQLFunction( "least" ) );
|
||||
|
||||
registerFunction("time", new StandardSQLFunction("time", StandardBasicTypes.TIME) );
|
||||
registerFunction("timestamp", new StandardSQLFunction("timestamp", StandardBasicTypes.TIMESTAMP) );
|
||||
registerFunction("date", new StandardSQLFunction("date", StandardBasicTypes.DATE) );
|
||||
registerFunction("microsecond", new StandardSQLFunction("microsecond", StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "time", new StandardSQLFunction( "time", StandardBasicTypes.TIME ) );
|
||||
registerFunction( "timestamp", new StandardSQLFunction( "timestamp", StandardBasicTypes.TIMESTAMP ) );
|
||||
registerFunction( "date", new StandardSQLFunction( "date", StandardBasicTypes.DATE ) );
|
||||
registerFunction( "microsecond", new StandardSQLFunction( "microsecond", StandardBasicTypes.INTEGER ) );
|
||||
|
||||
registerFunction( "second", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "second(?1)") );
|
||||
registerFunction( "minute", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "minute(?1)") );
|
||||
registerFunction( "hour", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "hour(?1)") );
|
||||
registerFunction( "day", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "day(?1)") );
|
||||
registerFunction( "month", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "month(?1)") );
|
||||
registerFunction( "year", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "year(?1)") );
|
||||
registerFunction( "second", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "second(?1)" ) );
|
||||
registerFunction( "minute", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "minute(?1)" ) );
|
||||
registerFunction( "hour", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "hour(?1)" ) );
|
||||
registerFunction( "day", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "day(?1)" ) );
|
||||
registerFunction( "month", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "month(?1)" ) );
|
||||
registerFunction( "year", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "year(?1)" ) );
|
||||
|
||||
registerFunction( "extract", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "?1(?3)") );
|
||||
registerFunction( "extract", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "?1(?3)" ) );
|
||||
|
||||
registerFunction("dayname", new StandardSQLFunction("dayname", StandardBasicTypes.STRING) );
|
||||
registerFunction("monthname", new StandardSQLFunction("monthname", StandardBasicTypes.STRING) );
|
||||
registerFunction("dayofmonth", new StandardSQLFunction("dayofmonth", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("dayofweek", new StandardSQLFunction("dayofweek", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("dayofyear", new StandardSQLFunction("dayofyear", StandardBasicTypes.INTEGER) );
|
||||
registerFunction("weekofyear", new StandardSQLFunction("weekofyear", StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "dayname", new StandardSQLFunction( "dayname", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "monthname", new StandardSQLFunction( "monthname", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "dayofmonth", new StandardSQLFunction( "dayofmonth", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "dayofweek", new StandardSQLFunction( "dayofweek", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "dayofyear", new StandardSQLFunction( "dayofyear", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "weekofyear", new StandardSQLFunction( "weekofyear", StandardBasicTypes.INTEGER ) );
|
||||
|
||||
registerFunction( "replace", new StandardSQLFunction("replace", StandardBasicTypes.STRING) );
|
||||
registerFunction( "translate", new StandardSQLFunction("translate", StandardBasicTypes.STRING) );
|
||||
registerFunction( "lpad", new StandardSQLFunction("lpad", StandardBasicTypes.STRING) );
|
||||
registerFunction( "rpad", new StandardSQLFunction("rpad", StandardBasicTypes.STRING) );
|
||||
registerFunction( "substr", new StandardSQLFunction("substr", StandardBasicTypes.STRING) );
|
||||
registerFunction( "initcap", new StandardSQLFunction("initcap", StandardBasicTypes.STRING) );
|
||||
registerFunction( "lower", new StandardSQLFunction("lower", StandardBasicTypes.STRING) );
|
||||
registerFunction( "ltrim", new StandardSQLFunction("ltrim", StandardBasicTypes.STRING) );
|
||||
registerFunction( "rtrim", new StandardSQLFunction("rtrim", StandardBasicTypes.STRING) );
|
||||
registerFunction( "lfill", new StandardSQLFunction("ltrim", StandardBasicTypes.STRING) );
|
||||
registerFunction( "rfill", new StandardSQLFunction("rtrim", StandardBasicTypes.STRING) );
|
||||
registerFunction( "soundex", new StandardSQLFunction("soundex", StandardBasicTypes.STRING) );
|
||||
registerFunction( "upper", new StandardSQLFunction("upper", StandardBasicTypes.STRING) );
|
||||
registerFunction( "ascii", new StandardSQLFunction("ascii", StandardBasicTypes.STRING) );
|
||||
registerFunction( "index", new StandardSQLFunction("index", StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "replace", new StandardSQLFunction( "replace", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "translate", new StandardSQLFunction( "translate", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "lpad", new StandardSQLFunction( "lpad", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "rpad", new StandardSQLFunction( "rpad", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "substr", new StandardSQLFunction( "substr", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "initcap", new StandardSQLFunction( "initcap", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "lower", new StandardSQLFunction( "lower", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "ltrim", new StandardSQLFunction( "ltrim", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "rtrim", new StandardSQLFunction( "rtrim", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "lfill", new StandardSQLFunction( "ltrim", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "rfill", new StandardSQLFunction( "rtrim", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "soundex", new StandardSQLFunction( "soundex", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "upper", new StandardSQLFunction( "upper", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "ascii", new StandardSQLFunction( "ascii", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "index", new StandardSQLFunction( "index", StandardBasicTypes.INTEGER ) );
|
||||
|
||||
registerFunction( "value", new StandardSQLFunction( "value" ) );
|
||||
|
||||
registerFunction( "concat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "(", "||", ")" ) );
|
||||
registerFunction( "substring", new StandardSQLFunction( "substr", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "locate", new StandardSQLFunction("index", StandardBasicTypes.INTEGER) );
|
||||
registerFunction( "locate", new StandardSQLFunction( "index", StandardBasicTypes.INTEGER ) );
|
||||
registerFunction( "coalesce", new StandardSQLFunction( "value" ) );
|
||||
|
||||
getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);
|
||||
getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dropConstraints() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
return "add";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddForeignKeyConstraintString(
|
||||
String constraintName,
|
||||
String[] foreignKey,
|
||||
String referencedTable,
|
||||
String[] primaryKey, boolean referencesPrimaryKey
|
||||
) {
|
||||
StringBuilder res = new StringBuilder(30)
|
||||
.append(" foreign key ")
|
||||
.append(constraintName)
|
||||
.append(" (")
|
||||
.append( StringHelper.join( ", ", foreignKey ) )
|
||||
.append(") references ")
|
||||
.append(referencedTable);
|
||||
String[] primaryKey,
|
||||
boolean referencesPrimaryKey) {
|
||||
final StringBuilder res = new StringBuilder( 30 )
|
||||
.append( " foreign key " )
|
||||
.append( constraintName )
|
||||
.append( " (" )
|
||||
.append( StringHelper.join( ", ", foreignKey ) )
|
||||
.append( ") references " )
|
||||
.append( referencedTable );
|
||||
|
||||
if(!referencesPrimaryKey) {
|
||||
res.append(" (")
|
||||
.append( StringHelper.join(", ", primaryKey) )
|
||||
.append(')');
|
||||
if ( !referencesPrimaryKey ) {
|
||||
res.append( " (" )
|
||||
.append( StringHelper.join( ", ", primaryKey ) )
|
||||
.append( ')' );
|
||||
}
|
||||
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddPrimaryKeyConstraintString(String constraintName) {
|
||||
return " primary key ";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNullColumnString() {
|
||||
return " null";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSequenceNextValString(String sequenceName) {
|
||||
return "select " + getSelectSequenceNextValString( sequenceName ) + " from dual";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectSequenceNextValString(String sequenceName) {
|
||||
return sequenceName + ".nextval";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateSequenceString(String sequenceName) {
|
||||
return "create sequence " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDropSequenceString(String sequenceName) {
|
||||
return "drop sequence " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQuerySequencesString() {
|
||||
return "select sequence_name from domain.sequences";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CaseFragment createCaseFragment() {
|
||||
return new DecodeCaseFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTemporaryTables() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateTemporaryTablePostfix() {
|
||||
return "ignore rollback";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateTemporaryTableName(String baseTableName) {
|
||||
return "temp." + super.generateTemporaryTableName(baseTableName);
|
||||
return "temp." + super.generateTemporaryTableName( baseTableName );
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -45,9 +45,13 @@
|
||||
* @author Yoryos Valotasios
|
||||
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class SQLServer2005Dialect extends SQLServerDialect {
|
||||
private static final int MAX_LENGTH = 8000;
|
||||
|
||||
/**
|
||||
* Constructs a SQLServer2005Dialect
|
||||
*/
|
||||
public SQLServer2005Dialect() {
|
||||
// HHH-3965 fix
|
||||
// As per http://www.sql-server-helper.com/faq/sql-server-2005-varchar-max-p01.aspx
|
||||
@ -74,23 +78,25 @@ public LimitHandler buildLimitHandler(String sql, RowSelection selection) {
|
||||
return new SQLServer2005LimitHandler( sql, selection );
|
||||
}
|
||||
|
||||
@Override // since SQLServer2005 the nowait hint is supported
|
||||
@Override
|
||||
public String appendLockHint(LockOptions lockOptions, String tableName) {
|
||||
// NOTE : since SQLServer2005 the nowait hint is supported
|
||||
if ( lockOptions.getLockMode() == LockMode.UPGRADE_NOWAIT ) {
|
||||
return tableName + " with (updlock, rowlock, nowait)";
|
||||
}
|
||||
LockMode mode = lockOptions.getLockMode();
|
||||
boolean isNoWait = lockOptions.getTimeOut() == LockOptions.NO_WAIT;
|
||||
String noWaitStr = isNoWait? ", nowait" :"";
|
||||
|
||||
final LockMode mode = lockOptions.getLockMode();
|
||||
final boolean isNoWait = lockOptions.getTimeOut() == LockOptions.NO_WAIT;
|
||||
final String noWaitStr = isNoWait ? ", nowait" : "";
|
||||
switch ( mode ) {
|
||||
case UPGRADE_NOWAIT:
|
||||
return tableName + " with (updlock, rowlock, nowait)";
|
||||
return tableName + " with (updlock, rowlock, nowait)";
|
||||
case UPGRADE:
|
||||
case PESSIMISTIC_WRITE:
|
||||
case WRITE:
|
||||
return tableName + " with (updlock, rowlock"+noWaitStr+" )";
|
||||
return tableName + " with (updlock, rowlock" + noWaitStr + " )";
|
||||
case PESSIMISTIC_READ:
|
||||
return tableName + " with (holdlock, rowlock"+noWaitStr+" )";
|
||||
return tableName + " with (holdlock, rowlock" + noWaitStr + " )";
|
||||
default:
|
||||
return tableName;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.dialect.function.NoArgSQLFunction;
|
||||
@ -33,6 +34,9 @@
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class SQLServer2008Dialect extends SQLServer2005Dialect {
|
||||
/**
|
||||
* Constructs a SQLServer2008Dialect
|
||||
*/
|
||||
public SQLServer2008Dialect() {
|
||||
registerColumnType( Types.DATE, "date" );
|
||||
registerColumnType( Types.TIME, "time" );
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
@ -38,10 +39,13 @@
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class SQLServerDialect extends AbstractTransactSQLDialect {
|
||||
|
||||
private static final int PARAM_LIST_SIZE_LIMIT = 2100;
|
||||
|
||||
/**
|
||||
* Constructs a SQLServerDialect
|
||||
*/
|
||||
public SQLServerDialect() {
|
||||
registerColumnType( Types.VARBINARY, "image" );
|
||||
registerColumnType( Types.VARBINARY, 8000, "varbinary($l)" );
|
||||
@ -64,18 +68,18 @@ public SQLServerDialect() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNoColumnsInsertString() {
|
||||
public String getNoColumnsInsertString() {
|
||||
return "default values";
|
||||
}
|
||||
|
||||
static int getAfterSelectInsertPoint(String sql) {
|
||||
int selectIndex = sql.toLowerCase().indexOf( "select" );
|
||||
final int selectIndex = sql.toLowerCase().indexOf( "select" );
|
||||
final int selectDistinctIndex = sql.toLowerCase().indexOf( "select distinct" );
|
||||
return selectIndex + ( selectDistinctIndex == selectIndex ? 15 : 6 );
|
||||
return selectIndex + (selectDistinctIndex == selectIndex ? 15 : 6);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLimitString(String querySelect, int offset, int limit) {
|
||||
public String getLimitString(String querySelect, int offset, int limit) {
|
||||
if ( offset > 0 ) {
|
||||
throw new UnsupportedOperationException( "query result offset is not supported" );
|
||||
}
|
||||
@ -87,45 +91,47 @@ public String getLimitString(String querySelect, int offset, int limit) {
|
||||
|
||||
/**
|
||||
* Use <tt>insert table(...) values(...) select SCOPE_IDENTITY()</tt>
|
||||
* <p/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String appendIdentitySelectToInsert(String insertSQL) {
|
||||
public String appendIdentitySelectToInsert(String insertSQL) {
|
||||
return insertSQL + " select scope_identity()";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLimit() {
|
||||
public boolean supportsLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useMaxForLimit() {
|
||||
public boolean useMaxForLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLimitOffset() {
|
||||
public boolean supportsLimitOffset() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsVariableLimit() {
|
||||
public boolean supportsVariableLimit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char closeQuote() {
|
||||
public char closeQuote() {
|
||||
return ']';
|
||||
}
|
||||
|
||||
@Override
|
||||
public char openQuote() {
|
||||
public char openQuote() {
|
||||
return '[';
|
||||
}
|
||||
|
||||
@Override
|
||||
public String appendLockHint(LockOptions lockOptions, String tableName) {
|
||||
LockMode mode = lockOptions.getLockMode();
|
||||
public String appendLockHint(LockOptions lockOptions, String tableName) {
|
||||
final LockMode mode = lockOptions.getLockMode();
|
||||
switch ( mode ) {
|
||||
case UPGRADE:
|
||||
case UPGRADE_NOWAIT:
|
||||
@ -134,34 +140,39 @@ public String appendLockHint(LockOptions lockOptions, String tableName) {
|
||||
return tableName + " with (updlock, rowlock)";
|
||||
case PESSIMISTIC_READ:
|
||||
return tableName + " with (holdlock, rowlock)";
|
||||
case UPGRADE_SKIPLOCKED:
|
||||
return tableName + " with (updlock, rowlock, readpast)";
|
||||
case UPGRADE_SKIPLOCKED:
|
||||
return tableName + " with (updlock, rowlock, readpast)";
|
||||
default:
|
||||
return tableName;
|
||||
}
|
||||
}
|
||||
|
||||
// The current_timestamp is more accurate, but only known to be supported
|
||||
// in SQL Server 7.0 and later (i.e., Sybase not known to support it at all)
|
||||
|
||||
/**
|
||||
* The current_timestamp is more accurate, but only known to be supported in SQL Server 7.0 and later and
|
||||
* Sybase not known to support it at all
|
||||
* <p/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getCurrentTimestampSelectString() {
|
||||
public String getCurrentTimestampSelectString() {
|
||||
return "select current_timestamp";
|
||||
}
|
||||
|
||||
// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public boolean areStringComparisonsCaseInsensitive() {
|
||||
public boolean areStringComparisonsCaseInsensitive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() {
|
||||
public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCircularCascadeDeleteConstraints() {
|
||||
public boolean supportsCircularCascadeDeleteConstraints() {
|
||||
// SQL Server (at least up through 2005) does not support defining
|
||||
// cascade delete constraints which can circle back to the mutating
|
||||
// table
|
||||
@ -169,34 +180,30 @@ public boolean supportsCircularCascadeDeleteConstraints() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLobValueChangePropogation() {
|
||||
public boolean supportsLobValueChangePropogation() {
|
||||
// note: at least my local SQL Server 2005 Express shows this not working...
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesReadCommittedCauseWritersToBlockReaders() {
|
||||
return false; // here assume SQLServer2005 using snapshot isolation, which does not have this problem
|
||||
public boolean doesReadCommittedCauseWritersToBlockReaders() {
|
||||
// here assume SQLServer2005 using snapshot isolation, which does not have this problem
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesRepeatableReadCauseReadersToBlockWriters() {
|
||||
return false; // here assume SQLServer2005 using snapshot isolation, which does not have this problem
|
||||
public boolean doesRepeatableReadCauseReadersToBlockWriters() {
|
||||
// here assume SQLServer2005 using snapshot isolation, which does not have this problem
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see org.hibernate.dialect.Dialect#getSqlTypeDescriptorOverride(int)
|
||||
*/
|
||||
@Override
|
||||
protected SqlTypeDescriptor getSqlTypeDescriptorOverride( int sqlCode ) {
|
||||
return sqlCode == Types.TINYINT ? SmallIntTypeDescriptor.INSTANCE : super.getSqlTypeDescriptorOverride(sqlCode);
|
||||
}
|
||||
@Override
|
||||
protected SqlTypeDescriptor getSqlTypeDescriptorOverride(int sqlCode) {
|
||||
return sqlCode == Types.TINYINT ?
|
||||
SmallIntTypeDescriptor.INSTANCE :
|
||||
super.getSqlTypeDescriptorOverride( sqlCode );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.hibernate.dialect.Dialect#getInExpressionCountLimit()
|
||||
*/
|
||||
@Override
|
||||
public int getInExpressionCountLimit() {
|
||||
return PARAM_LIST_SIZE_LIMIT;
|
||||
|
@ -22,22 +22,29 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import org.hibernate.sql.JoinFragment;
|
||||
import org.hibernate.sql.Sybase11JoinFragment;
|
||||
|
||||
/**
|
||||
* A SQL dialect suitable for use with Sybase 11.9.2 (specifically: avoids ANSI JOIN syntax)
|
||||
*
|
||||
* @author Colm O' Flaherty
|
||||
*/
|
||||
public class Sybase11Dialect extends SybaseDialect {
|
||||
/**
|
||||
* Constructs a Sybase11Dialect
|
||||
*/
|
||||
public Sybase11Dialect() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JoinFragment createOuterJoinFragment() {
|
||||
return new Sybase11JoinFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCrossJoinSeparator() {
|
||||
return ", ";
|
||||
}
|
||||
|
@ -27,16 +27,11 @@
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.QueryTimeoutException;
|
||||
import org.hibernate.dialect.function.SQLFunctionTemplate;
|
||||
import org.hibernate.exception.ConstraintViolationException;
|
||||
import org.hibernate.exception.LockAcquisitionException;
|
||||
import org.hibernate.exception.LockTimeoutException;
|
||||
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
||||
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
|
||||
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
|
||||
import org.hibernate.internal.util.JdbcExceptionHelper;
|
||||
import org.hibernate.sql.ForUpdateFragment;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
@ -49,6 +44,9 @@
|
||||
*/
|
||||
public class SybaseASE157Dialect extends SybaseASE15Dialect {
|
||||
|
||||
/**
|
||||
* Constructs a SybaseASE157Dialect
|
||||
*/
|
||||
public SybaseASE157Dialect() {
|
||||
super();
|
||||
|
||||
@ -60,40 +58,43 @@ public SybaseASE157Dialect() {
|
||||
registerFunction( "charindex", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "charindex(?1, ?2, ?3)" ) );
|
||||
}
|
||||
|
||||
//HHH-7298 I don't know if this would break something or cause some side affects
|
||||
//but it is required to use 'select for update'
|
||||
@Override
|
||||
public String getTableTypeString() {
|
||||
//HHH-7298 I don't know if this would break something or cause some side affects
|
||||
//but it is required to use 'select for update'
|
||||
return " lock datarows";
|
||||
}
|
||||
|
||||
// support Lob Locator
|
||||
@Override
|
||||
public boolean supportsExpectedLobUsagePattern() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLobValueChangePropogation() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// support 'select ... for update [of columns]'
|
||||
@Override
|
||||
public boolean forUpdateOfColumns() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForUpdateString() {
|
||||
return " for update";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForUpdateString(String aliases) {
|
||||
return getForUpdateString() + " of " + aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String appendLockHint(LockOptions mode, String tableName) {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String applyLocksToSql(String sql, LockOptions aliasedLockOptions, Map keyColumnNames) {
|
||||
return sql + new ForUpdateFragment( this, aliasedLockOptions, keyColumnNames ).toFragmentString();
|
||||
@ -118,6 +119,4 @@ public JDBCException convert(SQLException sqlException, String message, String s
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -41,6 +41,9 @@
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class SybaseASE15Dialect extends SybaseDialect {
|
||||
/**
|
||||
* Constructs a SybaseASE15Dialect
|
||||
*/
|
||||
public SybaseASE15Dialect() {
|
||||
super();
|
||||
|
||||
@ -50,8 +53,8 @@ public SybaseASE15Dialect() {
|
||||
registerColumnType( Types.DATE, "date" );
|
||||
registerColumnType( Types.DECIMAL, "numeric($p,$s)" );
|
||||
registerColumnType( Types.TIME, "time" );
|
||||
registerColumnType( Types.REAL, "real" );
|
||||
registerColumnType( Types.BOOLEAN, "tinyint" );
|
||||
registerColumnType( Types.REAL, "real" );
|
||||
registerColumnType( Types.BOOLEAN, "tinyint" );
|
||||
|
||||
registerFunction( "second", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "datepart(second, ?1)" ) );
|
||||
registerFunction( "minute", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "datepart(minute, ?1)" ) );
|
||||
@ -164,7 +167,7 @@ public SybaseASE15Dialect() {
|
||||
registerFunction( "variance", new SQLFunctionTemplate( StandardBasicTypes.DOUBLE, "variance" ) );
|
||||
registerFunction( "var_pop", new SQLFunctionTemplate( StandardBasicTypes.DOUBLE, "var_pop" ) );
|
||||
registerFunction( "var_samp", new SQLFunctionTemplate( StandardBasicTypes.DOUBLE, "var_samp" ) );
|
||||
registerFunction( "sysdate", new NoArgSQLFunction("getdate", StandardBasicTypes.TIMESTAMP) );
|
||||
registerFunction( "sysdate", new NoArgSQLFunction("getdate", StandardBasicTypes.TIMESTAMP) );
|
||||
|
||||
registerSybaseKeywords();
|
||||
}
|
||||
@ -391,10 +394,12 @@ private void registerSybaseKeywords() {
|
||||
|
||||
// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public boolean supportsCascadeDelete() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxAliasLength() {
|
||||
return 30;
|
||||
}
|
||||
@ -404,11 +409,15 @@ public int getMaxAliasLength() {
|
||||
* <p/>
|
||||
* If the DB is configured to be case-sensitive, then this return
|
||||
* value will be incorrect.
|
||||
* <p/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean areStringComparisonsCaseInsensitive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentTimestampSQLFunctionName() {
|
||||
return "getdate()";
|
||||
}
|
||||
@ -417,19 +426,23 @@ public String getCurrentTimestampSQLFunctionName() {
|
||||
* Actually Sybase does not support LOB locators at al.
|
||||
*
|
||||
* @return false.
|
||||
* <p/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsExpectedLobUsagePattern() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCrossJoinSeparator() {
|
||||
return ", ";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SqlTypeDescriptor getSqlTypeDescriptorOverride(int sqlCode) {
|
||||
return sqlCode == Types.BOOLEAN ? TinyIntTypeDescriptor.INSTANCE : super.getSqlTypeDescriptorOverride( sqlCode );
|
||||
}
|
||||
@Override
|
||||
protected SqlTypeDescriptor getSqlTypeDescriptorOverride(int sqlCode) {
|
||||
return sqlCode == Types.BOOLEAN ? TinyIntTypeDescriptor.INSTANCE : super.getSqlTypeDescriptorOverride( sqlCode );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLockTimeouts() {
|
||||
|
@ -28,13 +28,15 @@
|
||||
* SQL Dialect for Sybase Anywhere
|
||||
* extending Sybase (Enterprise) Dialect
|
||||
* (Tested on ASA 8.x)
|
||||
* @author ?
|
||||
*/
|
||||
public class SybaseAnywhereDialect extends SybaseDialect {
|
||||
/**
|
||||
* Sybase Anywhere syntax would require a "DEFAULT" for each column specified,
|
||||
* but I suppose Hibernate use this syntax only with tables with just 1 column
|
||||
* <p/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getNoColumnsInsertString() {
|
||||
return "values (default)";
|
||||
}
|
||||
@ -44,13 +46,17 @@ public String getNoColumnsInsertString() {
|
||||
* <p/>
|
||||
* NOTE : Also, the DROP statement syntax used by Hibernate to drop constraints is
|
||||
* not compatible with ASA.
|
||||
* <p/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean dropConstraints() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsInsertSelectIdentity() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -36,12 +36,8 @@
|
||||
* @author Brett Meyer
|
||||
*/
|
||||
public class SybaseDialect extends AbstractTransactSQLDialect {
|
||||
|
||||
private static final int PARAM_LIST_SIZE_LIMIT = 250000;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.hibernate.dialect.Dialect#getInExpressionCountLimit()
|
||||
*/
|
||||
@Override
|
||||
public int getInExpressionCountLimit() {
|
||||
return PARAM_LIST_SIZE_LIMIT;
|
||||
|
@ -37,7 +37,6 @@
|
||||
* @author Jay Nance
|
||||
*/
|
||||
public class TeradataDialect extends Dialect {
|
||||
|
||||
private static final int PARAM_LIST_SIZE_LIMIT = 1024;
|
||||
|
||||
/**
|
||||
@ -63,7 +62,8 @@ public TeradataDialect() {
|
||||
registerColumnType( Types.DATE, "DATE" );
|
||||
registerColumnType( Types.TIME, "TIME" );
|
||||
registerColumnType( Types.TIMESTAMP, "TIMESTAMP" );
|
||||
registerColumnType( Types.BOOLEAN, "BYTEINT" ); // hibernate seems to ignore this type...
|
||||
// hibernate seems to ignore this type...
|
||||
registerColumnType( Types.BOOLEAN, "BYTEINT" );
|
||||
registerColumnType( Types.BLOB, "BLOB" );
|
||||
registerColumnType( Types.CLOB, "CLOB" );
|
||||
|
||||
@ -113,87 +113,87 @@ public TeradataDialect() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this dialect support the <tt>FOR UPDATE</tt> syntax?
|
||||
*
|
||||
* @return empty string ... Teradata does not support <tt>FOR UPDATE<tt> syntax
|
||||
* Teradata does not support <tt>FOR UPDATE</tt> syntax
|
||||
* <p/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getForUpdateString() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsIdentityColumns() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSequences() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
return "Add Column";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTemporaryTables() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateTemporaryTableString() {
|
||||
return "create global temporary table";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateTemporaryTablePostfix() {
|
||||
return " on commit preserve rows";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean performTemporaryTableDDLInIsolation() {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dropTemporaryTableAfterUse() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the database type associated with the given
|
||||
* <tt>java.sql.Types</tt> typecode.
|
||||
*
|
||||
* @param code <tt>java.sql.Types</tt> typecode
|
||||
* @param length the length or precision of the column
|
||||
* @param precision the precision of the column
|
||||
* @param scale the scale of the column
|
||||
*
|
||||
* @return the database type name
|
||||
*
|
||||
* @throws HibernateException
|
||||
*/
|
||||
public String getTypeName(int code, int length, int precision, int scale) throws HibernateException {
|
||||
/*
|
||||
* We might want a special case for 19,2. This is very common for money types
|
||||
* and here it is converted to 18,1
|
||||
*/
|
||||
float f = precision > 0 ? ( float ) scale / ( float ) precision : 0;
|
||||
int p = ( precision > 18 ? 18 : precision );
|
||||
int s = ( precision > 18 ? ( int ) ( 18.0 * f ) : ( scale > 18 ? 18 : scale ) );
|
||||
@Override
|
||||
public String getTypeName(int code, long length, int precision, int scale) throws HibernateException {
|
||||
// We might want a special case for 19,2. This is very common for money types
|
||||
// and here it is converted to 18,1
|
||||
final float f = precision > 0 ? (float) scale / (float) precision : 0;
|
||||
final int p = ( precision > 18 ? 18 : precision );
|
||||
final int s = ( precision > 18 ? (int) ( 18.0 * f ) : ( scale > 18 ? 18 : scale ) );
|
||||
|
||||
return super.getTypeName( code, length, p, s );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCascadeDelete() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCircularCascadeDeleteConstraints() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areStringComparisonsCaseInsensitive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsEmptyInList() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectClauseNullString(int sqlType) {
|
||||
String v = "null";
|
||||
|
||||
@ -235,35 +235,39 @@ public String getSelectClauseNullString(int sqlType) {
|
||||
case Types.DATALINK:
|
||||
case Types.BOOLEAN:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateMultisetTableString() {
|
||||
return "create multiset table ";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLobValueChangePropogation() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesReadCommittedCauseWritersToBlockReaders() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesRepeatableReadCauseReadersToBlockWriters() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsBindAsCallableArgument() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.hibernate.dialect.Dialect#getInExpressionCountLimit()
|
||||
*/
|
||||
@Override
|
||||
public int getInExpressionCountLimit() {
|
||||
return PARAM_LIST_SIZE_LIMIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,21 +44,24 @@
|
||||
|
||||
/**
|
||||
* A SQL dialect for TimesTen 5.1.
|
||||
*
|
||||
* <p/>
|
||||
* 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
|
||||
* - 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 and Max Andersen
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class TimesTenDialect extends Dialect {
|
||||
|
||||
/**
|
||||
* Constructs a TimesTenDialect
|
||||
*/
|
||||
public TimesTenDialect() {
|
||||
super();
|
||||
registerColumnType( Types.BIT, "TINYINT" );
|
||||
@ -77,101 +80,115 @@ public TimesTenDialect() {
|
||||
registerColumnType( Types.NUMERIC, "DECIMAL($p, $s)" );
|
||||
// TimesTen has no BLOB/CLOB support, but these types may be suitable
|
||||
// for some applications. The length is limited to 4 million bytes.
|
||||
registerColumnType( Types.BLOB, "VARBINARY(4000000)" );
|
||||
registerColumnType( Types.CLOB, "VARCHAR(4000000)" );
|
||||
|
||||
getDefaultProperties().setProperty(Environment.USE_STREAMS_FOR_BINARY, "true");
|
||||
getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);
|
||||
registerFunction( "lower", new StandardSQLFunction("lower") );
|
||||
registerFunction( "upper", new StandardSQLFunction("upper") );
|
||||
registerFunction( "rtrim", new StandardSQLFunction("rtrim") );
|
||||
registerFunction( "concat", new StandardSQLFunction("concat", StandardBasicTypes.STRING) );
|
||||
registerFunction( "mod", new StandardSQLFunction("mod") );
|
||||
registerFunction( "to_char", new StandardSQLFunction("to_char",StandardBasicTypes.STRING) );
|
||||
registerFunction( "to_date", new StandardSQLFunction("to_date",StandardBasicTypes.TIMESTAMP) );
|
||||
registerFunction( "sysdate", new NoArgSQLFunction("sysdate", StandardBasicTypes.TIMESTAMP, false) );
|
||||
registerFunction( "getdate", new NoArgSQLFunction("getdate", StandardBasicTypes.TIMESTAMP, false) );
|
||||
registerFunction( "nvl", new StandardSQLFunction("nvl") );
|
||||
registerColumnType( Types.BLOB, "VARBINARY(4000000)" );
|
||||
registerColumnType( Types.CLOB, "VARCHAR(4000000)" );
|
||||
|
||||
getDefaultProperties().setProperty( Environment.USE_STREAMS_FOR_BINARY, "true" );
|
||||
getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
|
||||
registerFunction( "lower", new StandardSQLFunction( "lower" ) );
|
||||
registerFunction( "upper", new StandardSQLFunction( "upper" ) );
|
||||
registerFunction( "rtrim", new StandardSQLFunction( "rtrim" ) );
|
||||
registerFunction( "concat", new StandardSQLFunction( "concat", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "mod", new StandardSQLFunction( "mod" ) );
|
||||
registerFunction( "to_char", new StandardSQLFunction( "to_char", StandardBasicTypes.STRING ) );
|
||||
registerFunction( "to_date", new StandardSQLFunction( "to_date", StandardBasicTypes.TIMESTAMP ) );
|
||||
registerFunction( "sysdate", new NoArgSQLFunction( "sysdate", StandardBasicTypes.TIMESTAMP, false ) );
|
||||
registerFunction( "getdate", new NoArgSQLFunction( "getdate", StandardBasicTypes.TIMESTAMP, false ) );
|
||||
registerFunction( "nvl", new StandardSQLFunction( "nvl" ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean dropConstraints() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean qualifyIndexName() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getAddColumnString() {
|
||||
return "add";
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean qualifyIndexName() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
return "add";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSequences() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectSequenceNextValString(String sequenceName) {
|
||||
return sequenceName + ".nextval";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSequenceNextValString(String sequenceName) {
|
||||
return "select first 1 " + sequenceName + ".nextval from sys.tables";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateSequenceString(String sequenceName) {
|
||||
return "create sequence " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDropSequenceString(String sequenceName) {
|
||||
return "drop sequence " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQuerySequencesString() {
|
||||
return "select NAME from sys.sequences";
|
||||
}
|
||||
|
||||
@Override
|
||||
public JoinFragment createOuterJoinFragment() {
|
||||
return new OracleJoinFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCrossJoinSeparator() {
|
||||
return ", ";
|
||||
}
|
||||
|
||||
// new methods in dialect3
|
||||
/*public boolean supportsForUpdateNowait() {
|
||||
return false;
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public String getForUpdateString() {
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean supportsColumnCheck() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTableCheck() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean supportsLimitOffset() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsVariableLimit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useMaxForLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLimitString(String querySelect, int offset, int limit) {
|
||||
if ( offset > 0 ) {
|
||||
throw new UnsupportedOperationException( "query result offset is not supported" );
|
||||
@ -182,51 +199,59 @@ public String getLimitString(String querySelect, int offset, int limit) {
|
||||
.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCurrentTimestampSelection() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentTimestampSelectString() {
|
||||
return "select first 1 sysdate from sys.tables";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurrentTimestampSelectStringCallable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTemporaryTables() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateTemporaryTableName(String baseTableName) {
|
||||
String name = super.generateTemporaryTableName(baseTableName);
|
||||
final String name = super.generateTemporaryTableName( baseTableName );
|
||||
return name.length() > 30 ? name.substring( 1, 30 ) : name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateTemporaryTableString() {
|
||||
return "create global temporary table";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateTemporaryTablePostfix() {
|
||||
return "on commit delete rows";
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
|
||||
// TimesTen has no known variation of a "SELECT ... FOR UPDATE" syntax...
|
||||
if ( lockMode==LockMode.PESSIMISTIC_FORCE_INCREMENT) {
|
||||
return new PessimisticForceIncrementLockingStrategy( lockable, lockMode);
|
||||
if ( lockMode == LockMode.PESSIMISTIC_FORCE_INCREMENT ) {
|
||||
return new PessimisticForceIncrementLockingStrategy( lockable, lockMode );
|
||||
}
|
||||
else if ( lockMode==LockMode.PESSIMISTIC_WRITE) {
|
||||
return new PessimisticWriteUpdateLockingStrategy( lockable, lockMode);
|
||||
else if ( lockMode == LockMode.PESSIMISTIC_WRITE ) {
|
||||
return new PessimisticWriteUpdateLockingStrategy( lockable, lockMode );
|
||||
}
|
||||
else if ( lockMode==LockMode.PESSIMISTIC_READ) {
|
||||
return new PessimisticReadUpdateLockingStrategy( lockable, lockMode);
|
||||
else if ( lockMode == LockMode.PESSIMISTIC_READ ) {
|
||||
return new PessimisticReadUpdateLockingStrategy( lockable, lockMode );
|
||||
}
|
||||
else if ( lockMode==LockMode.OPTIMISTIC) {
|
||||
return new OptimisticLockingStrategy( lockable, lockMode);
|
||||
else if ( lockMode == LockMode.OPTIMISTIC ) {
|
||||
return new OptimisticLockingStrategy( lockable, lockMode );
|
||||
}
|
||||
else if ( lockMode==LockMode.OPTIMISTIC_FORCE_INCREMENT) {
|
||||
return new OptimisticForceIncrementLockingStrategy( lockable, lockMode);
|
||||
else if ( lockMode == LockMode.OPTIMISTIC_FORCE_INCREMENT ) {
|
||||
return new OptimisticForceIncrementLockingStrategy( lockable, lockMode );
|
||||
}
|
||||
else if ( lockMode.greaterThan( LockMode.READ ) ) {
|
||||
return new UpdateLockingStrategy( lockable, lockMode );
|
||||
@ -238,6 +263,7 @@ else if ( lockMode.greaterThan( LockMode.READ ) ) {
|
||||
|
||||
// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public boolean supportsEmptyInList() {
|
||||
return false;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
@ -30,100 +31,124 @@
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
|
||||
/**
|
||||
* This class maps a type to names. Associations
|
||||
* may be marked with a capacity. Calling the get()
|
||||
* method with a type and actual size n will return
|
||||
* the associated name with smallest capacity >= n,
|
||||
* This class maps a type to names. Associations may be marked with a capacity. Calling the get()
|
||||
* method with a type and actual size n will return the associated name with smallest capacity >= n,
|
||||
* if available and an unmarked default type otherwise.
|
||||
* Eg, setting
|
||||
* <pre>
|
||||
* names.put(type, "TEXT" );
|
||||
* names.put(type, 255, "VARCHAR($l)" );
|
||||
* names.put(type, 65534, "LONGVARCHAR($l)" );
|
||||
* names.put( type, "TEXT" );
|
||||
* names.put( type, 255, "VARCHAR($l)" );
|
||||
* names.put( type, 65534, "LONGVARCHAR($l)" );
|
||||
* </pre>
|
||||
* will give you back the following:
|
||||
* <pre>
|
||||
* names.get(type) // --> "TEXT" (default)
|
||||
* names.get(type, 100) // --> "VARCHAR(100)" (100 is in [0:255])
|
||||
* names.get(type, 1000) // --> "LONGVARCHAR(1000)" (1000 is in [256:65534])
|
||||
* names.get(type, 100000) // --> "TEXT" (default)
|
||||
* names.get( type ) // --> "TEXT" (default)
|
||||
* names.get( type, 100 ) // --> "VARCHAR(100)" (100 is in [0:255])
|
||||
* names.get( type, 1000 ) // --> "LONGVARCHAR(1000)" (1000 is in [256:65534])
|
||||
* names.get( type, 100000 ) // --> "TEXT" (default)
|
||||
* </pre>
|
||||
* On the other hand, simply putting
|
||||
* <pre>
|
||||
* names.put(type, "VARCHAR($l)" );
|
||||
* names.put( type, "VARCHAR($l)" );
|
||||
* </pre>
|
||||
* would result in
|
||||
* <pre>
|
||||
* names.get(type) // --> "VARCHAR($l)" (will cause trouble)
|
||||
* names.get(type, 100) // --> "VARCHAR(100)"
|
||||
* names.get(type, 10000) // --> "VARCHAR(10000)"
|
||||
* names.get( type ) // --> "VARCHAR($l)" (will cause trouble)
|
||||
* names.get( type, 100 ) // --> "VARCHAR(100)"
|
||||
* names.get( type, 10000 ) // --> "VARCHAR(10000)"
|
||||
* </pre>
|
||||
*
|
||||
* @author Christoph Beck
|
||||
*/
|
||||
public class TypeNames {
|
||||
|
||||
private Map<Integer, Map<Long, String>> weighted = new HashMap<Integer, Map<Long, String>>();
|
||||
/**
|
||||
* Holds default type mappings for a typeCode. This is the non-sized mapping
|
||||
*/
|
||||
private Map<Integer, String> defaults = new HashMap<Integer, String>();
|
||||
|
||||
/**
|
||||
* get default type name for specified type
|
||||
* @param typecode the type key
|
||||
* @return the default type name associated with specified key
|
||||
* Holds the weighted mappings for a typeCode. The nested map is a TreeMap to sort its contents
|
||||
* based on the key (the weighting) to ensure proper iteration ordering during {@link #get(int, long, int, int)}
|
||||
*/
|
||||
public String get(int typecode) throws MappingException {
|
||||
String result = defaults.get( typecode );
|
||||
if (result==null) throw new MappingException("No Dialect mapping for JDBC type: " + typecode);
|
||||
private Map<Integer, Map<Long, String>> weighted = new HashMap<Integer, Map<Long, String>>();
|
||||
|
||||
/**
|
||||
* get default type name for specified type
|
||||
*
|
||||
* @param typeCode the type key
|
||||
*
|
||||
* @return the default type name associated with specified key
|
||||
*
|
||||
* @throws MappingException Indicates that no registrations were made for that typeCode
|
||||
*/
|
||||
public String get(int typeCode) throws MappingException {
|
||||
final String result = defaults.get( typeCode );
|
||||
if ( result == null ) {
|
||||
throw new MappingException( "No Dialect mapping for JDBC type: " + typeCode );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* get type name for specified type and size
|
||||
*
|
||||
* @param typeCode the type key
|
||||
* @param size the SQL length
|
||||
* @param scale the SQL scale
|
||||
* @param precision the SQL precision
|
||||
* @return the associated name with smallest capacity >= size,
|
||||
* if available and the default type name otherwise
|
||||
*
|
||||
* @return the associated name with smallest capacity >= size, if available and the default type name otherwise
|
||||
*
|
||||
* @throws MappingException Indicates that no registrations were made for that typeCode
|
||||
*/
|
||||
public String get(int typeCode, long size, int precision, int scale) throws MappingException {
|
||||
Map<Long, String> map = weighted.get( typeCode );
|
||||
if ( map!=null && map.size()>0 ) {
|
||||
final Map<Long, String> map = weighted.get( typeCode );
|
||||
if ( map != null && map.size() > 0 ) {
|
||||
// iterate entries ordered by capacity to find first fit
|
||||
for (Map.Entry<Long, String> entry: map.entrySet()) {
|
||||
for ( Map.Entry<Long, String> entry: map.entrySet() ) {
|
||||
if ( size <= entry.getKey() ) {
|
||||
return replace( entry.getValue(), size, precision, scale );
|
||||
}
|
||||
}
|
||||
}
|
||||
return replace( get(typeCode), size, precision, scale );
|
||||
|
||||
// if we get here one of 2 things happened:
|
||||
// 1) There was no weighted registration for that typeCode
|
||||
// 2) There was no weighting whose max capacity was big enough to contain size
|
||||
return replace( get( typeCode ), size, precision, scale );
|
||||
}
|
||||
|
||||
|
||||
private static String replace(String type, long size, int precision, int scale) {
|
||||
type = StringHelper.replaceOnce(type, "$s", Integer.toString(scale) );
|
||||
type = StringHelper.replaceOnce(type, "$l", Long.toString(size) );
|
||||
return StringHelper.replaceOnce(type, "$p", Integer.toString(precision) );
|
||||
type = StringHelper.replaceOnce( type, "$s", Integer.toString( scale ) );
|
||||
type = StringHelper.replaceOnce( type, "$l", Long.toString( size ) );
|
||||
return StringHelper.replaceOnce( type, "$p", Integer.toString( precision ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* set a type name for specified type key and capacity
|
||||
* @param typecode the type key
|
||||
* Register a weighted typeCode mapping
|
||||
*
|
||||
* @param typeCode the JDBC type code
|
||||
* @param capacity The capacity for this weighting
|
||||
* @param value The mapping (type name)
|
||||
*/
|
||||
public void put(int typecode, long capacity, String value) {
|
||||
Map<Long, String> map = weighted.get( typecode );
|
||||
if (map == null) {// add new ordered map
|
||||
public void put(int typeCode, long capacity, String value) {
|
||||
Map<Long, String> map = weighted.get( typeCode );
|
||||
if ( map == null ) {
|
||||
// add new ordered map
|
||||
map = new TreeMap<Long, String>();
|
||||
weighted.put( typecode, map );
|
||||
weighted.put( typeCode, map );
|
||||
}
|
||||
map.put(capacity, value);
|
||||
map.put( capacity, value );
|
||||
}
|
||||
|
||||
/**
|
||||
* set a default type name for specified type key
|
||||
* @param typecode the type key
|
||||
* Register a default (non-weighted) typeCode mapping
|
||||
*
|
||||
* @param typeCode the type key
|
||||
* @param value The mapping (type name)
|
||||
*/
|
||||
public void put(int typecode, String value) {
|
||||
defaults.put( typecode, value );
|
||||
public void put(int typeCode, String value) {
|
||||
defaults.put( typeCode, value );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,27 +79,32 @@ public final String render(Type argumentType, List args, SessionFactoryImplement
|
||||
if ( args.size() == 1 ) {
|
||||
// we have the form: trim(trimSource)
|
||||
// so we trim leading and trailing spaces
|
||||
return resolveBothSpaceTrimFunction().render( argumentType, args, factory ); // EARLY EXIT!!!!
|
||||
return resolveBothSpaceTrimFunction().render( argumentType, args, factory );
|
||||
}
|
||||
else if ( "from".equalsIgnoreCase( ( String ) args.get( 0 ) ) ) {
|
||||
else if ( "from".equalsIgnoreCase( (String) args.get( 0 ) ) ) {
|
||||
// we have the form: trim(from trimSource).
|
||||
// This is functionally equivalent to trim(trimSource)
|
||||
return resolveBothSpaceTrimFromFunction().render( argumentType, args, factory ); // EARLY EXIT!!!!
|
||||
return resolveBothSpaceTrimFromFunction().render( argumentType, args, factory );
|
||||
}
|
||||
else {
|
||||
// otherwise, a trim-specification and/or a trim-character
|
||||
// have been specified; we need to decide which options
|
||||
// are present and "do the right thing"
|
||||
boolean leading = true; // should leading trim-characters be trimmed?
|
||||
boolean trailing = true; // should trailing trim-characters be trimmed?
|
||||
String trimCharacter; // the trim-character (what is to be trimmed off?)
|
||||
String trimSource; // the trim-source (from where should it be trimmed?)
|
||||
|
||||
// should leading trim-characters be trimmed?
|
||||
boolean leading = true;
|
||||
// should trailing trim-characters be trimmed?
|
||||
boolean trailing = true;
|
||||
// the trim-character (what is to be trimmed off?)
|
||||
String trimCharacter;
|
||||
// the trim-source (from where should it be trimmed?)
|
||||
String trimSource;
|
||||
|
||||
// potentialTrimCharacterArgIndex = 1 assumes that a
|
||||
// trim-specification has been specified. we handle the
|
||||
// exception to that explicitly
|
||||
int potentialTrimCharacterArgIndex = 1;
|
||||
String firstArg = ( String ) args.get( 0 );
|
||||
final String firstArg = (String) args.get( 0 );
|
||||
if ( "leading".equalsIgnoreCase( firstArg ) ) {
|
||||
trailing = false;
|
||||
}
|
||||
@ -107,15 +112,16 @@ else if ( "trailing".equalsIgnoreCase( firstArg ) ) {
|
||||
leading = false;
|
||||
}
|
||||
else if ( "both".equalsIgnoreCase( firstArg ) ) {
|
||||
// nothing to do here
|
||||
}
|
||||
else {
|
||||
potentialTrimCharacterArgIndex = 0;
|
||||
}
|
||||
|
||||
String potentialTrimCharacter = ( String ) args.get( potentialTrimCharacterArgIndex );
|
||||
final String potentialTrimCharacter = (String) args.get( potentialTrimCharacterArgIndex );
|
||||
if ( "from".equalsIgnoreCase( potentialTrimCharacter ) ) {
|
||||
trimCharacter = "' '";
|
||||
trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
|
||||
trimSource = (String) args.get( potentialTrimCharacterArgIndex + 1 );
|
||||
}
|
||||
else if ( potentialTrimCharacterArgIndex + 1 >= args.size() ) {
|
||||
trimCharacter = "' '";
|
||||
@ -123,15 +129,15 @@ else if ( potentialTrimCharacterArgIndex + 1 >= args.size() ) {
|
||||
}
|
||||
else {
|
||||
trimCharacter = potentialTrimCharacter;
|
||||
if ( "from".equalsIgnoreCase( ( String ) args.get( potentialTrimCharacterArgIndex + 1 ) ) ) {
|
||||
trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 2 );
|
||||
if ( "from".equalsIgnoreCase( (String) args.get( potentialTrimCharacterArgIndex + 1 ) ) ) {
|
||||
trimSource = (String) args.get( potentialTrimCharacterArgIndex + 2 );
|
||||
}
|
||||
else {
|
||||
trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
|
||||
trimSource = (String) args.get( potentialTrimCharacterArgIndex + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
List<String> argsToUse = new ArrayList<String>();
|
||||
final List<String> argsToUse = new ArrayList<String>();
|
||||
argsToUse.add( trimSource );
|
||||
argsToUse.add( trimCharacter );
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.function;
|
||||
package org.hibernate.dialect.function;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
|
||||
/**
|
||||
@ -34,20 +34,51 @@
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class AnsiTrimEmulationFunction extends AbstractAnsiTrimEmulationFunction {
|
||||
/**
|
||||
* The default {@code ltrim} function name
|
||||
*/
|
||||
public static final String LTRIM = "ltrim";
|
||||
|
||||
/**
|
||||
* The default {@code rtrim} function name
|
||||
*/
|
||||
public static final String RTRIM = "rtrim";
|
||||
|
||||
/**
|
||||
* The default {@code replace} function name
|
||||
*/
|
||||
public static final String REPLACE = "replace";
|
||||
|
||||
/**
|
||||
* The placeholder used to represent whitespace
|
||||
*/
|
||||
public static final String SPACE_PLACEHOLDER = "${space}$";
|
||||
|
||||
/**
|
||||
* The SQLFunctionTemplate pattern for the trimming leading spaces
|
||||
*/
|
||||
public static final String LEADING_SPACE_TRIM_TEMPLATE = LTRIM + "(?1)";
|
||||
|
||||
/**
|
||||
* The SQLFunctionTemplate pattern for the trimming trailing spaces
|
||||
*/
|
||||
public static final String TRAILING_SPACE_TRIM_TEMPLATE = RTRIM + "(?1)";
|
||||
|
||||
/**
|
||||
* The SQLFunctionTemplate pattern for the trimming both leading and trailing spaces
|
||||
*/
|
||||
public static final String BOTH_SPACE_TRIM_TEMPLATE = LTRIM + "(" + RTRIM + "(?1))";
|
||||
public static final String BOTH_SPACE_TRIM_FROM_TEMPLATE = LTRIM + "(" + RTRIM + "(?2))"; //skip the FROM keyword in params
|
||||
|
||||
/**
|
||||
* The SQLFunctionTemplate pattern for the trimming both leading and trailing spaces, with the optional FROM keyword.
|
||||
* Different because we need to skip the FROM keyword in the SQLFunctionTemplate processing
|
||||
*/
|
||||
public static final String BOTH_SPACE_TRIM_FROM_TEMPLATE = LTRIM + "(" + RTRIM + "(?2))";
|
||||
|
||||
/**
|
||||
* A template for the series of calls required to trim non-space chars from the beginning of text.
|
||||
* <p/>
|
||||
* NOTE : essentially we:</ol>
|
||||
* NOTE : essentially we:<ol>
|
||||
* <li>replace all space chars with the text '${space}$'</li>
|
||||
* <li>replace all the actual replacement chars with space chars</li>
|
||||
* <li>perform left-trimming (that removes any of the space chars we just added which occur at the beginning of the text)</li>
|
||||
@ -206,6 +237,7 @@ public AnsiTrimEmulationFunction(String ltrimFunctionName, String rtrimFunctionN
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected SQLFunction resolveBothSpaceTrimFunction() {
|
||||
return bothSpaceTrim;
|
||||
}
|
||||
@ -213,6 +245,7 @@ protected SQLFunction resolveBothSpaceTrimFunction() {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected SQLFunction resolveBothSpaceTrimFromFunction() {
|
||||
return bothSpaceTrimFrom;
|
||||
}
|
||||
@ -220,6 +253,7 @@ protected SQLFunction resolveBothSpaceTrimFromFunction() {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected SQLFunction resolveLeadingSpaceTrimFunction() {
|
||||
return leadingSpaceTrim;
|
||||
}
|
||||
@ -227,6 +261,7 @@ protected SQLFunction resolveLeadingSpaceTrimFunction() {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected SQLFunction resolveTrailingSpaceTrimFunction() {
|
||||
return trailingSpaceTrim;
|
||||
}
|
||||
@ -234,6 +269,7 @@ protected SQLFunction resolveTrailingSpaceTrimFunction() {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected SQLFunction resolveBothTrimFunction() {
|
||||
return bothTrim;
|
||||
}
|
||||
@ -241,6 +277,7 @@ protected SQLFunction resolveBothTrimFunction() {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected SQLFunction resolveLeadingTrimFunction() {
|
||||
return leadingTrim;
|
||||
}
|
||||
@ -248,6 +285,7 @@ protected SQLFunction resolveLeadingTrimFunction() {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected SQLFunction resolveTrailingTrimFunction() {
|
||||
return trailingTrim;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.function;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
|
||||
/**
|
||||
@ -31,14 +32,11 @@
|
||||
*/
|
||||
public class AnsiTrimFunction extends TrimFunctionTemplate {
|
||||
protected String render(Options options, String trimSource, SessionFactoryImplementor factory) {
|
||||
return new StringBuilder()
|
||||
.append( "trim(" )
|
||||
.append( options.getTrimSpecification().getName() )
|
||||
.append( ' ' )
|
||||
.append( options.getTrimCharacter() )
|
||||
.append( " from " )
|
||||
.append( trimSource )
|
||||
.append( ')' )
|
||||
.toString();
|
||||
return String.format(
|
||||
"trim(%s %s from %s)",
|
||||
options.getTrimSpecification().getName(),
|
||||
options.getTrimCharacter(),
|
||||
trimSource
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.function;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
/**
|
||||
@ -34,6 +35,11 @@
|
||||
public class AvgWithArgumentCastFunction extends StandardAnsiSqlAggregationFunctions.AvgFunction {
|
||||
private final String castType;
|
||||
|
||||
/**
|
||||
* Constructs a AvgWithArgumentCastFunction
|
||||
*
|
||||
* @param castType The type to cast the avg argument to
|
||||
*/
|
||||
public AvgWithArgumentCastFunction(String castType) {
|
||||
this.castType = castType;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.function;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.QueryException;
|
||||
@ -30,45 +31,43 @@
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* ANSI-SQL style <tt>cast(foo as type)</tt> where the type is
|
||||
* a Hibernate type
|
||||
* ANSI-SQL style {@code cast(foo as type)} where the type is a Hibernate type
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class CastFunction implements SQLFunction {
|
||||
@Override
|
||||
public boolean hasArguments() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasParenthesesIfNoArguments() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
|
||||
return columnType; // this is really just a guess, unless the caller properly identifies the 'type' argument here
|
||||
// this is really just a guess, unless the caller properly identifies the 'type' argument here
|
||||
return columnType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String render(Type columnType, List args, SessionFactoryImplementor factory) throws QueryException {
|
||||
if ( args.size()!=2 ) {
|
||||
throw new QueryException("cast() requires two arguments");
|
||||
}
|
||||
String type = (String) args.get(1);
|
||||
int[] sqlTypeCodes = factory.getTypeResolver().heuristicType(type).sqlTypes(factory);
|
||||
final String type = (String) args.get( 1 );
|
||||
final int[] sqlTypeCodes = factory.getTypeResolver().heuristicType( type ).sqlTypes( factory );
|
||||
if ( sqlTypeCodes.length!=1 ) {
|
||||
throw new QueryException("invalid Hibernate type for cast()");
|
||||
}
|
||||
String sqlType = factory.getDialect().getCastTypeName( sqlTypeCodes[0] );
|
||||
if (sqlType==null) {
|
||||
if ( sqlType == null ) {
|
||||
//TODO: never reached, since getExplicitHibernateTypeName() actually throws an exception!
|
||||
sqlType = type;
|
||||
}
|
||||
/*else {
|
||||
//trim off the length/precision/scale
|
||||
int loc = sqlType.indexOf('(');
|
||||
if (loc>-1) {
|
||||
sqlType = sqlType.substring(0, loc);
|
||||
}
|
||||
}*/
|
||||
return "cast(" + args.get(0) + " as " + sqlType + ')';
|
||||
return "cast(" + args.get( 0 ) + " as " + sqlType + ')';
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -32,33 +32,42 @@
|
||||
|
||||
/**
|
||||
* Emulation of <tt>locate()</tt> on Sybase
|
||||
*
|
||||
* @author Nathan Moon
|
||||
*/
|
||||
public class CharIndexFunction implements SQLFunction {
|
||||
@Override
|
||||
public boolean hasArguments() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasParenthesesIfNoArguments() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
|
||||
return StandardBasicTypes.INTEGER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String render(Type columnType, List args, SessionFactoryImplementor factory) throws QueryException {
|
||||
boolean threeArgs = args.size() > 2;
|
||||
Object pattern = args.get(0);
|
||||
Object string = args.get(1);
|
||||
Object start = threeArgs ? args.get(2) : null;
|
||||
final boolean threeArgs = args.size() > 2;
|
||||
final Object pattern = args.get( 0 );
|
||||
final Object string = args.get( 1 );
|
||||
final Object start = threeArgs ? args.get( 2 ) : null;
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("charindex(").append( pattern ).append(", ");
|
||||
if (threeArgs) buf.append( "right(");
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
buf.append( "charindex(" ).append( pattern ).append( ", " );
|
||||
if (threeArgs) {
|
||||
buf.append( "right(" );
|
||||
}
|
||||
buf.append( string );
|
||||
if (threeArgs) buf.append( ", char_length(" ).append( string ).append(")-(").append( start ).append("-1))");
|
||||
buf.append(')');
|
||||
if (threeArgs) {
|
||||
buf.append( ", char_length(" ).append( string ).append( ")-(" ).append( start ).append( "-1))" );
|
||||
}
|
||||
buf.append( ')' );
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
|
@ -34,13 +34,16 @@
|
||||
* Classic AVG sqlfunction that return types as it was done in Hibernate 3.1
|
||||
*
|
||||
* @author Max Rydahl Andersen
|
||||
*
|
||||
*/
|
||||
public class ClassicAvgFunction extends StandardSQLFunction {
|
||||
/**
|
||||
* Constructs a ClassicAvgFunction
|
||||
*/
|
||||
public ClassicAvgFunction() {
|
||||
super( "avg" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
|
||||
int[] sqlTypes;
|
||||
try {
|
||||
@ -49,8 +52,12 @@ public Type getReturnType(Type columnType, Mapping mapping) throws QueryExceptio
|
||||
catch ( MappingException me ) {
|
||||
throw new QueryException( me );
|
||||
}
|
||||
if ( sqlTypes.length != 1 ) throw new QueryException( "multi-column type in avg()" );
|
||||
int sqlType = sqlTypes[0];
|
||||
|
||||
if ( sqlTypes.length != 1 ) {
|
||||
throw new QueryException( "multi-column type in avg()" );
|
||||
}
|
||||
|
||||
final int sqlType = sqlTypes[0];
|
||||
if ( sqlType == Types.INTEGER || sqlType == Types.BIGINT || sqlType == Types.TINYINT ) {
|
||||
return StandardBasicTypes.FLOAT;
|
||||
}
|
||||
@ -58,4 +65,4 @@ public Type getReturnType(Type columnType, Mapping mapping) throws QueryExceptio
|
||||
return columnType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.function;
|
||||
|
||||
import org.hibernate.engine.spi.Mapping;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.Type;
|
||||
@ -30,14 +31,17 @@
|
||||
* Classic COUNT sqlfunction that return types as it was done in Hibernate 3.1
|
||||
*
|
||||
* @author Max Rydahl Andersen
|
||||
*
|
||||
*/
|
||||
public class ClassicCountFunction extends StandardSQLFunction {
|
||||
/**
|
||||
* Constructs a ClassicCountFunction
|
||||
*/
|
||||
public ClassicCountFunction() {
|
||||
super( "count" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getReturnType(Type columnType, Mapping mapping) {
|
||||
return StandardBasicTypes.INTEGER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,8 +21,7 @@
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.function;
|
||||
|
||||
package org.hibernate.dialect.function;
|
||||
|
||||
/**
|
||||
* Classic SUM sqlfunction that return types as it was done in Hibernate 3.1
|
||||
@ -31,7 +30,10 @@
|
||||
*
|
||||
*/
|
||||
public class ClassicSumFunction extends StandardSQLFunction {
|
||||
/**
|
||||
* Constructs a ClassicSumFunction
|
||||
*/
|
||||
public ClassicSumFunction() {
|
||||
super( "sum" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,28 +34,39 @@
|
||||
* @author Jonathan Levinson
|
||||
*/
|
||||
public class ConditionalParenthesisFunction extends StandardSQLFunction {
|
||||
|
||||
/**
|
||||
* Constructs a ConditionalParenthesisFunction with the given name
|
||||
*
|
||||
* @param name The function name
|
||||
*/
|
||||
public ConditionalParenthesisFunction(String name) {
|
||||
super( name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a ConditionalParenthesisFunction with the given name
|
||||
*
|
||||
* @param name The function name
|
||||
* @param type The function return type
|
||||
*/
|
||||
public ConditionalParenthesisFunction(String name, Type type) {
|
||||
super( name, type );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasParenthesesIfNoArguments() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String render(List args, SessionFactoryImplementor factory) {
|
||||
final boolean hasArgs = !args.isEmpty();
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append( getName() );
|
||||
@Override
|
||||
public String render(Type firstArgumentType, List arguments, SessionFactoryImplementor sessionFactory) {
|
||||
final boolean hasArgs = !arguments.isEmpty();
|
||||
final StringBuilder buf = new StringBuilder( getName() );
|
||||
if ( hasArgs ) {
|
||||
buf.append( "(" );
|
||||
for ( int i = 0; i < args.size(); i++ ) {
|
||||
buf.append( args.get( i ) );
|
||||
if ( i < args.size() - 1 ) {
|
||||
for ( int i = 0; i < arguments.size(); i++ ) {
|
||||
buf.append( arguments.get( i ) );
|
||||
if ( i < arguments.size() - 1 ) {
|
||||
buf.append( ", " );
|
||||
}
|
||||
}
|
||||
|
@ -36,24 +36,28 @@
|
||||
* @author Jonathan Levinson
|
||||
*/
|
||||
public class ConvertFunction implements SQLFunction {
|
||||
|
||||
@Override
|
||||
public boolean hasArguments() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasParenthesesIfNoArguments() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getReturnType(Type firstArgumentType, Mapping mapping) throws QueryException {
|
||||
return StandardBasicTypes.STRING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String render(Type firstArgumentType, List args, SessionFactoryImplementor factory) throws QueryException {
|
||||
if ( args.size() != 2 && args.size() != 3 ) {
|
||||
throw new QueryException( "convert() requires two or three arguments" );
|
||||
}
|
||||
String type = ( String ) args.get( 1 );
|
||||
|
||||
final String type = (String) args.get( 1 );
|
||||
|
||||
if ( args.size() == 2 ) {
|
||||
return "{fn convert(" + args.get( 0 ) + " , " + type + ")}";
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.function;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@ -33,8 +34,8 @@
|
||||
|
||||
/**
|
||||
* A specialized concat() function definition in which:<ol>
|
||||
* <li>we translate to use the concat operator ('||')</li>
|
||||
* <li>wrap dynamic parameters in CASTs to VARCHAR</li>
|
||||
* <li>we translate to use the concat operator ('||')</li>
|
||||
* <li>wrap dynamic parameters in CASTs to VARCHAR</li>
|
||||
* </ol>
|
||||
* <p/>
|
||||
* This last spec is to deal with a limitation on DB2 and variants (e.g. Derby)
|
||||
@ -51,6 +52,7 @@ public class DerbyConcatFunction implements SQLFunction {
|
||||
* <p/>
|
||||
* Here we always return <tt>true</tt>
|
||||
*/
|
||||
@Override
|
||||
public boolean hasArguments() {
|
||||
return true;
|
||||
}
|
||||
@ -60,6 +62,7 @@ public boolean hasArguments() {
|
||||
* <p/>
|
||||
* Here we always return <tt>true</tt>
|
||||
*/
|
||||
@Override
|
||||
public boolean hasParenthesesIfNoArguments() {
|
||||
return true;
|
||||
}
|
||||
@ -69,6 +72,7 @@ public boolean hasParenthesesIfNoArguments() {
|
||||
* <p/>
|
||||
* Here we always return {@link StandardBasicTypes#STRING}.
|
||||
*/
|
||||
@Override
|
||||
public Type getReturnType(Type argumentType, Mapping mapping) throws QueryException {
|
||||
return StandardBasicTypes.STRING;
|
||||
}
|
||||
@ -83,25 +87,23 @@ public Type getReturnType(Type argumentType, Mapping mapping) throws QueryExcept
|
||||
* arg elements in <tt>cast</tt> function calls, use the concatenation operator on the <tt>cast</tt>
|
||||
* returns, and then wrap that whole thing in a call to the Derby <tt>varchar</tt> function.
|
||||
*/
|
||||
@Override
|
||||
public String render(Type argumentType, List args, SessionFactoryImplementor factory) throws QueryException {
|
||||
boolean areAllArgsParams = true;
|
||||
Iterator itr = args.iterator();
|
||||
while ( itr.hasNext() ) {
|
||||
final String arg = ( String ) itr.next();
|
||||
if ( ! "?".equals( arg ) ) {
|
||||
areAllArgsParams = false;
|
||||
// first figure out if all arguments are dynamic (jdbc parameters) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
boolean areAllArgumentsDynamic = true;
|
||||
for ( Object arg1 : args ) {
|
||||
final String arg = (String) arg1;
|
||||
if ( !"?".equals( arg ) ) {
|
||||
// we found a non-dynamic argument
|
||||
areAllArgumentsDynamic = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( areAllArgsParams ) {
|
||||
if ( areAllArgumentsDynamic ) {
|
||||
return join(
|
||||
args.iterator(),
|
||||
new StringTransformer() {
|
||||
public String transform(String string) {
|
||||
return "cast( ? as varchar(32672) )";
|
||||
}
|
||||
},
|
||||
CAST_STRING_TRANSFORMER,
|
||||
new StringJoinTemplate() {
|
||||
public String getBeginning() {
|
||||
return "varchar( ";
|
||||
@ -118,11 +120,7 @@ public String getEnding() {
|
||||
else {
|
||||
return join(
|
||||
args.iterator(),
|
||||
new StringTransformer() {
|
||||
public String transform(String string) {
|
||||
return string;
|
||||
}
|
||||
},
|
||||
NO_TRANSFORM_STRING_TRANSFORMER,
|
||||
new StringJoinTemplate() {
|
||||
public String getBeginning() {
|
||||
return "(";
|
||||
@ -139,9 +137,31 @@ public String getEnding() {
|
||||
}
|
||||
|
||||
private static interface StringTransformer {
|
||||
/**
|
||||
* Transform a string to another
|
||||
*
|
||||
* @param string The String to be transformed
|
||||
*
|
||||
* @return The transformed form
|
||||
*/
|
||||
public String transform(String string);
|
||||
}
|
||||
|
||||
private static final StringTransformer CAST_STRING_TRANSFORMER = new StringTransformer() {
|
||||
@Override
|
||||
public String transform(String string) {
|
||||
// expectation is that incoming string is "?"
|
||||
return "cast( ? as varchar(32672) )";
|
||||
}
|
||||
};
|
||||
|
||||
private static final StringTransformer NO_TRANSFORM_STRING_TRANSFORMER = new StringTransformer() {
|
||||
@Override
|
||||
public String transform(String string) {
|
||||
return string;
|
||||
}
|
||||
};
|
||||
|
||||
private static interface StringJoinTemplate {
|
||||
/**
|
||||
* Getter for property 'beginning'.
|
||||
@ -165,9 +185,9 @@ private static interface StringJoinTemplate {
|
||||
|
||||
private static String join(Iterator/*<String>*/ elements, StringTransformer elementTransformer, StringJoinTemplate template) {
|
||||
// todo : make this available via StringHelper?
|
||||
StringBuilder buffer = new StringBuilder( template.getBeginning() );
|
||||
final StringBuilder buffer = new StringBuilder( template.getBeginning() );
|
||||
while ( elements.hasNext() ) {
|
||||
final String element = ( String ) elements.next();
|
||||
final String element = (String) elements.next();
|
||||
buffer.append( elementTransformer.transform( element ) );
|
||||
if ( elements.hasNext() ) {
|
||||
buffer.append( template.getSeparator() );
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.function;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.QueryException;
|
||||
@ -31,40 +32,57 @@
|
||||
|
||||
/**
|
||||
* A function which takes no arguments
|
||||
*
|
||||
*
|
||||
* @author Michi
|
||||
*/
|
||||
public class NoArgSQLFunction implements SQLFunction {
|
||||
private Type returnType;
|
||||
private boolean hasParenthesesIfNoArguments;
|
||||
private String name;
|
||||
private Type returnType;
|
||||
private boolean hasParenthesesIfNoArguments;
|
||||
private String name;
|
||||
|
||||
public NoArgSQLFunction(String name, Type returnType) {
|
||||
this(name, returnType, true);
|
||||
}
|
||||
/**
|
||||
* Constructs a NoArgSQLFunction
|
||||
*
|
||||
* @param name The function name
|
||||
* @param returnType The function return type
|
||||
*/
|
||||
public NoArgSQLFunction(String name, Type returnType) {
|
||||
this( name, returnType, true );
|
||||
}
|
||||
|
||||
public NoArgSQLFunction(String name, Type returnType, boolean hasParenthesesIfNoArguments) {
|
||||
this.returnType = returnType;
|
||||
this.hasParenthesesIfNoArguments = hasParenthesesIfNoArguments;
|
||||
this.name = name;
|
||||
}
|
||||
/**
|
||||
* Constructs a NoArgSQLFunction
|
||||
*
|
||||
* @param name The function name
|
||||
* @param returnType The function return type
|
||||
* @param hasParenthesesIfNoArguments Does the function call need parenthesis if there are no arguments?
|
||||
*/
|
||||
public NoArgSQLFunction(String name, Type returnType, boolean hasParenthesesIfNoArguments) {
|
||||
this.returnType = returnType;
|
||||
this.hasParenthesesIfNoArguments = hasParenthesesIfNoArguments;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasArguments() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasParenthesesIfNoArguments() {
|
||||
return hasParenthesesIfNoArguments;
|
||||
}
|
||||
|
||||
public Type getReturnType(Type argumentType, Mapping mapping) throws QueryException {
|
||||
return returnType;
|
||||
}
|
||||
@Override
|
||||
public Type getReturnType(Type argumentType, Mapping mapping) throws QueryException {
|
||||
return returnType;
|
||||
}
|
||||
|
||||
public String render(Type argumentType, List args, SessionFactoryImplementor factory) throws QueryException {
|
||||
if ( args.size()>0 ) {
|
||||
throw new QueryException("function takes no arguments: " + name);
|
||||
}
|
||||
return hasParenthesesIfNoArguments ? name + "()" : name;
|
||||
}
|
||||
@Override
|
||||
public String render(Type argumentType, List args, SessionFactoryImplementor factory) throws QueryException {
|
||||
if ( args.size() > 0 ) {
|
||||
throw new QueryException( "function takes no arguments: " + name );
|
||||
}
|
||||
return hasParenthesesIfNoArguments ? name + "()" : name;
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.function;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.QueryException;
|
||||
@ -35,30 +36,32 @@
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class NvlFunction implements SQLFunction {
|
||||
@Override
|
||||
public boolean hasArguments() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasParenthesesIfNoArguments() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getReturnType(Type argumentType, Mapping mapping) throws QueryException {
|
||||
return argumentType;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public String render(Type argumentType, List args, SessionFactoryImplementor factory) throws QueryException {
|
||||
int lastIndex = args.size()-1;
|
||||
Object last = args.remove(lastIndex);
|
||||
final int lastIndex = args.size()-1;
|
||||
final Object last = args.remove( lastIndex );
|
||||
if ( lastIndex==0 ) {
|
||||
return last.toString();
|
||||
}
|
||||
Object secondLast = args.get(lastIndex-1);
|
||||
String nvl = "nvl(" + secondLast + ", " + last + ")";
|
||||
args.set(lastIndex-1, nvl);
|
||||
final Object secondLast = args.get( lastIndex-1 );
|
||||
final String nvl = "nvl(" + secondLast + ", " + last + ")";
|
||||
args.set( lastIndex-1, nvl );
|
||||
return render( argumentType, args, factory );
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -32,35 +32,48 @@
|
||||
|
||||
/**
|
||||
* Emulation of <tt>locate()</tt> on PostgreSQL
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class PositionSubstringFunction implements SQLFunction {
|
||||
@Override
|
||||
public boolean hasArguments() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasParenthesesIfNoArguments() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getReturnType(Type firstArgumentType, Mapping mapping) throws QueryException {
|
||||
return StandardBasicTypes.INTEGER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String render(Type firstArgumentType, List args, SessionFactoryImplementor factory) throws QueryException {
|
||||
boolean threeArgs = args.size() > 2;
|
||||
Object pattern = args.get(0);
|
||||
Object string = args.get(1);
|
||||
Object start = threeArgs ? args.get(2) : null;
|
||||
final boolean threeArgs = args.size() > 2;
|
||||
final Object pattern = args.get( 0 );
|
||||
final Object string = args.get( 1 );
|
||||
final Object start = threeArgs ? args.get( 2 ) : null;
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
if (threeArgs) buf.append('(');
|
||||
buf.append("position(").append( pattern ).append(" in ");
|
||||
if (threeArgs) buf.append( "substring(");
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
if (threeArgs) {
|
||||
buf.append( '(' );
|
||||
}
|
||||
buf.append( "position(" ).append( pattern ).append( " in " );
|
||||
if (threeArgs) {
|
||||
buf.append( "substring(");
|
||||
}
|
||||
buf.append( string );
|
||||
if (threeArgs) buf.append( ", " ).append( start ).append(')');
|
||||
buf.append(')');
|
||||
if (threeArgs) buf.append('+').append( start ).append("-1)");
|
||||
if (threeArgs) {
|
||||
buf.append( ", " ).append( start ).append( ')' );
|
||||
}
|
||||
buf.append( ')' );
|
||||
if (threeArgs) {
|
||||
buf.append( '+' ).append( start ).append( "-1)" );
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.function;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.QueryException;
|
||||
@ -70,7 +71,6 @@ public interface SQLFunction {
|
||||
*/
|
||||
public Type getReturnType(Type firstArgumentType, Mapping mapping) throws QueryException;
|
||||
|
||||
|
||||
/**
|
||||
* Render the function call as SQL fragment.
|
||||
* <p/>
|
||||
|
@ -28,25 +28,51 @@
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
|
||||
/**
|
||||
* Defines a registry for SQLFunction instances
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SQLFunctionRegistry {
|
||||
private final Dialect dialect;
|
||||
private final Map<String, SQLFunction> userFunctions;
|
||||
|
||||
/**
|
||||
* Constructs a SQLFunctionRegistry
|
||||
*
|
||||
* @param dialect The dialect
|
||||
* @param userFunctions Any application-supplied function definitions
|
||||
*/
|
||||
public SQLFunctionRegistry(Dialect dialect, Map<String, SQLFunction> userFunctions) {
|
||||
this.dialect = dialect;
|
||||
this.userFunctions = new HashMap<String, SQLFunction>( userFunctions );
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a SQLFunction by name
|
||||
*
|
||||
* @param functionName The name of the function to locate
|
||||
*
|
||||
* @return The located function, maye return {@code null}
|
||||
*/
|
||||
public SQLFunction findSQLFunction(String functionName) {
|
||||
String name = functionName.toLowerCase();
|
||||
SQLFunction userFunction = userFunctions.get( name );
|
||||
final String name = functionName.toLowerCase();
|
||||
final SQLFunction userFunction = userFunctions.get( name );
|
||||
return userFunction != null
|
||||
? userFunction
|
||||
: dialect.getFunctions().get( name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this registry contain the named function
|
||||
*
|
||||
* @param functionName The name of the function to attempt to locate
|
||||
*
|
||||
* @return {@code true} if the registry contained that function
|
||||
*/
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public boolean hasFunction(String functionName) {
|
||||
String name = functionName.toLowerCase();
|
||||
final String name = functionName.toLowerCase();
|
||||
return userFunctions.containsKey( name ) || dialect.getFunctions().containsKey( name );
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.function;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.QueryException;
|
||||
@ -30,11 +31,13 @@
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* Represents HQL functions that can have different representations in different SQL dialects.
|
||||
* E.g. in HQL we can define function <code>concat(?1, ?2)</code> to concatenate two strings
|
||||
* p1 and p2. Target SQL function will be dialect-specific, e.g. <code>(?1 || ?2)</code> for
|
||||
* Oracle, <code>concat(?1, ?2)</code> for MySql, <code>(?1 + ?2)</code> for MS SQL.
|
||||
* Each dialect will define a template as a string (exactly like above) marking function
|
||||
* Represents HQL functions that can have different representations in different SQL dialects where that
|
||||
* difference can be handled via a template/pattern.
|
||||
* <p/>
|
||||
* E.g. in HQL we can define function <code>concat(?1, ?2)</code> to concatenate two strings
|
||||
* p1 and p2. Dialects would register different versions of this class *using the same name* (concat) but with
|
||||
* different templates or patterns; <code>(?1 || ?2)</code> for Oracle, <code>concat(?1, ?2)</code> for MySql,
|
||||
* <code>(?1 + ?2)</code> for MS SQL. Each dialect will define a template as a string (exactly like above) marking function
|
||||
* parameters with '?' followed by parameter's index (first index is 1).
|
||||
*
|
||||
* @author <a href="mailto:alex@jboss.org">Alexey Loubyansky</a>
|
||||
@ -44,47 +47,50 @@ public class SQLFunctionTemplate implements SQLFunction {
|
||||
private final TemplateRenderer renderer;
|
||||
private final boolean hasParenthesesIfNoArgs;
|
||||
|
||||
/**
|
||||
* Constructs a SQLFunctionTemplate
|
||||
*
|
||||
* @param type The functions return type
|
||||
* @param template The function template
|
||||
*/
|
||||
public SQLFunctionTemplate(Type type, String template) {
|
||||
this( type, template, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a SQLFunctionTemplate
|
||||
*
|
||||
* @param type The functions return type
|
||||
* @param template The function template
|
||||
* @param hasParenthesesIfNoArgs If there are no arguments, are parentheses required?
|
||||
*/
|
||||
public SQLFunctionTemplate(Type type, String template, boolean hasParenthesesIfNoArgs) {
|
||||
this.type = type;
|
||||
this.renderer = new TemplateRenderer( template );
|
||||
this.hasParenthesesIfNoArgs = hasParenthesesIfNoArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String render(Type argumentType, List args, SessionFactoryImplementor factory) {
|
||||
return renderer.render( args, factory );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Type getReturnType(Type argumentType, Mapping mapping) throws QueryException {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean hasArguments() {
|
||||
return renderer.getAnticipatedNumberOfArguments() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean hasParenthesesIfNoArguments() {
|
||||
return hasParenthesesIfNoArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return renderer.getTemplate();
|
||||
}
|
||||
|
@ -45,9 +45,12 @@ public class StandardAnsiSqlAggregationFunctions {
|
||||
* Definition of a standard ANSI SQL compliant <tt>COUNT</tt> function
|
||||
*/
|
||||
public static class CountFunction extends StandardSQLFunction {
|
||||
/**
|
||||
* Singleton access
|
||||
*/
|
||||
public static final CountFunction INSTANCE = new CountFunction();
|
||||
|
||||
public CountFunction() {
|
||||
protected CountFunction() {
|
||||
super( "count", StandardBasicTypes.LONG );
|
||||
}
|
||||
|
||||
@ -62,35 +65,37 @@ public String render(Type firstArgumentType, List arguments, SessionFactoryImple
|
||||
}
|
||||
|
||||
private String renderCountDistinct(List arguments) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
final StringBuilder buffer = new StringBuilder();
|
||||
buffer.append( "count(distinct " );
|
||||
String sep = "";
|
||||
Iterator itr = arguments.iterator();
|
||||
itr.next(); // intentionally skip first
|
||||
final Iterator itr = arguments.iterator();
|
||||
// intentionally skip first
|
||||
itr.next();
|
||||
while ( itr.hasNext() ) {
|
||||
buffer.append( sep )
|
||||
.append( itr.next() );
|
||||
buffer.append( sep ).append( itr.next() );
|
||||
sep = ", ";
|
||||
}
|
||||
return buffer.append( ")" ).toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Definition of a standard ANSI SQL compliant <tt>AVG</tt> function
|
||||
*/
|
||||
public static class AvgFunction extends StandardSQLFunction {
|
||||
/**
|
||||
* Singleton access
|
||||
*/
|
||||
public static final AvgFunction INSTANCE = new AvgFunction();
|
||||
|
||||
public AvgFunction() {
|
||||
protected AvgFunction() {
|
||||
super( "avg", StandardBasicTypes.DOUBLE );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String render(Type firstArgumentType, List arguments, SessionFactoryImplementor factory) throws QueryException {
|
||||
int jdbcTypeCode = determineJdbcTypeCode( firstArgumentType, factory );
|
||||
return render( jdbcTypeCode, arguments.get(0).toString(), factory );
|
||||
final int jdbcTypeCode = determineJdbcTypeCode( firstArgumentType, factory );
|
||||
return render( jdbcTypeCode, arguments.get( 0 ).toString(), factory );
|
||||
}
|
||||
|
||||
protected final int determineJdbcTypeCode(Type firstArgumentType, SessionFactoryImplementor factory) throws QueryException {
|
||||
@ -106,6 +111,7 @@ protected final int determineJdbcTypeCode(Type firstArgumentType, SessionFactory
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnusedParameters")
|
||||
protected String render(int firstArgumentJdbcType, String argument, SessionFactoryImplementor factory) {
|
||||
return "avg(" + renderArgument( argument, firstArgumentJdbcType ) + ")";
|
||||
}
|
||||
@ -115,44 +121,49 @@ protected String renderArgument(String argument, int firstArgumentJdbcType) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Definition of a standard ANSI SQL compliant <tt>MAX</tt> function
|
||||
*/
|
||||
public static class MaxFunction extends StandardSQLFunction {
|
||||
/**
|
||||
* Singleton access
|
||||
*/
|
||||
public static final MaxFunction INSTANCE = new MaxFunction();
|
||||
|
||||
public MaxFunction() {
|
||||
protected MaxFunction() {
|
||||
super( "max" );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Definition of a standard ANSI SQL compliant <tt>MIN</tt> function
|
||||
*/
|
||||
public static class MinFunction extends StandardSQLFunction {
|
||||
/**
|
||||
* Singleton access
|
||||
*/
|
||||
public static final MinFunction INSTANCE = new MinFunction();
|
||||
|
||||
public MinFunction() {
|
||||
protected MinFunction() {
|
||||
super( "min" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Definition of a standard ANSI SQL compliant <tt>SUM</tt> function
|
||||
*/
|
||||
public static class SumFunction extends StandardSQLFunction {
|
||||
/**
|
||||
* Singleton access
|
||||
*/
|
||||
public static final SumFunction INSTANCE = new SumFunction();
|
||||
|
||||
public SumFunction() {
|
||||
protected SumFunction() {
|
||||
super( "sum" );
|
||||
}
|
||||
|
||||
protected final int determineJdbcTypeCode(Type type, Mapping mapping) throws QueryException {
|
||||
try {
|
||||
final int[] jdbcTypeCodes = type.sqlTypes( mapping );
|
||||
if ( jdbcTypeCodes.length != 1 ) {
|
||||
throw new QueryException( "multiple-column type in sum()" );
|
||||
}
|
||||
return jdbcTypeCodes[0];
|
||||
}
|
||||
catch ( MappingException me ) {
|
||||
throw new QueryException( me );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getReturnType(Type firstArgumentType, Mapping mapping) {
|
||||
final int jdbcType = determineJdbcTypeCode( firstArgumentType, mapping );
|
||||
|
||||
@ -193,8 +204,27 @@ else if ( jdbcType == Types.BIGINT
|
||||
// as a last resort, return the type of the first argument
|
||||
return firstArgumentType;
|
||||
}
|
||||
|
||||
protected final int determineJdbcTypeCode(Type type, Mapping mapping) throws QueryException {
|
||||
try {
|
||||
final int[] jdbcTypeCodes = type.sqlTypes( mapping );
|
||||
if ( jdbcTypeCodes.length != 1 ) {
|
||||
throw new QueryException( "multiple-column type in sum()" );
|
||||
}
|
||||
return jdbcTypeCodes[0];
|
||||
}
|
||||
catch ( MappingException me ) {
|
||||
throw new QueryException( me );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Push the functions defined on StandardAnsiSqlAggregationFunctions into the given map
|
||||
*
|
||||
* @param functionMap The map of functions to push to
|
||||
*/
|
||||
public static void primeFunctionMap(Map<String, SQLFunction> functionMap) {
|
||||
functionMap.put( AvgFunction.INSTANCE.getName(), AvgFunction.INSTANCE );
|
||||
functionMap.put( CountFunction.INSTANCE.getName(), CountFunction.INSTANCE );
|
||||
@ -202,4 +232,7 @@ public static void primeFunctionMap(Map<String, SQLFunction> functionMap) {
|
||||
functionMap.put( MinFunction.INSTANCE.getName(), MinFunction.INSTANCE );
|
||||
functionMap.put( SumFunction.INSTANCE.getName(), SumFunction.INSTANCE );
|
||||
}
|
||||
|
||||
private StandardAnsiSqlAggregationFunctions() {
|
||||
}
|
||||
}
|
||||
|
@ -35,18 +35,22 @@
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class StandardJDBCEscapeFunction extends StandardSQLFunction {
|
||||
public StandardJDBCEscapeFunction(String name) {
|
||||
super( name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a StandardJDBCEscapeFunction
|
||||
*
|
||||
* @param name The function name
|
||||
* @param typeValue The function return type
|
||||
*/
|
||||
public StandardJDBCEscapeFunction(String name, Type typeValue) {
|
||||
super( name, typeValue );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String render(Type argumentType, List args, SessionFactoryImplementor factory) {
|
||||
return "{fn " + super.render( argumentType, args, factory ) + "}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{fn " + getName() + "...}";
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.function;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.engine.spi.Mapping;
|
||||
@ -84,32 +85,24 @@ public Type getType() {
|
||||
return registeredType;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean hasArguments() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean hasParenthesesIfNoArguments() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Type getReturnType(Type firstArgumentType, Mapping mapping) {
|
||||
return registeredType == null ? firstArgumentType : registeredType;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String render(Type firstArgumentType, List arguments, SessionFactoryImplementor sessionFactory) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
buf.append( name ).append( '(' );
|
||||
for ( int i = 0; i < arguments.size(); i++ ) {
|
||||
buf.append( arguments.get( i ) );
|
||||
@ -120,6 +113,7 @@ public String render(Type firstArgumentType, List arguments, SessionFactoryImple
|
||||
return buf.append( ')' ).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
@ -36,21 +36,28 @@
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class TemplateRenderer {
|
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, TemplateRenderer.class.getName());
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
TemplateRenderer.class.getName()
|
||||
);
|
||||
|
||||
private final String template;
|
||||
private final String[] chunks;
|
||||
private final int[] paramIndexes;
|
||||
|
||||
/**
|
||||
* Constructs a template renderer
|
||||
*
|
||||
* @param template The template
|
||||
*/
|
||||
@SuppressWarnings({ "UnnecessaryUnboxing" })
|
||||
public TemplateRenderer(String template) {
|
||||
this.template = template;
|
||||
|
||||
List<String> chunkList = new ArrayList<String>();
|
||||
List<Integer> paramList = new ArrayList<Integer>();
|
||||
StringBuilder chunk = new StringBuilder( 10 );
|
||||
StringBuilder index = new StringBuilder( 2 );
|
||||
final List<String> chunkList = new ArrayList<String>();
|
||||
final List<Integer> paramList = new ArrayList<Integer>();
|
||||
final StringBuilder chunk = new StringBuilder( 10 );
|
||||
final StringBuilder index = new StringBuilder( 2 );
|
||||
|
||||
for ( int i = 0; i < template.length(); ++i ) {
|
||||
char c = template.charAt( i );
|
||||
@ -96,13 +103,21 @@ public int getAnticipatedNumberOfArguments() {
|
||||
return paramIndexes.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* The rendering code.
|
||||
*
|
||||
* @param args The arguments to inject into the template
|
||||
* @param factory The SessionFactory
|
||||
*
|
||||
* @return The rendered template with replacements
|
||||
*/
|
||||
@SuppressWarnings({ "UnusedDeclaration" })
|
||||
public String render(List args, SessionFactoryImplementor factory) {
|
||||
int numberOfArguments = args.size();
|
||||
final int numberOfArguments = args.size();
|
||||
if ( getAnticipatedNumberOfArguments() > 0 && numberOfArguments != getAnticipatedNumberOfArguments() ) {
|
||||
LOG.missingArguments( getAnticipatedNumberOfArguments(), numberOfArguments );
|
||||
}
|
||||
StringBuilder buf = new StringBuilder();
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
for ( int i = 0; i < chunks.length; ++i ) {
|
||||
if ( i < paramIndexes.length ) {
|
||||
final int index = paramIndexes[i] - 1;
|
||||
|
@ -36,30 +36,34 @@
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class TrimFunctionTemplate implements SQLFunction {
|
||||
@Override
|
||||
public boolean hasArguments() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasParenthesesIfNoArguments() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getReturnType(Type firstArgument, Mapping mapping) throws QueryException {
|
||||
return StandardBasicTypes.STRING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String render(Type firstArgument, List args, SessionFactoryImplementor factory) throws QueryException {
|
||||
final Options options = new Options();
|
||||
final String trimSource;
|
||||
|
||||
if ( args.size() == 1 ) {
|
||||
// we have the form: trim(trimSource)
|
||||
trimSource = ( String ) args.get( 0 );
|
||||
trimSource = (String) args.get( 0 );
|
||||
}
|
||||
else if ( "from".equalsIgnoreCase( ( String ) args.get( 0 ) ) ) {
|
||||
else if ( "from".equalsIgnoreCase( (String) args.get( 0 ) ) ) {
|
||||
// we have the form: trim(from trimSource).
|
||||
// This is functionally equivalent to trim(trimSource)
|
||||
trimSource = ( String ) args.get( 1 );
|
||||
trimSource = (String) args.get( 1 );
|
||||
}
|
||||
else {
|
||||
// otherwise, a trim-specification and/or a trim-character
|
||||
@ -70,7 +74,7 @@ else if ( "from".equalsIgnoreCase( ( String ) args.get( 0 ) ) ) {
|
||||
// trim-specification has been specified. we handle the
|
||||
// exception to that explicitly
|
||||
int potentialTrimCharacterArgIndex = 1;
|
||||
String firstArg = ( String ) args.get( 0 );
|
||||
final String firstArg = (String) args.get( 0 );
|
||||
if ( "leading".equalsIgnoreCase( firstArg ) ) {
|
||||
options.setTrimSpecification( Specification.LEADING );
|
||||
}
|
||||
@ -84,20 +88,20 @@ else if ( "both".equalsIgnoreCase( firstArg ) ) {
|
||||
potentialTrimCharacterArgIndex = 0;
|
||||
}
|
||||
|
||||
String potentialTrimCharacter = ( String ) args.get( potentialTrimCharacterArgIndex );
|
||||
final String potentialTrimCharacter = (String) args.get( potentialTrimCharacterArgIndex );
|
||||
if ( "from".equalsIgnoreCase( potentialTrimCharacter ) ) {
|
||||
trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
|
||||
trimSource = (String) args.get( potentialTrimCharacterArgIndex + 1 );
|
||||
}
|
||||
else if ( potentialTrimCharacterArgIndex + 1 >= args.size() ) {
|
||||
trimSource = potentialTrimCharacter;
|
||||
}
|
||||
else {
|
||||
options.setTrimCharacter( potentialTrimCharacter );
|
||||
if ( "from".equalsIgnoreCase( ( String ) args.get( potentialTrimCharacterArgIndex + 1 ) ) ) {
|
||||
trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 2 );
|
||||
if ( "from".equalsIgnoreCase( (String) args.get( potentialTrimCharacterArgIndex + 1 ) ) ) {
|
||||
trimSource = (String) args.get( potentialTrimCharacterArgIndex + 2 );
|
||||
}
|
||||
else {
|
||||
trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
|
||||
trimSource = (String) args.get( potentialTrimCharacterArgIndex + 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -106,7 +110,7 @@ else if ( potentialTrimCharacterArgIndex + 1 >= args.size() ) {
|
||||
|
||||
protected abstract String render(Options options, String trimSource, SessionFactoryImplementor factory);
|
||||
|
||||
public static class Options {
|
||||
protected static class Options {
|
||||
public static final String DEFAULT_TRIM_CHARACTER = "' '";
|
||||
|
||||
private String trimCharacter = DEFAULT_TRIM_CHARACTER;
|
||||
@ -129,7 +133,7 @@ public void setTrimSpecification(Specification trimSpecification) {
|
||||
}
|
||||
}
|
||||
|
||||
public static class Specification {
|
||||
protected static class Specification {
|
||||
public static final Specification LEADING = new Specification( "leading" );
|
||||
public static final Specification TRAILING = new Specification( "trailing" );
|
||||
public static final Specification BOTH = new Specification( "both" );
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.function;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.QueryException;
|
||||
@ -73,35 +74,26 @@ public VarArgsSQLFunction(String begin, String sep, String end) {
|
||||
this( null, begin, sep, end );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p/>
|
||||
* Always returns true here.
|
||||
*/
|
||||
@Override
|
||||
public boolean hasArguments() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p/>
|
||||
* Always returns true here.
|
||||
*/
|
||||
@Override
|
||||
public boolean hasParenthesesIfNoArguments() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Type getReturnType(Type firstArgumentType, Mapping mapping) throws QueryException {
|
||||
return registeredType == null ? firstArgumentType : registeredType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String render(Type firstArgumentType, List arguments, SessionFactoryImplementor factory) {
|
||||
StringBuilder buf = new StringBuilder().append( begin );
|
||||
final StringBuilder buf = new StringBuilder().append( begin );
|
||||
for ( int i = 0; i < arguments.size(); i++ ) {
|
||||
buf.append( transformArgument( ( String ) arguments.get( i ) ) );
|
||||
buf.append( transformArgument( (String) arguments.get( i ) ) );
|
||||
if ( i < arguments.size() - 1 ) {
|
||||
buf.append( sep );
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.lock;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.persister.entity.Lockable;
|
||||
@ -70,7 +71,7 @@ else if ( timeout == LockOptions.SKIP_LOCKED) {
|
||||
|
||||
private String noWaitSql;
|
||||
|
||||
public String getNoWaitSql() {
|
||||
protected String getNoWaitSql() {
|
||||
if ( noWaitSql == null ) {
|
||||
noWaitSql = generateLockString( LockOptions.NO_WAIT );
|
||||
}
|
||||
@ -79,7 +80,7 @@ public String getNoWaitSql() {
|
||||
|
||||
private String skipLockedSql;
|
||||
|
||||
public String getSkipLockedSql() {
|
||||
protected String getSkipLockedSql() {
|
||||
if ( skipLockedSql == null ) {
|
||||
skipLockedSql = generateLockString( LockOptions.SKIP_LOCKED );
|
||||
}
|
||||
|
@ -51,10 +51,11 @@ public interface LockingStrategy {
|
||||
* @param object The object logically being locked (currently not used)
|
||||
* @param timeout timeout in milliseconds, 0 = no wait, -1 = wait indefinitely
|
||||
* @param session The session from which the lock request originated
|
||||
*
|
||||
* @throws StaleObjectStateException Indicates an inability to locate the database row as part of acquiring
|
||||
* the requested lock.
|
||||
* @throws LockingStrategyException Indicates a failure in the lock attempt
|
||||
*/
|
||||
public void lock(Serializable id, Object version, Object object, int timeout, SessionImplementor session)
|
||||
throws StaleObjectStateException, LockingStrategyException;
|
||||
throws StaleObjectStateException, LockingStrategyException;
|
||||
}
|
||||
|
@ -33,13 +33,26 @@
|
||||
public abstract class LockingStrategyException extends HibernateException {
|
||||
private final Object entity;
|
||||
|
||||
/**
|
||||
* Constructs a LockingStrategyException
|
||||
*
|
||||
* @param entity The entity we were trying to lock
|
||||
* @param message Message explaining the condition
|
||||
*/
|
||||
public LockingStrategyException(Object entity, String message) {
|
||||
super( message );
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
public LockingStrategyException(Object entity, String message, Throwable root) {
|
||||
super( message, root );
|
||||
/**
|
||||
* Constructs a LockingStrategyException
|
||||
*
|
||||
* @param entity The entity we were trying to lock
|
||||
* @param message Message explaining the condition
|
||||
* @param cause The underlying cause
|
||||
*/
|
||||
public LockingStrategyException(Object entity, String message, Throwable cause) {
|
||||
super( message, cause );
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
|
@ -29,11 +29,24 @@
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class OptimisticEntityLockException extends LockingStrategyException {
|
||||
/**
|
||||
* Constructs a OptimisticEntityLockException
|
||||
*
|
||||
* @param entity The entity we were trying to lock
|
||||
* @param message Message explaining the condition
|
||||
*/
|
||||
public OptimisticEntityLockException(Object entity, String message) {
|
||||
super( entity, message );
|
||||
}
|
||||
|
||||
public OptimisticEntityLockException(Object entity, String message, Throwable root) {
|
||||
super( entity, message, root );
|
||||
/**
|
||||
* Constructs a OptimisticEntityLockException
|
||||
*
|
||||
* @param entity The entity we were trying to lock
|
||||
* @param message Message explaining the condition
|
||||
* @param cause The underlying cause
|
||||
*/
|
||||
public OptimisticEntityLockException(Object entity, String message, Throwable cause) {
|
||||
super( entity, message, cause );
|
||||
}
|
||||
}
|
||||
|
@ -65,14 +65,12 @@ public void lock(Serializable id, Object version, Object object, int timeout, Se
|
||||
if ( !lockable.isVersioned() ) {
|
||||
throw new HibernateException( "[" + lockMode + "] not supported for non-versioned entities [" + lockable.getEntityName() + "]" );
|
||||
}
|
||||
EntityEntry entry = session.getPersistenceContext().getEntry( object );
|
||||
EntityIncrementVersionProcess incrementVersion = new EntityIncrementVersionProcess( object, entry );
|
||||
EventSource source = (EventSource) session;
|
||||
// Register the EntityIncrementVersionProcess action to run just prior to transaction commit.
|
||||
source.getActionQueue().registerProcess( incrementVersion );
|
||||
final EntityEntry entry = session.getPersistenceContext().getEntry( object );
|
||||
// Register the EntityIncrementVersionProcess action to run just prior to transaction commit.
|
||||
( (EventSource) session ).getActionQueue().registerProcess( new EntityIncrementVersionProcess( object, entry ) );
|
||||
}
|
||||
|
||||
protected LockMode getLockMode() {
|
||||
return lockMode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,6 @@
|
||||
* @since 3.5
|
||||
*/
|
||||
public class OptimisticLockingStrategy implements LockingStrategy {
|
||||
|
||||
private final Lockable lockable;
|
||||
private final LockMode lockMode;
|
||||
|
||||
@ -66,14 +65,12 @@ public void lock(Serializable id, Object version, Object object, int timeout, Se
|
||||
if ( !lockable.isVersioned() ) {
|
||||
throw new OptimisticLockException( object, "[" + lockMode + "] not supported for non-versioned entities [" + lockable.getEntityName() + "]" );
|
||||
}
|
||||
EntityEntry entry = session.getPersistenceContext().getEntry(object);
|
||||
EventSource source = (EventSource)session;
|
||||
EntityVerifyVersionProcess verifyVersion = new EntityVerifyVersionProcess(object, entry);
|
||||
final EntityEntry entry = session.getPersistenceContext().getEntry(object);
|
||||
// Register the EntityVerifyVersionProcess action to run just prior to transaction commit.
|
||||
source.getActionQueue().registerProcess(verifyVersion);
|
||||
( (EventSource) session ).getActionQueue().registerProcess( new EntityVerifyVersionProcess( object, entry ) );
|
||||
}
|
||||
|
||||
protected LockMode getLockMode() {
|
||||
return lockMode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,14 @@
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class PessimisticEntityLockException extends LockingStrategyException {
|
||||
public PessimisticEntityLockException(Object entity, String message, JDBCException root) {
|
||||
super( entity, message, root );
|
||||
/**
|
||||
* Constructs a PessimisticEntityLockException
|
||||
*
|
||||
* @param entity The entity we were trying to lock
|
||||
* @param message Message explaining the condition
|
||||
* @param cause The underlying cause
|
||||
*/
|
||||
public PessimisticEntityLockException(Object entity, String message, JDBCException cause) {
|
||||
super( entity, message, cause );
|
||||
}
|
||||
}
|
||||
|
@ -64,9 +64,9 @@ public void lock(Serializable id, Object version, Object object, int timeout, Se
|
||||
if ( !lockable.isVersioned() ) {
|
||||
throw new HibernateException( "[" + lockMode + "] not supported for non-versioned entities [" + lockable.getEntityName() + "]" );
|
||||
}
|
||||
EntityEntry entry = session.getPersistenceContext().getEntry( object );
|
||||
final EntityEntry entry = session.getPersistenceContext().getEntry( object );
|
||||
final EntityPersister persister = entry.getPersister();
|
||||
Object nextVersion = persister.forceVersionIncrement( entry.getId(), entry.getVersion(), session );
|
||||
final Object nextVersion = persister.forceVersionIncrement( entry.getId(), entry.getVersion(), session );
|
||||
entry.forceLocked( object, nextVersion );
|
||||
}
|
||||
|
||||
@ -78,4 +78,4 @@ public void lock(Serializable id, Object version, Object object, int timeout, Se
|
||||
protected LockMode getLockMode() {
|
||||
return lockMode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -70,10 +70,10 @@ public PessimisticReadSelectLockingStrategy(Lockable lockable, LockMode lockMode
|
||||
@Override
|
||||
public void lock(Serializable id, Object version, Object object, int timeout, SessionImplementor session) {
|
||||
final String sql = determineSql( timeout );
|
||||
SessionFactoryImplementor factory = session.getFactory();
|
||||
final SessionFactoryImplementor factory = session.getFactory();
|
||||
try {
|
||||
try {
|
||||
PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
final PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
getLockable().getIdentifierType().nullSafeSet( st, id, 1, session );
|
||||
if ( getLockable().isVersioned() ) {
|
||||
@ -85,7 +85,7 @@ public void lock(Serializable id, Object version, Object object, int timeout, Se
|
||||
);
|
||||
}
|
||||
|
||||
ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
final ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
try {
|
||||
if ( !rs.next() ) {
|
||||
if ( factory.getStatistics().isStatisticsEnabled() ) {
|
||||
@ -118,10 +118,10 @@ public void lock(Serializable id, Object version, Object object, int timeout, Se
|
||||
}
|
||||
|
||||
protected String generateLockString(int lockTimeout) {
|
||||
SessionFactoryImplementor factory = getLockable().getFactory();
|
||||
LockOptions lockOptions = new LockOptions( getLockMode() );
|
||||
final SessionFactoryImplementor factory = getLockable().getFactory();
|
||||
final LockOptions lockOptions = new LockOptions( getLockMode() );
|
||||
lockOptions.setTimeOut( lockTimeout );
|
||||
SimpleSelect select = new SimpleSelect( factory.getDialect() )
|
||||
final SimpleSelect select = new SimpleSelect( factory.getDialect() )
|
||||
.setLockOptions( lockOptions )
|
||||
.setTableName( getLockable().getRootTableName() )
|
||||
.addColumn( getLockable().getRootTableIdentifierColumnNames()[0] )
|
||||
@ -134,4 +134,4 @@ protected String generateLockString(int lockTimeout) {
|
||||
}
|
||||
return select.toStatementString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,8 +52,7 @@
|
||||
* @since 3.5
|
||||
*/
|
||||
public class PessimisticReadUpdateLockingStrategy implements LockingStrategy {
|
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
PessimisticReadUpdateLockingStrategy.class.getName()
|
||||
);
|
||||
@ -89,10 +88,11 @@ public void lock(Serializable id, Object version, Object object, int timeout, Se
|
||||
if ( !lockable.isVersioned() ) {
|
||||
throw new HibernateException( "write locks via update not supported for non-versioned entities [" + lockable.getEntityName() + "]" );
|
||||
}
|
||||
SessionFactoryImplementor factory = session.getFactory();
|
||||
|
||||
final SessionFactoryImplementor factory = session.getFactory();
|
||||
try {
|
||||
try {
|
||||
PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
final PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
lockable.getVersionType().nullSafeSet( st, version, 1, session );
|
||||
int offset = 2;
|
||||
@ -104,8 +104,9 @@ public void lock(Serializable id, Object version, Object object, int timeout, Se
|
||||
lockable.getVersionType().nullSafeSet( st, version, offset, session );
|
||||
}
|
||||
|
||||
int affected = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st );
|
||||
if ( affected < 0 ) { // todo: should this instead check for exactly one row modified?
|
||||
final int affected = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st );
|
||||
// todo: should this instead check for exactly one row modified?
|
||||
if ( affected < 0 ) {
|
||||
if (factory.getStatistics().isStatisticsEnabled()) {
|
||||
factory.getStatisticsImplementor().optimisticFailure( lockable.getEntityName() );
|
||||
}
|
||||
@ -132,8 +133,8 @@ public void lock(Serializable id, Object version, Object object, int timeout, Se
|
||||
}
|
||||
|
||||
protected String generateLockString() {
|
||||
SessionFactoryImplementor factory = lockable.getFactory();
|
||||
Update update = new Update( factory.getDialect() );
|
||||
final SessionFactoryImplementor factory = lockable.getFactory();
|
||||
final Update update = new Update( factory.getDialect() );
|
||||
update.setTableName( lockable.getRootTableName() );
|
||||
update.addPrimaryKeyColumns( lockable.getRootTableIdentifierColumnNames() );
|
||||
update.setVersionColumnName( lockable.getVersionColumnName() );
|
||||
@ -147,4 +148,4 @@ protected String generateLockString() {
|
||||
protected LockMode getLockMode() {
|
||||
return lockMode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -69,10 +69,10 @@ public PessimisticWriteSelectLockingStrategy(Lockable lockable, LockMode lockMod
|
||||
@Override
|
||||
public void lock(Serializable id, Object version, Object object, int timeout, SessionImplementor session) {
|
||||
final String sql = determineSql( timeout );
|
||||
SessionFactoryImplementor factory = session.getFactory();
|
||||
final SessionFactoryImplementor factory = session.getFactory();
|
||||
try {
|
||||
try {
|
||||
PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
final PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
getLockable().getIdentifierType().nullSafeSet( st, id, 1, session );
|
||||
if ( getLockable().isVersioned() ) {
|
||||
@ -84,7 +84,7 @@ public void lock(Serializable id, Object version, Object object, int timeout, Se
|
||||
);
|
||||
}
|
||||
|
||||
ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
final ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
try {
|
||||
if ( !rs.next() ) {
|
||||
if ( factory.getStatistics().isStatisticsEnabled() ) {
|
||||
@ -116,10 +116,10 @@ public void lock(Serializable id, Object version, Object object, int timeout, Se
|
||||
}
|
||||
|
||||
protected String generateLockString(int lockTimeout) {
|
||||
SessionFactoryImplementor factory = getLockable().getFactory();
|
||||
LockOptions lockOptions = new LockOptions( getLockMode() );
|
||||
final SessionFactoryImplementor factory = getLockable().getFactory();
|
||||
final LockOptions lockOptions = new LockOptions( getLockMode() );
|
||||
lockOptions.setTimeOut( lockTimeout );
|
||||
SimpleSelect select = new SimpleSelect( factory.getDialect() )
|
||||
final SimpleSelect select = new SimpleSelect( factory.getDialect() )
|
||||
.setLockOptions( lockOptions )
|
||||
.setTableName( getLockable().getRootTableName() )
|
||||
.addColumn( getLockable().getRootTableIdentifierColumnNames()[0] )
|
||||
@ -132,4 +132,4 @@ protected String generateLockString(int lockTimeout) {
|
||||
}
|
||||
return select.toStatementString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,8 +52,7 @@
|
||||
* @since 3.5
|
||||
*/
|
||||
public class PessimisticWriteUpdateLockingStrategy implements LockingStrategy {
|
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
PessimisticWriteUpdateLockingStrategy.class.getName()
|
||||
);
|
||||
@ -88,10 +87,11 @@ public void lock(Serializable id, Object version, Object object, int timeout, Se
|
||||
if ( !lockable.isVersioned() ) {
|
||||
throw new HibernateException( "write locks via update not supported for non-versioned entities [" + lockable.getEntityName() + "]" );
|
||||
}
|
||||
SessionFactoryImplementor factory = session.getFactory();
|
||||
|
||||
final SessionFactoryImplementor factory = session.getFactory();
|
||||
try {
|
||||
try {
|
||||
PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
final PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
lockable.getVersionType().nullSafeSet( st, version, 1, session );
|
||||
int offset = 2;
|
||||
@ -103,8 +103,9 @@ public void lock(Serializable id, Object version, Object object, int timeout, Se
|
||||
lockable.getVersionType().nullSafeSet( st, version, offset, session );
|
||||
}
|
||||
|
||||
int affected = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st );
|
||||
if ( affected < 0 ) { // todo: should this instead check for exactly one row modified?
|
||||
final int affected = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st );
|
||||
// todo: should this instead check for exactly one row modified?
|
||||
if ( affected < 0 ) {
|
||||
if (factory.getStatistics().isStatisticsEnabled()) {
|
||||
factory.getStatisticsImplementor().optimisticFailure( lockable.getEntityName() );
|
||||
}
|
||||
@ -130,8 +131,8 @@ public void lock(Serializable id, Object version, Object object, int timeout, Se
|
||||
}
|
||||
|
||||
protected String generateLockString() {
|
||||
SessionFactoryImplementor factory = lockable.getFactory();
|
||||
Update update = new Update( factory.getDialect() );
|
||||
final SessionFactoryImplementor factory = lockable.getFactory();
|
||||
final Update update = new Update( factory.getDialect() );
|
||||
update.setTableName( lockable.getRootTableName() );
|
||||
update.addPrimaryKeyColumns( lockable.getRootTableIdentifierColumnNames() );
|
||||
update.setVersionColumnName( lockable.getVersionColumnName() );
|
||||
@ -145,4 +146,4 @@ protected String generateLockString() {
|
||||
protected LockMode getLockMode() {
|
||||
return lockMode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -61,19 +61,17 @@ public SelectLockingStrategy(Lockable lockable, LockMode lockMode) {
|
||||
super( lockable, lockMode );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see LockingStrategy#lock
|
||||
*/
|
||||
@Override
|
||||
public void lock(
|
||||
Serializable id,
|
||||
Object version,
|
||||
Object object,
|
||||
int timeout,
|
||||
SessionImplementor session) throws StaleObjectStateException, JDBCException {
|
||||
Serializable id,
|
||||
Object version,
|
||||
Object object,
|
||||
int timeout,
|
||||
SessionImplementor session) throws StaleObjectStateException, JDBCException {
|
||||
final String sql = determineSql( timeout );
|
||||
SessionFactoryImplementor factory = session.getFactory();
|
||||
final SessionFactoryImplementor factory = session.getFactory();
|
||||
try {
|
||||
PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
final PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
getLockable().getIdentifierType().nullSafeSet( st, id, 1, session );
|
||||
if ( getLockable().isVersioned() ) {
|
||||
@ -85,7 +83,7 @@ public void lock(
|
||||
);
|
||||
}
|
||||
|
||||
ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
final ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
try {
|
||||
if ( !rs.next() ) {
|
||||
if ( factory.getStatistics().isStatisticsEnabled() ) {
|
||||
@ -114,10 +112,10 @@ public void lock(
|
||||
}
|
||||
|
||||
protected String generateLockString(int timeout) {
|
||||
SessionFactoryImplementor factory = getLockable().getFactory();
|
||||
LockOptions lockOptions = new LockOptions( getLockMode() );
|
||||
final SessionFactoryImplementor factory = getLockable().getFactory();
|
||||
final LockOptions lockOptions = new LockOptions( getLockMode() );
|
||||
lockOptions.setTimeOut( timeout );
|
||||
SimpleSelect select = new SimpleSelect( factory.getDialect() )
|
||||
final SimpleSelect select = new SimpleSelect( factory.getDialect() )
|
||||
.setLockOptions( lockOptions )
|
||||
.setTableName( getLockable().getRootTableName() )
|
||||
.addColumn( getLockable().getRootTableIdentifierColumnNames()[0] )
|
||||
|
@ -49,8 +49,7 @@
|
||||
* @since 3.2
|
||||
*/
|
||||
public class UpdateLockingStrategy implements LockingStrategy {
|
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
UpdateLockingStrategy.class.getName()
|
||||
);
|
||||
@ -83,18 +82,19 @@ public UpdateLockingStrategy(Lockable lockable, LockMode lockMode) {
|
||||
|
||||
@Override
|
||||
public void lock(
|
||||
Serializable id,
|
||||
Object version,
|
||||
Object object,
|
||||
int timeout,
|
||||
SessionImplementor session) throws StaleObjectStateException, JDBCException {
|
||||
Serializable id,
|
||||
Object version,
|
||||
Object object,
|
||||
int timeout,
|
||||
SessionImplementor session) throws StaleObjectStateException, JDBCException {
|
||||
if ( !lockable.isVersioned() ) {
|
||||
throw new HibernateException( "write locks via update not supported for non-versioned entities [" + lockable.getEntityName() + "]" );
|
||||
}
|
||||
|
||||
// todo : should we additionally check the current isolation mode explicitly?
|
||||
SessionFactoryImplementor factory = session.getFactory();
|
||||
final SessionFactoryImplementor factory = session.getFactory();
|
||||
try {
|
||||
PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
final PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
lockable.getVersionType().nullSafeSet( st, version, 1, session );
|
||||
int offset = 2;
|
||||
@ -106,7 +106,7 @@ public void lock(
|
||||
lockable.getVersionType().nullSafeSet( st, version, offset, session );
|
||||
}
|
||||
|
||||
int affected = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st );
|
||||
final int affected = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st );
|
||||
if ( affected < 0 ) {
|
||||
if (factory.getStatistics().isStatisticsEnabled()) {
|
||||
factory.getStatisticsImplementor().optimisticFailure( lockable.getEntityName() );
|
||||
@ -122,16 +122,16 @@ public void lock(
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
throw session.getFactory().getSQLExceptionHelper().convert(
|
||||
sqle,
|
||||
"could not lock: " + MessageHelper.infoString( lockable, id, session.getFactory() ),
|
||||
sql
|
||||
sqle,
|
||||
"could not lock: " + MessageHelper.infoString( lockable, id, session.getFactory() ),
|
||||
sql
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
protected String generateLockString() {
|
||||
SessionFactoryImplementor factory = lockable.getFactory();
|
||||
Update update = new Update( factory.getDialect() );
|
||||
final SessionFactoryImplementor factory = lockable.getFactory();
|
||||
final Update update = new Update( factory.getDialect() );
|
||||
update.setTableName( lockable.getRootTableName() );
|
||||
update.addPrimaryKeyColumns( lockable.getRootTableIdentifierColumnNames() );
|
||||
update.setVersionColumnName( lockable.getVersionColumnName() );
|
||||
|
@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Support for Dialect-specific locking strategies
|
||||
*/
|
||||
package org.hibernate.dialect.lock;
|
@ -25,10 +25,12 @@ public AbstractLimitHandler(String sql, RowSelection selection) {
|
||||
this.selection = selection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLimit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLimitOffset() {
|
||||
return supportsLimit();
|
||||
}
|
||||
@ -112,20 +114,24 @@ public int convertToFirstRowValue(int zeroBasedFirstResult) {
|
||||
return zeroBasedFirstResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProcessedSql() {
|
||||
throw new UnsupportedOperationException( "Paged queries not supported by " + getClass().getName() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bindLimitParametersAtStartOfQuery(PreparedStatement statement, int index)
|
||||
throws SQLException {
|
||||
return bindLimitParametersFirst() ? bindLimitParameters( statement, index ) : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bindLimitParametersAtEndOfQuery(PreparedStatement statement, int index)
|
||||
throws SQLException {
|
||||
return !bindLimitParametersFirst() ? bindLimitParameters( statement, index ) : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxRows(PreparedStatement statement) throws SQLException {
|
||||
}
|
||||
|
||||
@ -142,10 +148,10 @@ protected int bindLimitParameters(PreparedStatement statement, int index)
|
||||
if ( !supportsVariableLimit() || !LimitHelper.hasMaxRows( selection ) ) {
|
||||
return 0;
|
||||
}
|
||||
int firstRow = convertToFirstRowValue( LimitHelper.getFirstRow( selection ) );
|
||||
int lastRow = getMaxOrLimit();
|
||||
boolean hasFirstRow = supportsLimitOffset() && ( firstRow > 0 || forceLimitUsage() );
|
||||
boolean reverse = bindLimitParametersInReverseOrder();
|
||||
final int firstRow = convertToFirstRowValue( LimitHelper.getFirstRow( selection ) );
|
||||
final int lastRow = getMaxOrLimit();
|
||||
final boolean hasFirstRow = supportsLimitOffset() && ( firstRow > 0 || forceLimitUsage() );
|
||||
final boolean reverse = bindLimitParametersInReverseOrder();
|
||||
if ( hasFirstRow ) {
|
||||
statement.setInt( index + ( reverse ? 1 : 0 ), firstRow );
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user