HHH-3519 : params in select clause

git-svn-id: https://svn.jboss.org/repos/hibernate/core/branches/Branch_3_2@15293 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Steve Ebersole 2008-10-08 22:59:59 +00:00
parent 969ba9a900
commit a008b898d6
4 changed files with 53 additions and 39 deletions

View File

@ -351,10 +351,26 @@ public boolean isCurrentTimestampSelectStringCallable() {
return false; return false;
} }
/**
* {@inheritDoc}
* <p/>
* DB2 is know to support parameters in the <tt>SELECT</tt> clause, but only in casted form
* (see {@link #requiresCastingOfParametersInSelectClause()}).
*
* @return True.
*/
public boolean supportsParametersInInsertSelect() { public boolean supportsParametersInInsertSelect() {
// DB2 known to not support parameters within the select return true;
// clause of an SQL INSERT ... SELECT ... statement }
return false;
/**
* 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.
*/
public boolean requiresCastingOfParametersInSelectClause() {
return true;
} }
public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() { public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() {

View File

@ -1595,14 +1595,14 @@ public boolean supportsParametersInInsertSelect() {
} }
/** /**
* Does this dialect support casted parameters within the select clause of * Does this dialect require that parameters appearing in the <tt>SELECT</tt> clause be wrapped in <tt>cast()</tt>
* INSERT ... SELECT ... cast( ? as <type> ) statements? * calls to tell the db parser the expected type.
* *
* @return True if this is supported; false otherwise. * @return True if select clause parameter must be cast()ed
* @since 3.2 * @since 3.2
*/ */
public boolean supportsCastedParametersInInsertSelect() { public boolean requiresCastingOfParametersInSelectClause() {
return true; return false;
} }
/** /**

View File

@ -15,7 +15,6 @@
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.hibernate.QueryException; import org.hibernate.QueryException;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.AssertionFailure;
import org.hibernate.engine.JoinSequence; import org.hibernate.engine.JoinSequence;
import org.hibernate.engine.ParameterBinder; import org.hibernate.engine.ParameterBinder;
import org.hibernate.engine.SessionFactoryImplementor; import org.hibernate.engine.SessionFactoryImplementor;
@ -662,38 +661,38 @@ protected void postProcessInsert(AST insert) throws SemanticException, QueryExce
AST versionValueNode = null; AST versionValueNode = null;
if ( sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect() ) { if ( sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect() ) {
int sqlTypes[] = versionType.sqlTypes( sessionFactoryHelper.getFactory() );
if ( sqlTypes == null || sqlTypes.length == 0 ) {
throw new IllegalStateException( versionType.getClass() + ".sqlTypes() returns null or empty array" );
}
if ( sqlTypes.length > 1 ) {
throw new IllegalStateException(
versionType.getClass() +
".sqlTypes() returns > 1 element; only single-valued versions are allowed."
);
}
versionValueNode = getASTFactory().create( HqlSqlTokenTypes.PARAM, "?" ); versionValueNode = getASTFactory().create( HqlSqlTokenTypes.PARAM, "?" );
ParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification( versionType ); ParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification( versionType );
( ( ParameterNode ) versionValueNode ).setHqlParameterSpecification( paramSpec ); ( ( ParameterNode ) versionValueNode ).setHqlParameterSpecification( paramSpec );
parameters.add( 0, paramSpec ); parameters.add( 0, paramSpec );
}
else if ( sessionFactoryHelper.getFactory().getDialect().supportsCastedParametersInInsertSelect() ) { if ( sessionFactoryHelper.getFactory().getDialect().requiresCastingOfParametersInSelectClause() ) {
int sqlTypes[] = versionType.sqlTypes( sessionFactoryHelper.getFactory() ); // we need to wrtap the param in a cast()
if ( sqlTypes == null || sqlTypes.length == 0 ) {
throw new AssertionFailure( versionType.getClass() + "sqlTypes() returns null or empty array" );
}
if ( sqlTypes.length > 1 ) {
throw new UnsupportedOperationException( versionType.getClass() +
".sqlTypes() returns > 1 element; only single-valued versions are allowed." );
}
MethodNode versionMethodNode = ( MethodNode ) getASTFactory().create( HqlSqlTokenTypes.METHOD_CALL, "(" ); MethodNode versionMethodNode = ( MethodNode ) getASTFactory().create( HqlSqlTokenTypes.METHOD_CALL, "(" );
AST methodIdentNode = getASTFactory().create( HqlSqlTokenTypes.IDENT, "cast" ); AST methodIdentNode = getASTFactory().create( HqlSqlTokenTypes.IDENT, "cast" );
versionMethodNode.initializeMethodNode(methodIdentNode, true );
versionMethodNode.addChild( methodIdentNode ); versionMethodNode.addChild( methodIdentNode );
versionMethodNode.initializeMethodNode(methodIdentNode, true );
AST castExprListNode = getASTFactory().create( HqlSqlTokenTypes.EXPR_LIST, "exprList" ); AST castExprListNode = getASTFactory().create( HqlSqlTokenTypes.EXPR_LIST, "exprList" );
methodIdentNode.setNextSibling( castExprListNode ); methodIdentNode.setNextSibling( castExprListNode );
AST paramNode = getASTFactory().create( HqlSqlTokenTypes.PARAM, "?" ); castExprListNode.addChild( versionValueNode );
ParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification( versionType ); versionValueNode.setNextSibling(
( ( ParameterNode ) paramNode ).setHqlParameterSpecification( paramSpec );
castExprListNode.addChild( paramNode );
paramNode.setNextSibling(
getASTFactory().create( getASTFactory().create(
HqlSqlTokenTypes.IDENT, HqlSqlTokenTypes.IDENT,
sessionFactoryHelper.getFactory().getDialect().getTypeName( sqlTypes[0] ) ) sessionFactoryHelper.getFactory().getDialect().getTypeName( sqlTypes[0] ) )
); );
processFunction( versionMethodNode, true ); processFunction( versionMethodNode, true );
versionValueNode = versionMethodNode; versionValueNode = versionMethodNode;
parameters.add( 0, paramSpec ); }
} }
else { else {
if ( isIntegral( versionType ) ) { if ( isIntegral( versionType ) ) {

View File

@ -419,8 +419,7 @@ public void testInsertWithGeneratedTimestampVersion() {
// dialects which do not allow a parameter in the select portion of an INSERT ... SELECT statement // dialects which do not allow a parameter in the select portion of an INSERT ... SELECT statement
// will also be problematic for this test because the timestamp here is vm-based as opposed to // will also be problematic for this test because the timestamp here is vm-based as opposed to
// db-based. // db-based.
if ( !getDialect().supportsParametersInInsertSelect() && if ( ! getDialect().supportsParametersInInsertSelect() ) {
!getDialect().supportsCastedParametersInInsertSelect() ) {
reportSkip( "dialect does not support parameter in INSERT ... SELECT", reportSkip( "dialect does not support parameter in INSERT ... SELECT",
"test bulk inserts with generated id and generated timestamp"); "test bulk inserts with generated id and generated timestamp");
return; return;