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) {
|
private SqmExpression<?> visitFinalFunctionArgument(HqlParser.ExpressionContext expression) {
|
||||||
// the final argument to a function may accept multi-value parameter (varargs),
|
// the final argument to a function may accept multi-value parameter (varargs),
|
||||||
// but only if we are operating in non-strict JPA mode
|
// but only if we are operating in non-strict JPA mode
|
||||||
parameterDeclarationContextStack.push( creationOptions::useStrictJpaCompliance );
|
parameterDeclarationContextStack.push( () -> !creationOptions.useStrictJpaCompliance() );
|
||||||
try {
|
try {
|
||||||
return (SqmExpression<?>) expression.accept( this );
|
return (SqmExpression<?>) expression.accept( this );
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.util.List;
|
||||||
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
|
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
|
||||||
import org.hibernate.query.sqm.NodeBuilder;
|
import org.hibernate.query.sqm.NodeBuilder;
|
||||||
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
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.sql.SqmToSqlAstConverter;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmDistinct;
|
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.SqmTypedNode;
|
||||||
import org.hibernate.query.sqm.tree.SqmVisitableNode;
|
import org.hibernate.query.sqm.tree.SqmVisitableNode;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmFunction;
|
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.SqlAstNode;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
@ -60,8 +62,22 @@ public class SelfRenderingSqmFunction<T> extends SqmFunction<T> {
|
||||||
|
|
||||||
final ArrayList<SqlAstNode> sqlAstArguments = new ArrayList<>( sqmArguments.size() );
|
final ArrayList<SqlAstNode> sqlAstArguments = new ArrayList<>( sqmArguments.size() );
|
||||||
for ( SqmTypedNode<?> sqmArgument : sqmArguments ) {
|
for ( SqmTypedNode<?> sqmArgument : sqmArguments ) {
|
||||||
|
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 ) );
|
sqlAstArguments.add( (SqlAstNode) ( (SqmVisitableNode) sqmArgument ).accept( walker ) );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sqlAstArguments.add( (SqlAstNode) ( (SqmVisitableNode) sqmArgument ).accept( walker ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
return sqlAstArguments;
|
return sqlAstArguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4943,4 +4943,34 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
return selection;
|
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;
|
package org.hibernate.query.sqm.sql;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.internal.util.collections.Stack;
|
import org.hibernate.internal.util.collections.Stack;
|
||||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
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.spi.SqlAstCreationState;
|
||||||
import org.hibernate.sql.ast.Clause;
|
import org.hibernate.sql.ast.Clause;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specialized SemanticQueryWalker (SQM visitor) for producing SQL AST.
|
* 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 {
|
public interface SqmToSqlAstConverter extends SemanticQueryWalker<Object>, SqlAstCreationState {
|
||||||
Stack<Clause> getCurrentClauseStack();
|
Stack<Clause> getCurrentClauseStack();
|
||||||
|
|
||||||
|
List<Expression> expandSelfRenderingFunctionMultiValueParameter(SqmParameter sqmParameter);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue