HHH-14153 optimize away temp table for single-table HQL update
When a HQL bulk update query only touches a single table, use BasicExecutor instead of MultiTableUpdateExecutor. This is an alternate implementation to the one proposed by @NathanQingyangXu in #3508 and loosely based on that work.
This commit is contained in:
parent
59d40c3bf5
commit
d1119d320a
|
@ -141,7 +141,7 @@ public class HqlSqlWalker extends HqlSqlBaseWalker implements ErrorReporter, Par
|
|||
private ArrayList<ParameterSpecification> parameterSpecs = new ArrayList<>();
|
||||
private int numberOfParametersInSetClause;
|
||||
|
||||
private ArrayList assignmentSpecifications = new ArrayList();
|
||||
private ArrayList<AssignmentSpecification> assignmentSpecifications = new ArrayList<>();
|
||||
|
||||
private JoinType impliedJoinType = JoinType.INNER_JOIN;
|
||||
|
||||
|
@ -1393,7 +1393,7 @@ public class HqlSqlWalker extends HqlSqlBaseWalker implements ErrorReporter, Par
|
|||
}
|
||||
}
|
||||
|
||||
public ArrayList getAssignmentSpecifications() {
|
||||
public ArrayList<AssignmentSpecification> getAssignmentSpecifications() {
|
||||
return assignmentSpecifications;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,8 @@ import antlr.RecognitionException;
|
|||
import antlr.TokenStreamException;
|
||||
import antlr.collections.AST;
|
||||
|
||||
import static java.util.Collections.singleton;
|
||||
|
||||
/**
|
||||
* A QueryTranslator that uses an Antlr-based parser.
|
||||
*
|
||||
|
@ -609,10 +611,10 @@ public class QueryTranslatorImpl implements FilterTranslator {
|
|||
else if ( walker.getStatementType() == HqlSqlTokenTypes.UPDATE ) {
|
||||
final FromElement fromElement = walker.getFinalFromClause().getFromElement();
|
||||
final Queryable persister = fromElement.getQueryable();
|
||||
if ( persister.isMultiTable() ) {
|
||||
// even here, if only properties mapped to the "base table" are referenced
|
||||
// in the set and where clauses, this could be handled by the BasicDelegate.
|
||||
// TODO : decide if it is better performance-wise to doAfterTransactionCompletion that check, or to simply use the MultiTableUpdateDelegate
|
||||
|
||||
boolean affectsExtraTables = persister.isMultiTable()
|
||||
&& !singleton( persister.getTableName() ).containsAll( walker.getQuerySpaces() );
|
||||
if ( affectsExtraTables ) {
|
||||
return new MultiTableUpdateExecutor( walker );
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.hibernate.engine.spi.QueryParameters;
|
|||
import org.hibernate.engine.spi.RowSelection;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
import org.hibernate.hql.internal.antlr.HqlSqlTokenTypes;
|
||||
import org.hibernate.hql.internal.ast.HqlSqlWalker;
|
||||
import org.hibernate.hql.internal.ast.QuerySyntaxException;
|
||||
import org.hibernate.hql.internal.ast.SqlGenerator;
|
||||
|
@ -40,7 +41,16 @@ public class BasicExecutor implements StatementExecutor {
|
|||
try {
|
||||
SqlGenerator gen = new SqlGenerator( walker.getSessionFactoryHelper().getFactory() );
|
||||
gen.statement( walker.getAST() );
|
||||
if ( walker.getStatementType() == HqlSqlTokenTypes.UPDATE ) {
|
||||
// workaround for a problem where HqlSqlWalker actually generates
|
||||
// broken SQL with undefined aliases in the where clause, because
|
||||
// that is what MultiTableUpdateExecutor is expecting to get
|
||||
String alias = walker.getFinalFromClause().getFromElement().getTableAlias();
|
||||
sql = gen.getSQL().replace( alias + ".", "" );
|
||||
}
|
||||
else {
|
||||
sql = gen.getSQL();
|
||||
}
|
||||
gen.getParseErrorHandler().throwQueryException();
|
||||
parameterSpecifications = gen.getCollectedParameters();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue