Fix multi value parameters expansion for SelfRenderingSqmFunction
This commit is contained in:
parent
3f7044eebe
commit
ab8cfe0d83
|
@ -3006,7 +3006,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
private SqmExpression<?> visitFinalFunctionArgument(HqlParser.ExpressionContext expression) {
|
||||
// the final argument to a function may accept multi-value parameter (varargs),
|
||||
// but only if we are operating in non-strict JPA mode
|
||||
parameterDeclarationContextStack.push( creationOptions::useStrictJpaCompliance );
|
||||
parameterDeclarationContextStack.push( () -> !creationOptions.useStrictJpaCompliance() );
|
||||
try {
|
||||
return (SqmExpression<?>) expression.accept( this );
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.util.List;
|
|||
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
|
||||
import org.hibernate.query.sqm.NodeBuilder;
|
||||
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
||||
import org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter;
|
||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmDistinct;
|
||||
|
|
|
@ -17,7 +17,9 @@ import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
|||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||
import org.hibernate.query.sqm.tree.SqmVisitableNode;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmFunction;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmParameter;
|
||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
|
@ -60,7 +62,21 @@ public class SelfRenderingSqmFunction<T> extends SqmFunction<T> {
|
|||
|
||||
final ArrayList<SqlAstNode> sqlAstArguments = new ArrayList<>( sqmArguments.size() );
|
||||
for ( SqmTypedNode<?> sqmArgument : sqmArguments ) {
|
||||
sqlAstArguments.add( (SqlAstNode) ( (SqmVisitableNode) sqmArgument ).accept( walker ) );
|
||||
if ( sqmArgument instanceof SqmParameter ) {
|
||||
final SqmParameter sqmParameter = (SqmParameter) sqmArgument;
|
||||
if ( sqmParameter.allowMultiValuedBinding() ) {
|
||||
final List<Expression> expressions = walker.expandSelfRenderingFunctionMultiValueParameter( sqmParameter );
|
||||
for ( int i = 0; i < expressions.size(); i++ ) {
|
||||
sqlAstArguments.add( expressions.get( i ) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
sqlAstArguments.add( (SqlAstNode) ( (SqmVisitableNode) sqmArgument ).accept( walker ) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
sqlAstArguments.add( (SqlAstNode) ( (SqmVisitableNode) sqmArgument ).accept( walker ) );
|
||||
}
|
||||
}
|
||||
return sqlAstArguments;
|
||||
}
|
||||
|
|
|
@ -4943,4 +4943,34 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
return selection;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Expression> expandSelfRenderingFunctionMultiValueParameter(SqmParameter sqmParameter) {
|
||||
assert sqmParameter.allowMultiValuedBinding();
|
||||
final QueryParameterImplementor<?> domainParam = domainParameterXref.getQueryParameter(
|
||||
sqmParameter );
|
||||
final QueryParameterBinding domainParamBinding = domainParameterBindings.getBinding(
|
||||
domainParam );
|
||||
|
||||
final Collection bindValues = domainParamBinding.getBindValues();
|
||||
final int bindValuesSize = bindValues.size();
|
||||
final List<Expression> result = new ArrayList<>( bindValuesSize );
|
||||
|
||||
boolean first = true;
|
||||
for ( int i = 0; i < bindValuesSize; i++ ) {
|
||||
final SqmParameter sqmParamToConsume;
|
||||
// for each bind value create an "expansion"
|
||||
if ( first ) {
|
||||
sqmParamToConsume = sqmParameter;
|
||||
first = false;
|
||||
}
|
||||
else {
|
||||
sqmParamToConsume = sqmParameter.copy();
|
||||
domainParameterXref.addExpansion( domainParam, sqmParameter, sqmParamToConsume );
|
||||
}
|
||||
final Expression expression = consumeSqmParameter( sqmParamToConsume );
|
||||
result.add( expression );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,14 @@
|
|||
*/
|
||||
package org.hibernate.query.sqm.sql;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.internal.util.collections.Stack;
|
||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmParameter;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||
import org.hibernate.sql.ast.Clause;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
|
||||
/**
|
||||
* Specialized SemanticQueryWalker (SQM visitor) for producing SQL AST.
|
||||
|
@ -18,4 +22,7 @@ import org.hibernate.sql.ast.Clause;
|
|||
*/
|
||||
public interface SqmToSqlAstConverter extends SemanticQueryWalker<Object>, SqlAstCreationState {
|
||||
Stack<Clause> getCurrentClauseStack();
|
||||
|
||||
List<Expression> expandSelfRenderingFunctionMultiValueParameter(SqmParameter sqmParameter);
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue