Author: steve.ebersole(a)jboss.com
Date: 2006-12-08 11:06:14 -0500 (Fri, 08 Dec 2006)
New Revision: 10963
Modified:
trunk/Hibernate3/src/org/hibernate/dialect/Cache71Dialect.java
trunk/Hibernate3/src/org/hibernate/dialect/DB2Dialect.java
trunk/Hibernate3/src/org/hibernate/dialect/DerbyDialect.java
trunk/Hibernate3/src/org/hibernate/dialect/Dialect.java
trunk/Hibernate3/src/org/hibernate/dialect/H2Dialect.java
trunk/Hibernate3/src/org/hibernate/dialect/HSQLDialect.java
trunk/Hibernate3/src/org/hibernate/dialect/IngresDialect.java
trunk/Hibernate3/src/org/hibernate/dialect/MySQLDialect.java
trunk/Hibernate3/src/org/hibernate/dialect/Oracle9Dialect.java
trunk/Hibernate3/src/org/hibernate/dialect/PostgreSQLDialect.java
trunk/Hibernate3/src/org/hibernate/dialect/SQLServerDialect.java
trunk/Hibernate3/src/org/hibernate/dialect/SybaseDialect.java
trunk/Hibernate3/src/org/hibernate/dialect/TimesTenDialect.java
trunk/Hibernate3/test/org/hibernate/test/TestCase.java
Log:
HHH-2286 : dialect informational metadata;
javadoc and code cleanup
Modified: trunk/Hibernate3/src/org/hibernate/dialect/Cache71Dialect.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/dialect/Cache71Dialect.java 2006-12-08 13:03:52 UTC
(rev 10962)
+++ trunk/Hibernate3/src/org/hibernate/dialect/Cache71Dialect.java 2006-12-08 16:06:14 UTC
(rev 10963)
@@ -634,4 +634,19 @@
return extractUsingTemplate( "constraint (", ") violated",
sqle.getMessage() );
}
};
+
+
+ // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public boolean supportsEmptyInList() {
+ return false;
+ }
+
+ public boolean areStringComparisonsCaseInsensitive() {
+ return true;
+ }
+
+ public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() {
+ return false;
+ }
}
Modified: trunk/Hibernate3/src/org/hibernate/dialect/DB2Dialect.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/dialect/DB2Dialect.java 2006-12-08 13:03:52 UTC
(rev 10962)
+++ trunk/Hibernate3/src/org/hibernate/dialect/DB2Dialect.java 2006-12-08 16:06:14 UTC
(rev 10963)
@@ -360,4 +360,10 @@
public String getCurrentTimestampSQLFunctionName() {
return "sysdate";
}
+
+ // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public boolean supportsEmptyInList() {
+ return false;
+ }
}
Modified: trunk/Hibernate3/src/org/hibernate/dialect/DerbyDialect.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/dialect/DerbyDialect.java 2006-12-08 13:03:52 UTC
(rev 10962)
+++ trunk/Hibernate3/src/org/hibernate/dialect/DerbyDialect.java 2006-12-08 16:06:14 UTC
(rev 10963)
@@ -128,8 +128,8 @@
// 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 = null; // the trim-character
- String trimSource = null; // the trim-source
+ String trimCharacter; // the trim-character
+ String trimSource; // the trim-source
// potentialTrimCharacterArgIndex = 1 assumes that a
// trim-specification has been specified. we handle the
@@ -167,8 +167,7 @@
}
}
- List argsToUse = null;
- argsToUse = new ArrayList();
+ List argsToUse = new ArrayList();
argsToUse.add( trimSource );
argsToUse.add( trimCharacter );
@@ -189,4 +188,16 @@
}
}
}
+
+
+ // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public boolean supportsExpectedLobUsagePattern() {
+ // My attempts on Derby show this not working with CLOBs or BLOBs.
+ // An example of the error message I get with CLOBs is:
+ // A truncation error was encountered trying to shrink CLOB
'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&' to length
255.
+ //
+ // I highly suspect this would be the case with all DB2 variant databases...
+ return false;
+ }
}
Modified: trunk/Hibernate3/src/org/hibernate/dialect/Dialect.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/dialect/Dialect.java 2006-12-08 13:03:52 UTC (rev
10962)
+++ trunk/Hibernate3/src/org/hibernate/dialect/Dialect.java 2006-12-08 16:06:14 UTC (rev
10963)
@@ -1164,16 +1164,6 @@
}
/**
- * Should LOBs (both BLOB and CLOB) be bound using stream operations (i.e.
- * {@link java.sql.PreparedStatement#setBinaryStream}).
- *
- * @return True if BLOBs and CLOBs should be bound using stream operations.
- */
- public boolean useInputStreamToInsertBlob() {
- return true;
- }
-
- /**
* Meant as a means for end users to affect the select strings being sent
* to the database and perhaps manipulate them in some fashion.
* <p/>
@@ -1206,33 +1196,7 @@
return bool ? "1" : "0";
}
- /**
- * Does this dialect support parameters within the select clause of
- * INSERT ... SELECT ... statements?
- *
- * @return True if this is supported; false otherwise.
- */
- public boolean supportsParametersInInsertSelect() {
- return true;
- }
- /**
- * Is this dialect known to support what ANSI-SQL terms "row value
- * constructor" syntax; sometimes called tuple syntax.
- * <p/>
- * Basically, does it support syntax like
- * "... where (FIRST_NAME, LAST_NAME) = ('Steve', 'Ebersole')
...".
- *
- * @return True if this SQL dialect is known to support "row value
- * constructor" syntax; false otherwise.
- * @since 3.2
- */
- public boolean supportsRowValueConstructorSyntax() {
- // return false here, as most databases do not properly support this construct...
- return false;
- }
-
-
// identifier quoting support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
@@ -1323,6 +1287,8 @@
/**
* The syntax used to add a column to a table (optional).
+ *
+ * @return The "add column" fragment.
*/
public String getAddColumnString() {
throw new UnsupportedOperationException( "No add column syntax supported by
Dialect" );
@@ -1340,31 +1306,35 @@
/**
* The syntax used to add a foreign key constraint to a table.
*
+ * @param constraintName The FK constraint name.
+ * @param foreignKey The names of the columns comprising the FK
+ * @param referencedTable The table referenced by the FK
+ * @param primaryKey The explicit columns in the referencedTable referenced
+ * by this FK.
* @param referencesPrimaryKey if false, constraint should be
* explicit about which column names the constraint refers to
*
- * @return String
+ * @return the "add FK" fragment
*/
public String getAddForeignKeyConstraintString(
String constraintName,
String[] foreignKey,
String referencedTable,
String[] primaryKey,
- boolean referencesPrimaryKey
- ) {
+ boolean referencesPrimaryKey) {
StringBuffer res = new StringBuffer( 30 );
res.append( " add constraint " )
- .append( constraintName )
- .append( " foreign key (" )
- .append( StringHelper.join( ", ", foreignKey ) )
- .append( ") references " )
- .append( referencedTable );
+ .append( constraintName )
+ .append( " foreign key (" )
+ .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();
@@ -1373,7 +1343,8 @@
/**
* The syntax used to add a primary key constraint to a table.
*
- * @return String
+ * @param constraintName The name of the PK constraint.
+ * @return The "add PK" fragment
*/
public String getAddPrimaryKeyConstraintString(String constraintName) {
return " add constraint " + constraintName + " primary key ";
@@ -1414,6 +1385,9 @@
/**
* Does this dialect support column-level check constraints?
+ *
+ * @return True if column-level CHECK constraints are supported; false
+ * otherwise.
*/
public boolean supportsColumnCheck() {
return true;
@@ -1421,6 +1395,9 @@
/**
* Does this dialect support table-level check constraints?
+ *
+ * @return True if table-level CHECK constraints are supported; false
+ * otherwise.
*/
public boolean supportsTableCheck() {
return true;
@@ -1443,4 +1420,211 @@
return "";
}
+
+ // Informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ /**
+ * Does this dialect support empty IN lists?
+ * <p/>
+ * For example, is [where XYZ in ()] a supported construct?
+ *
+ * @return True if empty in lists are supported; false otherwise.
+ * @since 3.2
+ */
+ public boolean supportsEmptyInList() {
+ return true;
+ }
+
+ /**
+ * Are string comparisons implicitly case insensitive.
+ * <p/>
+ * In other words, does [where 'XYZ' = 'xyz'] resolve to true?
+ *
+ * @return True if comparisons are case insensitive.
+ * @since 3.2
+ */
+ public boolean areStringComparisonsCaseInsensitive() {
+ return false;
+ }
+
+ /**
+ * Is this dialect known to support what ANSI-SQL terms "row value
+ * constructor" syntax; sometimes called tuple syntax.
+ * <p/>
+ * Basically, does it support syntax like
+ * "... where (FIRST_NAME, LAST_NAME) = ('Steve', 'Ebersole')
...".
+ *
+ * @return True if this SQL dialect is known to support "row value
+ * constructor" syntax; false otherwise.
+ * @since 3.2
+ */
+ public boolean supportsRowValueConstructorSyntax() {
+ // return false here, as most databases do not properly support this construct...
+ return false;
+ }
+
+ /**
+ * If the dialect supports {@link #supportsRowValueConstructorSyntax() row values},
+ * does it offer such support in IN lists as well?
+ * <p/>
+ * For example, "... where (FIRST_NAME, LAST_NAME) IN ( (?, ?), (?, ?) ) ..."
+ *
+ * @return True if this SQL dialect is known to support "row value
+ * constructor" syntax in the IN list; false otherwise.
+ * @since 3.2
+ */
+ public boolean supportsRowValueConstructorSyntaxInInList() {
+ return false;
+ }
+
+ /**
+ * Should LOBs (both BLOB and CLOB) be bound using stream operations (i.e.
+ * {@link java.sql.PreparedStatement#setBinaryStream}).
+ *
+ * @return True if BLOBs and CLOBs should be bound using stream operations.
+ * @since 3.2
+ */
+ public boolean useInputStreamToInsertBlob() {
+ return true;
+ }
+
+ /**
+ * Does this dialect support parameters within the select clause of
+ * INSERT ... SELECT ... statements?
+ *
+ * @return True if this is supported; false otherwise.
+ * @since 3.2
+ */
+ public boolean supportsParametersInInsertSelect() {
+ return true;
+ }
+
+ /**
+ * Does this dialect support asking the result set its positioning
+ * information on forward only cursors. Specifically, in the case of
+ * scrolling fetches, Hibernate needs to use
+ * {@link java.sql.ResultSet#isAfterLast} and
+ * {@link java.sql.ResultSet#isBeforeFirst}. Certain drivers do not
+ * allow access to these methods for forward only cursors.
+ * <p/>
+ * NOTE : this is highly driver dependent!
+ *
+ * @return True if methods like {@link java.sql.ResultSet#isAfterLast} and
+ * {@link java.sql.ResultSet#isBeforeFirst} are supported for forward
+ * only cursors; false otherwise.
+ * @since 3.2
+ */
+ public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() {
+ return true;
+ }
+
+ /**
+ * Does this dialect support definition of cascade delete constraints
+ * which can cause circular chains?
+ *
+ * @return True if circular cascade delete constraints are supported; false
+ * otherwise.
+ * @since 3.2
+ */
+ public boolean supportsCircularCascadeDeleteConstraints() {
+ return true;
+ }
+
+ /**
+ * Are subselects supported as the left-hand-side (LHS) of
+ * IN-predicates.
+ * <p/>
+ * In other words, is syntax like "... <subquery> IN (1, 2, 3) ..."
supported?
+ *
+ * @return True if subselects can appear as the LHS of an in-predicate;
+ * false otherwise.
+ * @since 3.2
+ */
+ public boolean supportsSubselectAsInPredicateLHS() {
+ return true;
+ }
+
+ /**
+ * Expected LOB usage pattern is such that I can perform an insert
+ * via prepared statement with a parameter binding for a LOB value
+ * without crazy casting to JDBC driver implementation-specific classes...
+ * <p/>
+ * Part of the trickiness here is the fact that this is largely
+ * driver dependent. For example, Oracle (which is notoriously bad with
+ * LOB support in their drivers historically) actually does a pretty good
+ * job with LOB support as of the 10.2.x versions of their drivers...
+ *
+ * @return True if normal LOB usage patterns can be used with this driver;
+ * false if driver-specific hookiness needs to be applied.
+ * @since 3.2
+ */
+ public boolean supportsExpectedLobUsagePattern() {
+ return true;
+ }
+
+ /**
+ * Does the dialect support propogating changes to LOB
+ * values back to the database? Talking about mutating the
+ * internal value of the locator as opposed to supplying a new
+ * locator instance...
+ * <p/>
+ * For BLOBs, the internal value might be changed by:
+ * {@link java.sql.Blob#setBinaryStream},
+ * {@link java.sql.Blob#setBytes(long, byte[])},
+ * {@link java.sql.Blob#setBytes(long, byte[], int, int)},
+ * or {@link java.sql.Blob#truncate(long)}.
+ * <p/>
+ * For CLOBs, the internal value might be changed by:
+ * {@link java.sql.Clob#setAsciiStream(long)},
+ * {@link java.sql.Clob#setCharacterStream(long)},
+ * {@link java.sql.Clob#setString(long, String)},
+ * {@link java.sql.Clob#setString(long, String, int, int)},
+ * or {@link java.sql.Clob#truncate(long)}.
+ * <p/>
+ * NOTE : I do not know the correct answer currently for
+ * databases which (1) are not part of the cruise control process
+ * or (2) do not {@link #supportsExpectedLobUsagePattern}.
+ *
+ * @return True if the changes are propogated back to the
+ * database; false otherwise.
+ * @since 3.2
+ */
+ public boolean supportsLobValueChangePropogation() {
+ return true;
+ }
+
+ /**
+ * Is it supported to materialize a LOB locator outside the transaction in
+ * which it was created?
+ * <p/>
+ * Again, part of the trickiness here is the fact that this is largely
+ * driver dependent.
+ * <p/>
+ * NOTE: all database I have tested which {@link #supportsExpectedLobUsagePattern()}
+ * also support the ability to materialize a LOB outside the owning transaction...
+ *
+ * @return True if unbounded materialization is supported; false otherwise.
+ * @since 3.2
+ */
+ public boolean supportsUnboundedLobLocatorMaterialization() {
+ return true;
+ }
+
+ /**
+ * Does this dialect support referencing the table being mutated in
+ * a subquery. The "table being mutated" is the table referenced in
+ * an UPDATE or a DELETE query. And so can that table then be
+ * referenced in a subquery of said UPDATE/DELETE query.
+ * <p/>
+ * For example, would the following two syntaxes be supported:<ul>
+ * <li>delete from TABLE_A where ID not in ( select ID from TABLE_A )</li>
+ * <li>update TABLE_A set NON_ID = 'something' where ID in ( select ID
from TABLE_A)</li>
+ * </ul>
+ *
+ * @return True if this dialect allows references the mutating table from
+ * a subquery.
+ */
+ public boolean supportsSubqueryOnMutatingTable() {
+ return true;
+ }
}
Modified: trunk/Hibernate3/src/org/hibernate/dialect/H2Dialect.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/dialect/H2Dialect.java 2006-12-08 13:03:52 UTC (rev
10962)
+++ trunk/Hibernate3/src/org/hibernate/dialect/H2Dialect.java 2006-12-08 16:06:14 UTC (rev
10963)
@@ -275,4 +275,10 @@
return true;
}
+
+ // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public boolean supportsLobValueChangePropogation() {
+ return false;
+ }
}
\ No newline at end of file
Modified: trunk/Hibernate3/src/org/hibernate/dialect/HSQLDialect.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/dialect/HSQLDialect.java 2006-12-08 13:03:52 UTC
(rev 10962)
+++ trunk/Hibernate3/src/org/hibernate/dialect/HSQLDialect.java 2006-12-08 16:06:14 UTC
(rev 10963)
@@ -303,4 +303,15 @@
super.lock( id, version, object, session );
}
}
+
+
+ // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public boolean supportsEmptyInList() {
+ return false;
+ }
+
+ public boolean supportsLobValueChangePropogation() {
+ return false;
+ }
}
Modified: trunk/Hibernate3/src/org/hibernate/dialect/IngresDialect.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/dialect/IngresDialect.java 2006-12-08 13:03:52 UTC
(rev 10962)
+++ trunk/Hibernate3/src/org/hibernate/dialect/IngresDialect.java 2006-12-08 16:06:14 UTC
(rev 10963)
@@ -12,11 +12,11 @@
/**
* An Ingres SQL dialect.
- *
+ * <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 31 digits in decimal
- *
+ *
* @author Ian Booth, Bruce Lunsford, Max Rydahl Andersen
*/
public class IngresDialect extends Dialect {
@@ -48,32 +48,32 @@
registerColumnType( Types.BLOB, "long byte" );
registerColumnType( Types.CLOB, "long varchar" );
- registerFunction( "abs", new StandardSQLFunction("abs") );
+ registerFunction( "abs", new StandardSQLFunction( "abs" ) );
registerFunction( "atan", new StandardSQLFunction( "atan",
Hibernate.DOUBLE ) );
- registerFunction( "bit_add", new StandardSQLFunction("bit_add") );
- registerFunction( "bit_and", new StandardSQLFunction("bit_and") );
- registerFunction( "bit_length", new
StandardSQLFunction("bit_length") );
- registerFunction( "bit_not", new StandardSQLFunction("bit_not") );
- registerFunction( "bit_or", new StandardSQLFunction("bit_or") );
- registerFunction( "bit_xor", new StandardSQLFunction("bit_xor") );
+ registerFunction( "bit_add", new StandardSQLFunction( "bit_add" )
);
+ registerFunction( "bit_and", new StandardSQLFunction( "bit_and" )
);
+ registerFunction( "bit_length", new StandardSQLFunction(
"bit_length" ) );
+ registerFunction( "bit_not", new StandardSQLFunction( "bit_not" )
);
+ registerFunction( "bit_or", new StandardSQLFunction( "bit_or" ) );
+ registerFunction( "bit_xor", new StandardSQLFunction( "bit_xor" )
);
registerFunction( "character_length", new StandardSQLFunction(
"character_length", Hibernate.LONG ) );
registerFunction( "charextract", new StandardSQLFunction(
"charextract", Hibernate.STRING ) );
- registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING,
"(","+",")" ) );
+ registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING,
"(", "+", ")" ) );
registerFunction( "cos", new StandardSQLFunction( "cos",
Hibernate.DOUBLE ) );
registerFunction( "current_user", new NoArgSQLFunction(
"current_user", Hibernate.STRING, false ) );
- registerFunction( "current_time", new
NoArgSQLFunction("date('now')", Hibernate.TIMESTAMP, false) );
- registerFunction( "current_timestamp", new
NoArgSQLFunction("date('now')", Hibernate.TIMESTAMP, false) );
- registerFunction( "current_date", new
NoArgSQLFunction("date('now')", Hibernate.TIMESTAMP, false) );
+ registerFunction( "current_time", new NoArgSQLFunction(
"date('now')", Hibernate.TIMESTAMP, false ) );
+ registerFunction( "current_timestamp", new NoArgSQLFunction(
"date('now')", Hibernate.TIMESTAMP, false ) );
+ registerFunction( "current_date", new NoArgSQLFunction(
"date('now')", Hibernate.TIMESTAMP, false ) );
registerFunction( "date_trunc", new StandardSQLFunction(
"date_trunc", Hibernate.TIMESTAMP ) );
- registerFunction( "day", new StandardSQLFunction("day",
Hibernate.INTEGER) );
+ registerFunction( "day", new StandardSQLFunction( "day",
Hibernate.INTEGER ) );
registerFunction( "dba", new NoArgSQLFunction( "dba",
Hibernate.STRING, true ) );
registerFunction( "dow", new StandardSQLFunction( "dow",
Hibernate.STRING ) );
registerFunction( "extract", new SQLFunctionTemplate( Hibernate.INTEGER,
"date_part('?1', ?3)" ) );
registerFunction( "exp", new StandardSQLFunction( "exp",
Hibernate.DOUBLE ) );
- registerFunction( "gmt_timestamp", new StandardSQLFunction(
"gmt_timestamp", Hibernate.STRING ) );
+ registerFunction( "gmt_timestamp", new StandardSQLFunction(
"gmt_timestamp", Hibernate.STRING ) );
registerFunction( "hash", new StandardSQLFunction( "hash",
Hibernate.INTEGER ) );
registerFunction( "hex", new StandardSQLFunction( "hex",
Hibernate.STRING ) );
- registerFunction( "hour", new StandardSQLFunction("hour",
Hibernate.INTEGER) );
+ registerFunction( "hour", new StandardSQLFunction( "hour",
Hibernate.INTEGER ) );
registerFunction( "initial_user", new NoArgSQLFunction(
"initial_user", Hibernate.STRING, false ) );
registerFunction( "intextract", new StandardSQLFunction(
"intextract", Hibernate.INTEGER ) );
registerFunction( "left", new StandardSQLFunction( "left",
Hibernate.STRING ) );
@@ -81,10 +81,10 @@
registerFunction( "length", new StandardSQLFunction( "length",
Hibernate.LONG ) );
registerFunction( "ln", new StandardSQLFunction( "ln",
Hibernate.DOUBLE ) );
registerFunction( "log", new StandardSQLFunction( "log",
Hibernate.DOUBLE ) );
- registerFunction( "lower", new StandardSQLFunction("lower") );
- registerFunction( "lowercase", new StandardSQLFunction("lowercase")
);
- registerFunction( "minute", new StandardSQLFunction("minute",
Hibernate.INTEGER) );
- registerFunction( "month", new StandardSQLFunction("month",
Hibernate.INTEGER) );
+ registerFunction( "lower", new StandardSQLFunction( "lower" ) );
+ registerFunction( "lowercase", new StandardSQLFunction( "lowercase"
) );
+ registerFunction( "minute", new StandardSQLFunction( "minute",
Hibernate.INTEGER ) );
+ registerFunction( "month", new StandardSQLFunction( "month",
Hibernate.INTEGER ) );
registerFunction( "octet_length", new StandardSQLFunction(
"octet_length", Hibernate.LONG ) );
registerFunction( "pad", new StandardSQLFunction( "pad",
Hibernate.STRING ) );
registerFunction( "position", new StandardSQLFunction( "position",
Hibernate.LONG ) );
@@ -93,18 +93,18 @@
registerFunction( "randomf", new NoArgSQLFunction( "randomf",
Hibernate.DOUBLE, true ) );
registerFunction( "right", new StandardSQLFunction( "right",
Hibernate.STRING ) );
registerFunction( "session_user", new NoArgSQLFunction(
"session_user", Hibernate.STRING, false ) );
- registerFunction( "second", new StandardSQLFunction("second",
Hibernate.INTEGER) );
+ registerFunction( "second", new StandardSQLFunction( "second",
Hibernate.INTEGER ) );
registerFunction( "size", new NoArgSQLFunction( "size",
Hibernate.LONG, true ) );
- registerFunction( "squeeze", new StandardSQLFunction("squeeze") );
+ registerFunction( "squeeze", new StandardSQLFunction( "squeeze" )
);
registerFunction( "sin", new StandardSQLFunction( "sin",
Hibernate.DOUBLE ) );
registerFunction( "soundex", new StandardSQLFunction( "soundex",
Hibernate.STRING ) );
registerFunction( "sqrt", new StandardSQLFunction( "sqrt",
Hibernate.DOUBLE ) );
registerFunction( "substring", new SQLFunctionTemplate( Hibernate.STRING,
"substring(?1 FROM ?2 FOR ?3)" ) );
registerFunction( "system_user", new NoArgSQLFunction(
"system_user", Hibernate.STRING, false ) );
- registerFunction( "trim", new StandardSQLFunction("trim",
Hibernate.STRING ) );
+ registerFunction( "trim", new StandardSQLFunction( "trim",
Hibernate.STRING ) );
registerFunction( "unhex", new StandardSQLFunction( "unhex",
Hibernate.STRING ) );
- registerFunction( "upper", new StandardSQLFunction("upper") );
- registerFunction( "uppercase", new StandardSQLFunction("uppercase")
);
+ registerFunction( "upper", new StandardSQLFunction( "upper" ) );
+ registerFunction( "uppercase", new StandardSQLFunction( "uppercase"
) );
registerFunction( "user", new NoArgSQLFunction( "user",
Hibernate.STRING, false ) );
registerFunction( "usercode", new NoArgSQLFunction( "usercode",
Hibernate.STRING, true ) );
registerFunction( "username", new NoArgSQLFunction( "username",
Hibernate.STRING, true ) );
@@ -112,42 +112,47 @@
registerFunction( "uuid_compare", new StandardSQLFunction(
"uuid_compare", Hibernate.INTEGER ) );
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) );
+ registerFunction( "year", new StandardSQLFunction( "year",
Hibernate.INTEGER ) );
}
-
+
/**
* Do we need to drop constraints before dropping tables in this dialect?
+ *
* @return boolean
*/
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).
*/
public String getAddColumnString() {
return "add column";
}
-
+
/**
* The keyword used to specify a nullable column.
+ *
* @return String
*/
public String getNullColumnString() {
return " with null";
}
-
+
/**
* Does this dialect support sequences?
+ *
* @return boolean
*/
public boolean supportsSequences() {
@@ -156,9 +161,10 @@
/**
* The syntax that fetches the next value of a sequence, if sequences are supported.
+ *
* @param sequenceName the name of the sequence
+ *
* @return String
- * @throws MappingException if no sequences
*/
public String getSequenceNextValString(String sequenceName) {
return "select nextval for " + sequenceName;
@@ -166,9 +172,10 @@
/**
* The syntax used to create a sequence, if sequences are supported.
+ *
* @param sequenceName the name of the sequence
+ *
* @return String
- * @throws MappingException if no sequences
*/
public String getCreateSequenceString(String sequenceName) {
return "create sequence " + sequenceName;
@@ -176,9 +183,10 @@
/**
* The syntax used to drop a sequence, if sequences are supported.
+ *
* @param sequenceName the name of the sequence
+ *
* @return String
- * @throws MappingException if no sequences
*/
public String getDropSequenceString(String sequenceName) {
return "drop sequence " + sequenceName + " restrict";
@@ -190,49 +198,50 @@
public String getQuerySequencesString() {
return "select seq_name from iisequence";
}
-
+
/**
- * The name of the SQL function that transforms a string to
+ * The name of the SQL function that transforms a string to
* lowercase
- *
+ *
* @return String
*/
public String getLowercaseFunction() {
return "lowercase";
}
-
+
/**
* Does this <tt>Dialect</tt> have some kind of <tt>LIMIT</tt>
syntax?
*/
public boolean supportsLimit() {
return true;
}
-
+
/**
* Does this dialect support an offset?
*/
public boolean supportsLimitOffset() {
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) {
- if (offset > 0) {
+ if ( offset > 0 ) {
throw new UnsupportedOperationException( "offset not supported" );
}
- return new StringBuffer( querySelect.length()+16 )
- .append(querySelect)
- .insert(6, " first " + limit )
- .toString();
+ return new StringBuffer( querySelect.length() + 16 )
+ .append( querySelect )
+ .insert( 6, " first " + limit )
+ .toString();
}
public boolean supportsVariableLimit() {
return false;
}
-
+
/**
* Does the <tt>LIMIT</tt> clause take a "maximum" row number
instead
* of a total number of returned rows?
@@ -240,6 +249,7 @@
public boolean useMaxForLimit() {
return true;
}
+
/**
* Ingres explicitly needs "unique not null", because "with null" is
default
*/
@@ -249,7 +259,7 @@
/**
* Does this dialect support temporary tables?
- */
+ */
public boolean supportsTemporaryTables() {
return true;
}
@@ -263,14 +273,20 @@
}
public String generateTemporaryTableName(String baseTableName) {
- return "session." + super.generateTemporaryTableName(baseTableName);
+ return "session." + super.generateTemporaryTableName( baseTableName );
}
-
+
/**
* Expression for current_timestamp
*/
public String getCurrentTimestampSQLFunctionName() {
return "date(now)";
}
+
+ // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public boolean supportsSubselectAsInPredicateLHS() {
+ return false;
+ }
}
Modified: trunk/Hibernate3/src/org/hibernate/dialect/MySQLDialect.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/dialect/MySQLDialect.java 2006-12-08 13:03:52 UTC
(rev 10962)
+++ trunk/Hibernate3/src/org/hibernate/dialect/MySQLDialect.java 2006-12-08 16:06:14 UTC
(rev 10963)
@@ -317,8 +317,7 @@
while (!isResultSet && ps.getUpdateCount() != -1) {
isResultSet = ps.getMoreResults();
}
- ResultSet rs = ps.getResultSet();
- return rs;
+ return ps.getResultSet();
}
public boolean supportsRowValueConstructorSyntax() {
@@ -328,4 +327,24 @@
public Boolean performTemporaryTableDDLInIsolation() {
return Boolean.FALSE;
}
+
+
+ // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public boolean supportsEmptyInList() {
+ return false;
+ }
+
+ public boolean areStringComparisonsCaseInsensitive() {
+ return true;
+ }
+
+ public boolean supportsLobValueChangePropogation() {
+ // note: at least my local MySQL 5.1 install shows this not working...
+ return false;
+ }
+
+ public boolean supportsSubqueryOnMutatingTable() {
+ return false;
+ }
}
\ No newline at end of file
Modified: trunk/Hibernate3/src/org/hibernate/dialect/Oracle9Dialect.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/dialect/Oracle9Dialect.java 2006-12-08 13:03:52 UTC
(rev 10962)
+++ trunk/Hibernate3/src/org/hibernate/dialect/Oracle9Dialect.java 2006-12-08 16:06:14 UTC
(rev 10963)
@@ -282,8 +282,7 @@
public ResultSet getResultSet(CallableStatement ps) throws SQLException {
ps.execute();
- ResultSet rs = (ResultSet) ps.getObject(1);
- return rs;
+ return ( ResultSet ) ps.getObject( 1 );
}
public boolean supportsUnionAll() {
@@ -326,4 +325,19 @@
public boolean isCurrentTimestampSelectStringCallable() {
return false;
}
+
+
+ // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public boolean supportsEmptyInList() {
+ return false;
+ }
+
+ public boolean supportsRowValueConstructorSyntax() {
+ return true;
+ }
+
+ public boolean supportsRowValueConstructorSyntaxInInList() {
+ return true;
+ }
}
Modified: trunk/Hibernate3/src/org/hibernate/dialect/PostgreSQLDialect.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/dialect/PostgreSQLDialect.java 2006-12-08 13:03:52
UTC (rev 10962)
+++ trunk/Hibernate3/src/org/hibernate/dialect/PostgreSQLDialect.java 2006-12-08 16:06:14
UTC (rev 10963)
@@ -293,7 +293,14 @@
}
};
+
+ // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
public boolean supportsRowValueConstructorSyntax() {
return true;
}
+
+ public boolean supportsEmptyInList() {
+ return false;
+ }
}
Modified: trunk/Hibernate3/src/org/hibernate/dialect/SQLServerDialect.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/dialect/SQLServerDialect.java 2006-12-08 13:03:52
UTC (rev 10962)
+++ trunk/Hibernate3/src/org/hibernate/dialect/SQLServerDialect.java 2006-12-08 16:06:14
UTC (rev 10963)
@@ -2,22 +2,16 @@
package org.hibernate.dialect;
import java.sql.Types;
-import java.util.List;
-import java.util.ArrayList;
import org.hibernate.Hibernate;
import org.hibernate.LockMode;
-import org.hibernate.QueryException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.type.Type;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.StandardSQLFunction;
-import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.dialect.function.AnsiTrimEmulationFunction;
/**
- * A dialect for Microsoft SQL Server 2000
+ * A dialect for Microsoft SQL Server 2000 and 2005
+ *
* @author Gavin King
*/
public class SQLServerDialect extends SybaseDialect {
@@ -111,4 +105,26 @@
return "select current_timestamp";
}
+
+ // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public boolean areStringComparisonsCaseInsensitive() {
+ return true;
+ }
+
+ public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() {
+ return false;
+ }
+
+ public boolean supportsCircularCascadeDeleteConstraints() {
+ // SQL Server (at least up through 2005) does not support defining
+ // cascade delete constraints which can circel back to the mutating
+ // table
+ return false;
+ }
+
+ public boolean supportsLobValueChangePropogation() {
+ // note: at least my local SQL Server 2005 Express shows this not working...
+ return false;
+ }
}
Modified: trunk/Hibernate3/src/org/hibernate/dialect/SybaseDialect.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/dialect/SybaseDialect.java 2006-12-08 13:03:52 UTC
(rev 10962)
+++ trunk/Hibernate3/src/org/hibernate/dialect/SybaseDialect.java 2006-12-08 16:06:14 UTC
(rev 10963)
@@ -144,17 +144,16 @@
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();
+ 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;
+ 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
+ return ps.getResultSet();
}
public boolean supportsCurrentTimestampSelection() {
@@ -180,4 +179,11 @@
public boolean dropTemporaryTableAfterUse() {
return true; // sql-server, at least needed this dropped after use; strange!
}
+
+
+ // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public boolean supportsEmptyInList() {
+ return false;
+ }
}
Modified: trunk/Hibernate3/src/org/hibernate/dialect/TimesTenDialect.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/dialect/TimesTenDialect.java 2006-12-08 13:03:52
UTC (rev 10962)
+++ trunk/Hibernate3/src/org/hibernate/dialect/TimesTenDialect.java 2006-12-08 16:06:14
UTC (rev 10963)
@@ -148,17 +148,13 @@
return true;
}
- private static int getAfterSelectInsertPoint(String sql) {
- return 6; //sql.startsWith("select distinct") ? 15 : 6;
- }
-
public String getLimitString(String querySelect, int offset, int limit) {
if ( offset > 0 ) {
throw new UnsupportedOperationException( "TimesTen does not support offset"
);
}
return new StringBuffer( querySelect.length()+8 )
.append(querySelect)
- .insert( getAfterSelectInsertPoint(querySelect), " first " + limit )
+ .insert( 6, " first " + limit )
.toString();
}
@@ -200,4 +196,10 @@
return new SelectLockingStrategy( lockable, lockMode );
}
}
+
+ // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public boolean supportsEmptyInList() {
+ return false;
+ }
}
Modified: trunk/Hibernate3/test/org/hibernate/test/TestCase.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/TestCase.java 2006-12-08 13:03:52 UTC (rev
10962)
+++ trunk/Hibernate3/test/org/hibernate/test/TestCase.java 2006-12-08 16:06:14 UTC (rev
10963)
@@ -20,17 +20,7 @@
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.DB2Dialect;
import org.hibernate.dialect.Dialect;
-import org.hibernate.dialect.HSQLDialect;
-import org.hibernate.dialect.IngresDialect;
-import org.hibernate.dialect.MySQLDialect;
-import org.hibernate.dialect.Oracle9Dialect;
-import org.hibernate.dialect.PostgreSQLDialect;
-import org.hibernate.dialect.SQLServerDialect;
-import org.hibernate.dialect.SybaseDialect;
-import org.hibernate.dialect.TimesTenDialect;
import org.hibernate.dialect.DerbyDialect;
-import org.hibernate.dialect.Cache71Dialect;
-import org.hibernate.dialect.H2Dialect;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
@@ -482,24 +472,11 @@
* @return true if is allowed
*/
protected boolean dialectSupportsEmptyInList(String testDescription) {
- boolean canDoIt = dialectIsNot(
- new Class[] {
- Oracle9Dialect.class,
- MySQLDialect.class,
- DB2Dialect.class,
- HSQLDialect.class,
- SQLServerDialect.class,
- SybaseDialect.class,
- PostgreSQLDialect.class,
- TimesTenDialect.class,
- Cache71Dialect.class
- }
- );
-
- if ( !canDoIt ) {
- reportSkip( "Dialect does not support SQL: \'x in ()\'.",
testDescription );
+ if ( ! getDialect().supportsEmptyInList() ) {
+ reportSkip( "Dialect does not support SQL empty in list : x in ()",
testDescription );
+ return false;
}
- return canDoIt;
+ return true;
}
/**
@@ -508,34 +485,23 @@
* @return true if sensitive
*/
protected boolean dialectIsCaseSensitive(String testDescription) {
- // MySQL and SQLServer is case insensitive on strings (at least in default
installation)
- boolean canDoIt = dialectIsNot(
- new Class[] { MySQLDialect.class, SQLServerDialect.class, Cache71Dialect.class }
- );
-
- if ( !canDoIt ) {
+ if ( getDialect().areStringComparisonsCaseInsensitive() ) {
reportSkip( "Dialect is case sensitive. ", testDescription );
+ return true;
}
- return canDoIt;
+ return false;
}
protected boolean supportsRowValueConstructorSyntaxInInList() {
- boolean supported = ! (getDialect() instanceof HSQLDialect ||
- getDialect() instanceof PostgreSQLDialect ||
- getDialect() instanceof MySQLDialect ||
- getDialect() instanceof DB2Dialect ||
- getDialect() instanceof SybaseDialect ||
- getDialect() instanceof Cache71Dialect
- );
-
- if ( !supported ) {
+ if ( ! getDialect().supportsRowValueConstructorSyntaxInInList() ) {
reportSkip( "Dialect does not support 'tuple' syntax as part of an IN
value list", "query support" );
+ return false;
}
- return supported;
+ return true;
}
protected boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() {
- if ( getDialect() instanceof SQLServerDialect || getDialect() instanceof Cache71Dialect
) {
+ if ( ! getDialect().supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() ) {
reportSkip( "Driver does not support 'position query' methods on
forward-only cursors", "query support" );
return false;
}
@@ -543,7 +509,7 @@
}
protected boolean supportsCircularCascadeDelete() {
- if ( getDialect() instanceof SQLServerDialect ) {
+ if ( ! getDialect().supportsCircularCascadeDeleteConstraints() ) {
reportSkip( "db/dialect does not support 'circular' cascade delete
constraints", "cascade delete constraint support" );
return false;
}
@@ -551,12 +517,11 @@
}
protected boolean supportsSubselectOnLeftSideIn() {
- if (dialectIsNot( IngresDialect.class )) {
- return true;
- } else {
+ if ( ! getDialect().supportsSubselectAsInPredicateLHS() ) {
reportSkip( "Database does not support (<subselect>) in ( ... ) ",
"query support" );
return false;
}
+ return true;
}
/**
@@ -572,9 +537,7 @@
* @return True if expected usage pattern is support; false otherwise.
*/
protected boolean supportsExpectedLobUsagePattern() {
- // note : For Derby, the insertions get truncated...
- Class[] exceptions = new Class[] { DerbyDialect.class };
- if ( dialectIsOneOf( exceptions ) ) {
+ if ( ! getDialect().supportsExpectedLobUsagePattern() ) {
reportSkip( "database/driver does not support expected LOB usage pattern",
"LOB support" );
return false;
}
@@ -591,12 +554,7 @@
* database; false otherwise.
*/
protected boolean supportsLobValueChangePropogation() {
- // note: at least my local MySQL 5.1 install shows this not working...
- // note: at least my local SQL Server 2005 Express shows this not working...
- Class[] exceptions = new Class[] {
- HSQLDialect.class, H2Dialect.class, MySQLDialect.class, SQLServerDialect.class
- };
- if ( dialectIsOneOf( exceptions ) ) {
+ if ( ! getDialect().supportsLobValueChangePropogation() ) {
reportSkip( "database/driver does not support propogating LOB value change back
to database", "LOB support" );
return false;
}
@@ -616,8 +574,7 @@
* @return True if unbounded materialization is supported; false otherwise.
*/
protected boolean supportsUnboundedLobLocatorMaterialization() {
- Class[] exceptions = new Class[] { }; // none known of...
- if ( dialectIsOneOf( exceptions ) ) {
+ if ( !getDialect().supportsUnboundedLobLocatorMaterialization() ) {
reportSkip( "database/driver does not support materializing a LOB locator outside
the 'owning' transaction", "LOB support" );
return false;
}
@@ -625,19 +582,18 @@
}
protected boolean supportsSubqueryOnMutatingTable() {
- // I only know of MySQL having this limitation...
- return dialectIsNot( MySQLDialect.class );
+ if ( !getDialect().supportsSubqueryOnMutatingTable() ) {
+ reportSkip( "database/driver does not support referencing mutating table in
subquery", "bulk DML support" );
+ return false;
+ }
+ return true;
}
- private boolean dialectIs(Class dialectClass) {
+ protected boolean dialectIs(Class dialectClass) {
return dialectClass.isInstance( getDialect() );
}
- private boolean dialectIsNot(Class dialectClass) {
- return ! dialectIs( dialectClass );
- }
-
- private boolean dialectIsOneOf(Class[] dialectClasses) {
+ protected boolean dialectIsOneOf(Class[] dialectClasses) {
for ( int i = 0; i < dialectClasses.length; i++ ) {
if ( dialectClasses[i].isInstance( getDialect() ) ) {
return true;
@@ -646,7 +602,11 @@
return false;
}
- private boolean dialectIsNot(Class[] dialectClasses) {
+ protected boolean dialectIsNot(Class dialectClass) {
+ return ! dialectIs( dialectClass );
+ }
+
+ protected boolean dialectIsNot(Class[] dialectClasses) {
return ! dialectIsOneOf( dialectClasses );
}