Least-effort fix for HHH-2692
Conflicts: hibernate-core/src/main/java/org/hibernate/hql/ast/HqlSqlWalker.java hibernate-core/src/main/java/org/hibernate/hql/ast/tree/IntoClause.java hibernate-core/src/main/java/org/hibernate/hql/ast/tree/SelectExpressionList.java hibernate-core/src/test/java/org/hibernate/test/hql/BulkManipulationTest.java
This commit is contained in:
parent
51deee1e66
commit
9304c2b3e9
|
@ -409,6 +409,7 @@ selectExpr
|
||||||
| collectionFunction // elements() or indices()
|
| collectionFunction // elements() or indices()
|
||||||
| literal
|
| literal
|
||||||
| arithmeticExpr
|
| arithmeticExpr
|
||||||
|
| parameter
|
||||||
| query
|
| query
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -246,7 +246,7 @@ selectExpr
|
||||||
| aggregate
|
| aggregate
|
||||||
| c:constant { out(c); }
|
| c:constant { out(c); }
|
||||||
| arithmeticExpr
|
| arithmeticExpr
|
||||||
| param:PARAM { out(param); }
|
| parameter
|
||||||
| sn:SQL_NODE { out(sn); }
|
| sn:SQL_NODE { out(sn); }
|
||||||
| { out("("); } selectStatement { out(")"); }
|
| { out("("); } selectStatement { out(")"); }
|
||||||
;
|
;
|
||||||
|
|
|
@ -36,12 +36,6 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import antlr.ASTFactory;
|
|
||||||
import antlr.RecognitionException;
|
|
||||||
import antlr.SemanticException;
|
|
||||||
import antlr.collections.AST;
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.QueryException;
|
import org.hibernate.QueryException;
|
||||||
import org.hibernate.engine.internal.JoinSequence;
|
import org.hibernate.engine.internal.JoinSequence;
|
||||||
|
@ -104,6 +98,12 @@ import org.hibernate.type.DbTimestampType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
import org.hibernate.type.VersionType;
|
import org.hibernate.type.VersionType;
|
||||||
import org.hibernate.usertype.UserVersionType;
|
import org.hibernate.usertype.UserVersionType;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import antlr.ASTFactory;
|
||||||
|
import antlr.RecognitionException;
|
||||||
|
import antlr.SemanticException;
|
||||||
|
import antlr.collections.AST;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements methods used by the HQL->SQL tree transform grammar (a.k.a. the second phase).
|
* Implements methods used by the HQL->SQL tree transform grammar (a.k.a. the second phase).
|
||||||
|
@ -775,6 +775,20 @@ public class HqlSqlWalker extends HqlSqlBaseWalker implements ErrorReporter, Par
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect() ) {
|
||||||
|
AST child = selectClause.getFirstChild();
|
||||||
|
int i = 0;
|
||||||
|
while(child != null) {
|
||||||
|
if(child instanceof ParameterNode) {
|
||||||
|
// infer the parameter type from the type listed in the INSERT INTO clause
|
||||||
|
((ParameterNode)child).setExpectedType(insertStatement.getIntoClause()
|
||||||
|
.getInsertionTypes()[selectClause.getParameterPositions().get(i)]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
child = child.getNextSibling();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final boolean includeVersionProperty = persister.isVersioned() &&
|
final boolean includeVersionProperty = persister.isVersioned() &&
|
||||||
!insertStatement.getIntoClause().isExplicitVersionInsertion() &&
|
!insertStatement.getIntoClause().isExplicitVersionInsertion() &&
|
||||||
persister.isVersionPropertyInsertable();
|
persister.isVersionPropertyInsertable();
|
||||||
|
|
|
@ -116,12 +116,16 @@ public class IntoClause extends HqlSqlWalkerNode implements DisplayableNode {
|
||||||
|
|
||||||
public void validateTypes(SelectClause selectClause) throws QueryException {
|
public void validateTypes(SelectClause selectClause) throws QueryException {
|
||||||
Type[] selectTypes = selectClause.getQueryReturnTypes();
|
Type[] selectTypes = selectClause.getQueryReturnTypes();
|
||||||
if ( selectTypes.length != types.length ) {
|
if ( selectTypes.length + selectClause.getTotalParameterCount() != types.length ) {
|
||||||
throw new QueryException( "number of select types did not match those for insert" );
|
throw new QueryException( "number of select types did not match those for insert" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int parameterCount = 0;
|
||||||
for ( int i = 0; i < types.length; i++ ) {
|
for ( int i = 0; i < types.length; i++ ) {
|
||||||
if ( !areCompatible( types[i], selectTypes[i] ) ) {
|
if( selectClause.getParameterPositions().contains(i) ) {
|
||||||
|
parameterCount++;
|
||||||
|
}
|
||||||
|
else if ( !areCompatible( types[i], selectTypes[i - parameterCount] ) ) {
|
||||||
throw new QueryException(
|
throw new QueryException(
|
||||||
"insertion type [" + types[i] + "] and selection type [" +
|
"insertion type [" + types[i] + "] and selection type [" +
|
||||||
selectTypes[i] + "] at position " + i + " are not compatible"
|
selectTypes[i] + "] at position " + i + " are not compatible"
|
||||||
|
|
|
@ -24,18 +24,22 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.hql.internal.ast.tree;
|
package org.hibernate.hql.internal.ast.tree;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import antlr.collections.AST;
|
|
||||||
|
|
||||||
import org.hibernate.hql.internal.antlr.SqlTokenTypes;
|
import org.hibernate.hql.internal.antlr.SqlTokenTypes;
|
||||||
import org.hibernate.hql.internal.ast.util.ASTPrinter;
|
import org.hibernate.hql.internal.ast.util.ASTPrinter;
|
||||||
|
|
||||||
|
import antlr.collections.AST;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common behavior - a node that contains a list of select expressions.
|
* Common behavior - a node that contains a list of select expressions.
|
||||||
*
|
*
|
||||||
* @author josh
|
* @author josh
|
||||||
*/
|
*/
|
||||||
public abstract class SelectExpressionList extends HqlSqlWalkerNode {
|
public abstract class SelectExpressionList extends HqlSqlWalkerNode {
|
||||||
|
|
||||||
|
private List<Integer> parameterPositions = new ArrayList<Integer>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of SelectExpressions gathered from the children of the given parent AST node.
|
* Returns an array of SelectExpressions gathered from the children of the given parent AST node.
|
||||||
*
|
*
|
||||||
|
@ -47,17 +51,40 @@ public abstract class SelectExpressionList extends HqlSqlWalkerNode {
|
||||||
AST firstChild = getFirstSelectExpression();
|
AST firstChild = getFirstSelectExpression();
|
||||||
AST parent = this;
|
AST parent = this;
|
||||||
ArrayList list = new ArrayList( parent.getNumberOfChildren() );
|
ArrayList list = new ArrayList( parent.getNumberOfChildren() );
|
||||||
|
int p = 0;
|
||||||
for ( AST n = firstChild; n != null; n = n.getNextSibling() ) {
|
for ( AST n = firstChild; n != null; n = n.getNextSibling() ) {
|
||||||
if ( n instanceof SelectExpression ) {
|
if ( n instanceof SelectExpression ) {
|
||||||
list.add( n );
|
list.add( n );
|
||||||
}
|
}
|
||||||
|
else if( n instanceof ParameterNode ) {
|
||||||
|
parameterPositions.add(p);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
throw new IllegalStateException( "Unexpected AST: " + n.getClass().getName() + " " + new ASTPrinter( SqlTokenTypes.class ).showAsString( n, "" ) );
|
throw new IllegalStateException( "Unexpected AST: " + n.getClass().getName() + " " + new ASTPrinter( SqlTokenTypes.class ).showAsString( n, "" ) );
|
||||||
}
|
}
|
||||||
|
p++;
|
||||||
}
|
}
|
||||||
return ( SelectExpression[] ) list.toArray( new SelectExpression[list.size()] );
|
return ( SelectExpression[] ) list.toArray( new SelectExpression[list.size()] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The total number of parameter projections of this expression.
|
||||||
|
*
|
||||||
|
* @return The number of parameters in this select clause.
|
||||||
|
*/
|
||||||
|
public int getTotalParameterCount() {
|
||||||
|
return parameterPositions.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The position of parameters within the list of select expressions of this clause
|
||||||
|
*
|
||||||
|
* @return a list of positions representing the mapping from order of occurence to position
|
||||||
|
*/
|
||||||
|
public List<Integer> getParameterPositions() {
|
||||||
|
return parameterPositions;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the first select expression node that should be considered when building the array of select
|
* Returns the first select expression node that should be considered when building the array of select
|
||||||
* expressions.
|
* expressions.
|
||||||
|
|
|
@ -209,6 +209,30 @@ public class BulkManipulationTest extends BaseCoreFunctionalTestCase {
|
||||||
data.cleanup();
|
data.cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimpleInsertWithNamedParam() {
|
||||||
|
TestData data = new TestData();
|
||||||
|
data.prepare();
|
||||||
|
|
||||||
|
Session s = openSession();
|
||||||
|
Transaction t = s.beginTransaction();
|
||||||
|
|
||||||
|
org.hibernate.Query q = s.createQuery( "insert into Pickup (id, owner, vin) select id, :owner, vin from Car" );
|
||||||
|
q.setParameter("owner", "owner");
|
||||||
|
|
||||||
|
q.executeUpdate();
|
||||||
|
|
||||||
|
t.commit();
|
||||||
|
t = s.beginTransaction();
|
||||||
|
|
||||||
|
s.createQuery( "delete Vehicle" ).executeUpdate();
|
||||||
|
|
||||||
|
t.commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
data.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSimpleNativeSQLInsert() {
|
public void testSimpleNativeSQLInsert() {
|
||||||
TestData data = new TestData();
|
TestData data = new TestData();
|
||||||
|
|
Loading…
Reference in New Issue