HHH-4931 improve Ingres dialect supports
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18948 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
5aa0138ec2
commit
e699570e60
|
@ -0,0 +1,22 @@
|
|||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.function.NoArgSQLFunction;
|
||||
|
||||
/**
|
||||
* A SQL dialect for Ingres 10 and later versions.
|
||||
*
|
||||
* Changes:
|
||||
* <ul>
|
||||
* </ul>
|
||||
*
|
||||
* @author Raymond Fan
|
||||
*/
|
||||
public class Ingres10Dialect extends Ingres9Dialect {
|
||||
public Ingres10Dialect() {
|
||||
super();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,215 @@
|
|||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.dialect.function.NoArgSQLFunction;
|
||||
|
||||
/**
|
||||
* A SQL dialect for Ingres 9.3 and later versions.
|
||||
* <p />
|
||||
* Changes:
|
||||
* <ul>
|
||||
* <li>Support for the SQL functions current_time, current_timestamp and current_date added</li>
|
||||
* <li>Type mapping of <code>Types.TIMESTAMP</code> changed from "timestamp with time zone" to "timestamp(9) with time zone"</li>
|
||||
* <li>Improved handling of "SELECT...FOR UPDATE" statements</li>
|
||||
* <li>Added support for pooled sequences</li>
|
||||
* <li>Added support for SELECT queries with limit and offset</li>
|
||||
* <li>Added getIdentitySelectString</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Enrico Schenk, Raymond Fan
|
||||
*/
|
||||
public class Ingres9Dialect extends IngresDialect {
|
||||
public Ingres9Dialect() {
|
||||
super();
|
||||
registerDateTimeFunctions();
|
||||
registerDateTimeColumnTypes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register functions current_time, current_timestamp, current_date
|
||||
*/
|
||||
protected void registerDateTimeFunctions() {
|
||||
registerFunction("current_time", new NoArgSQLFunction("current_time", Hibernate.TIME, false));
|
||||
registerFunction("current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP, false));
|
||||
registerFunction("current_date", new NoArgSQLFunction("current_date", Hibernate.DATE, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register column types date, time, timestamp
|
||||
*/
|
||||
protected void registerDateTimeColumnTypes() {
|
||||
registerColumnType(Types.DATE, "ansidate");
|
||||
//registerColumnType(Types.TIME, "time with time zone");
|
||||
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>.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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()";
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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)
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
public boolean supportsCurrentTimestampSelection() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the command used to retrieve the current timestamp from the
|
||||
* database.
|
||||
*
|
||||
* @return The command.
|
||||
*/
|
||||
public String getCurrentTimestampSelectString() {
|
||||
return "select current_timestamp";
|
||||
}
|
||||
|
||||
/**
|
||||
* Expression for current_timestamp
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
public boolean doesRepeatableReadCauseReadersToBlockWriters() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// limit/offset support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
* Does this dialect's LIMIT support (if any) additionally support
|
||||
* specifying an offset?
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
public boolean supportsLimitOffset() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this dialect support bind variables (i.e., prepared statement
|
||||
* parameters) for its limit/offset?
|
||||
*
|
||||
* @return false
|
||||
*/
|
||||
public boolean supportsVariableLimit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a <tt>LIMIT</tt> clause to the given SQL <tt>SELECT</tt>
|
||||
*
|
||||
* @return the modified SQL
|
||||
*/
|
||||
public String getLimitString(String querySelect, int offset, int limit) {
|
||||
StringBuffer sb = new StringBuffer(querySelect.length() + 16);
|
||||
sb.append(querySelect.trim()).insert(6, " first " + limit);
|
||||
if (offset > 0) {
|
||||
sb.append(" offset " + offset);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -27,6 +27,7 @@ package org.hibernate.dialect;
|
|||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.function.SQLFunctionTemplate;
|
||||
import org.hibernate.dialect.function.NoArgSQLFunction;
|
||||
import org.hibernate.dialect.function.StandardSQLFunction;
|
||||
|
@ -36,9 +37,12 @@ import org.hibernate.dialect.function.VarArgsSQLFunction;
|
|||
* An SQL dialect for Ingres 9.2.
|
||||
* <p/>
|
||||
* Known limitations:
|
||||
* - only supports simple constants or columns on the left side of an IN, making (1,2,3) in (...) or (<subselect>) in (...) non-supported
|
||||
* - supports only 39 digits in decimal
|
||||
*
|
||||
* <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.
|
||||
* </ul>
|
||||
*
|
||||
* @author Ian Booth, Bruce Lunsford, Max Rydahl Andersen
|
||||
*/
|
||||
public class IngresDialect extends Dialect {
|
||||
|
@ -135,6 +139,17 @@ public class IngresDialect extends Dialect {
|
|||
registerFunction( "uuid_from_char", new StandardSQLFunction( "uuid_from_char", Hibernate.BYTE ) );
|
||||
registerFunction( "uuid_to_char", new StandardSQLFunction( "uuid_to_char", Hibernate.STRING ) );
|
||||
registerFunction( "year", new StandardSQLFunction( "year", Hibernate.INTEGER ) );
|
||||
// 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");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,6 +35,8 @@ import org.hibernate.dialect.H2Dialect;
|
|||
import org.hibernate.dialect.MySQLDialect;
|
||||
import org.hibernate.dialect.PostgreSQLDialect;
|
||||
import org.hibernate.dialect.DerbyDialect;
|
||||
import org.hibernate.dialect.Ingres10Dialect;
|
||||
import org.hibernate.dialect.Ingres9Dialect;
|
||||
import org.hibernate.dialect.IngresDialect;
|
||||
import org.hibernate.dialect.SQLServerDialect;
|
||||
import org.hibernate.dialect.InformixDialect;
|
||||
|
@ -78,6 +80,19 @@ public class StandardDialectResolver extends AbstractDialectResolver{
|
|||
}
|
||||
|
||||
if ( "ingres".equalsIgnoreCase( databaseName ) ) {
|
||||
switch( databaseMajorVersion ) {
|
||||
case 9:
|
||||
int databaseMinorVersion = metaData.getDatabaseMinorVersion();
|
||||
if (databaseMinorVersion > 2) {
|
||||
return new Ingres9Dialect();
|
||||
}
|
||||
return new IngresDialect();
|
||||
case 10:
|
||||
log.warn( "Ingres " + databaseMajorVersion + " is not yet fully supported; using Ingres 9.3 dialect" );
|
||||
return new Ingres10Dialect();
|
||||
default:
|
||||
log.warn( "Unknown Ingres major version [" + databaseMajorVersion + "] using Ingres 9.2 dialect" );
|
||||
}
|
||||
return new IngresDialect();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue