[hibernate-commits] Hibernate SVN: r15305 - in core/trunk: core/src/main/java/org/hibernate/hql/ast and 1 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Thu Oct 9 13:23:32 EDT 2008


Author: steve.ebersole at jboss.com
Date: 2008-10-09 13:23:32 -0400 (Thu, 09 Oct 2008)
New Revision: 15305

Modified:
   core/trunk/core/src/main/java/org/hibernate/dialect/DB2Dialect.java
   core/trunk/core/src/main/java/org/hibernate/dialect/Dialect.java
   core/trunk/core/src/main/java/org/hibernate/hql/ast/HqlSqlWalker.java
   core/trunk/testsuite/src/test/java/org/hibernate/test/hql/BulkManipulationTest.java
Log:
HHH-3519 : parameters in select clause

Modified: core/trunk/core/src/main/java/org/hibernate/dialect/DB2Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/DB2Dialect.java	2008-10-09 15:48:03 UTC (rev 15304)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/DB2Dialect.java	2008-10-09 17:23:32 UTC (rev 15305)
@@ -374,12 +374,28 @@
 		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() {
-		// DB2 known to not support parameters within the select
-		// clause of an SQL INSERT ... SELECT ... statement
-		return false;
+		return true;
 	}
 
+	/**
+	 * 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() {
 		return false;
 	}

Modified: core/trunk/core/src/main/java/org/hibernate/dialect/Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/Dialect.java	2008-10-09 15:48:03 UTC (rev 15304)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/Dialect.java	2008-10-09 17:23:32 UTC (rev 15305)
@@ -1617,8 +1617,8 @@
 	}
 
 	/**
-	 * Does this dialect support parameters within the select clause of
-	 * INSERT ... SELECT ... statements?
+	 * Does this dialect support parameters within the <tt>SELECT</tt> clause of
+	 * <tt>INSERT ... SELECT ...</tt> statements?
 	 *
 	 * @return True if this is supported; false otherwise.
 	 * @since 3.2
@@ -1628,6 +1628,17 @@
 	}
 
 	/**
+	 * Does this dialect require that parameters appearing in the <tt>SELECT</tt> clause be wrapped in <tt>cast()</tt>
+	 * calls to tell the db parser the expected type.
+	 *
+	 * @return True if select clause parameter must be cast()ed
+	 * @since 3.2
+	 */
+	public boolean requiresCastingOfParametersInSelectClause() {
+		return false;
+	}
+
+	/**
 	 * 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

Modified: core/trunk/core/src/main/java/org/hibernate/hql/ast/HqlSqlWalker.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/HqlSqlWalker.java	2008-10-09 15:48:03 UTC (rev 15304)
+++ core/trunk/core/src/main/java/org/hibernate/hql/ast/HqlSqlWalker.java	2008-10-09 17:23:32 UTC (rev 15305)
@@ -683,10 +683,38 @@
 			AST versionValueNode = null;
 
 			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, "?" );
 				ParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification( versionType );
 				( ( ParameterNode ) versionValueNode ).setHqlParameterSpecification( paramSpec );
 				parameters.add( 0, paramSpec );
+
+				if ( sessionFactoryHelper.getFactory().getDialect().requiresCastingOfParametersInSelectClause() ) {
+					// we need to wrtap the param in a cast()
+					MethodNode versionMethodNode = ( MethodNode ) getASTFactory().create( HqlSqlTokenTypes.METHOD_CALL, "(" );
+					AST methodIdentNode = getASTFactory().create( HqlSqlTokenTypes.IDENT, "cast" );
+					versionMethodNode.addChild( methodIdentNode );
+					versionMethodNode.initializeMethodNode(methodIdentNode, true );
+					AST castExprListNode = getASTFactory().create( HqlSqlTokenTypes.EXPR_LIST, "exprList" );
+					methodIdentNode.setNextSibling( castExprListNode );
+					castExprListNode.addChild( versionValueNode );
+					versionValueNode.setNextSibling(
+							getASTFactory().create(
+									HqlSqlTokenTypes.IDENT,
+									sessionFactoryHelper.getFactory().getDialect().getTypeName( sqlTypes[0] ) )
+					);
+					processFunction( versionMethodNode, true );
+					versionValueNode = versionMethodNode;
+				}
 			}
 			else {
 				if ( isIntegral( versionType ) ) {

Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/hql/BulkManipulationTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/hql/BulkManipulationTest.java	2008-10-09 15:48:03 UTC (rev 15304)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/hql/BulkManipulationTest.java	2008-10-09 17:23:32 UTC (rev 15305)
@@ -415,11 +415,13 @@
 			reportSkip( "bulk id generation not supported", "test bulk inserts with generated id and generated timestamp");
 			return;
 		}
+
 		// 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
 		// db-based.
-		if ( !getDialect().supportsParametersInInsertSelect() ) {
-			reportSkip( "dialect does not support parameter in INSERT ... SELECT", "test bulk inserts with generated id and generated timestamp");
+		if ( ! getDialect().supportsParametersInInsertSelect() ) {
+			reportSkip( "dialect does not support parameter in INSERT ... SELECT",
+				"test bulk inserts with generated id and generated timestamp");
 			return;
 		}
 




More information about the hibernate-commits mailing list