use of org.hibernate.query.sqm.sql.internal.SqmParameterInterpretation in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method consumeSqmParameter.
protected Expression consumeSqmParameter(SqmParameter<?> sqmParameter, MappingModelExpressible<?> valueMapping, BiConsumer<Integer, JdbcParameter> jdbcParameterConsumer) {
final List<JdbcParameter> jdbcParametersForSqm = new ArrayList<>();
resolveSqmParameter(sqmParameter, valueMapping, (index, jdbcParameter) -> {
jdbcParameterConsumer.accept(index, jdbcParameter);
jdbcParametersForSqm.add(jdbcParameter);
});
this.jdbcParameters.addParameters(jdbcParametersForSqm);
this.jdbcParamsBySqmParam.computeIfAbsent(sqmParameter, k -> new ArrayList<>(1)).add(jdbcParametersForSqm);
final QueryParameterImplementor<?> queryParameter = domainParameterXref.getQueryParameter(sqmParameter);
final QueryParameterBinding binding = domainParameterBindings.getBinding(queryParameter);
if (binding.setType(valueMapping)) {
replaceJdbcParametersType(sqmParameter, domainParameterXref.getSqmParameters(queryParameter), valueMapping);
}
return new SqmParameterInterpretation(sqmParameter, queryParameter, jdbcParametersForSqm, valueMapping, qp -> binding);
}
use of org.hibernate.query.sqm.sql.internal.SqmParameterInterpretation in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method consumeSingleSqmParameter.
protected Expression consumeSingleSqmParameter(SqmParameter<?> sqmParameter) {
final MappingModelExpressible<?> valueMapping = determineValueMapping(sqmParameter);
final List<JdbcParameter> jdbcParametersForSqm = new ArrayList<>();
resolveSqmParameter(sqmParameter, valueMapping, jdbcParametersForSqm::add);
this.jdbcParameters.addParameters(jdbcParametersForSqm);
this.jdbcParamsBySqmParam.computeIfAbsent(sqmParameter, k -> new ArrayList<>(1)).add(jdbcParametersForSqm);
final QueryParameterImplementor<?> queryParameter = domainParameterXref.getQueryParameter(sqmParameter);
final QueryParameterBinding binding = domainParameterBindings.getBinding(queryParameter);
if (binding.setType(valueMapping)) {
replaceJdbcParametersType(sqmParameter, domainParameterXref.getSqmParameters(queryParameter), valueMapping);
}
return new SqmParameterInterpretation(sqmParameter, queryParameter, jdbcParametersForSqm, valueMapping, qp -> binding);
}
use of org.hibernate.query.sqm.sql.internal.SqmParameterInterpretation in project hibernate-orm by hibernate.
the class AbstractSqlAstTranslator method renderExpressionAsLiteral.
protected void renderExpressionAsLiteral(Expression expression, JdbcParameterBindings jdbcParameterBindings) {
if (expression instanceof Literal) {
expression.accept(this);
return;
} else if (expression instanceof JdbcParameter) {
if (jdbcParameterBindings == null) {
throw new IllegalArgumentException("Can't interpret expression because no parameter bindings are available!");
}
final JdbcParameter parameter = (JdbcParameter) expression;
renderAsLiteral(parameter, getParameterBindValue(parameter));
return;
} else if (expression instanceof SqmParameterInterpretation) {
if (jdbcParameterBindings == null) {
throw new IllegalArgumentException("Can't interpret expression because no parameter bindings are available!");
}
final JdbcParameter parameter = (JdbcParameter) ((SqmParameterInterpretation) expression).getResolvedExpression();
renderAsLiteral(parameter, getParameterBindValue(parameter));
return;
}
throw new UnsupportedOperationException("Can't render expression as literal: " + expression);
}
use of org.hibernate.query.sqm.sql.internal.SqmParameterInterpretation in project hibernate-orm by hibernate.
the class AbstractSqlAstTranslator method visitInListPredicate.
@Override
public void visitInListPredicate(InListPredicate inListPredicate) {
final List<Expression> listExpressions = inListPredicate.getListExpressions();
if (listExpressions.isEmpty()) {
appendSql("1=0");
return;
}
Function<Expression, Expression> itemAccessor = Function.identity();
final SqlTuple lhsTuple;
if ((lhsTuple = SqlTupleContainer.getSqlTuple(inListPredicate.getTestExpression())) != null) {
if (lhsTuple.getExpressions().size() == 1) {
// Special case for tuples with arity 1 as any DBMS supports scalar IN predicates
itemAccessor = listExpression -> SqlTupleContainer.getSqlTuple(listExpression).getExpressions().get(0);
} else if (!supportsRowValueConstructorSyntaxInInList()) {
final ComparisonOperator comparisonOperator = inListPredicate.isNegated() ? ComparisonOperator.NOT_EQUAL : ComparisonOperator.EQUAL;
// Some DBs like Oracle support tuples only for the IN subquery predicate
if (supportsRowValueConstructorSyntaxInInSubQuery() && getDialect().supportsUnionAll()) {
inListPredicate.getTestExpression().accept(this);
if (inListPredicate.isNegated()) {
appendSql(" not");
}
appendSql(" in(");
String separator = NO_SEPARATOR;
for (Expression expression : listExpressions) {
appendSql(separator);
renderExpressionsAsSubquery(SqlTupleContainer.getSqlTuple(expression).getExpressions());
separator = " union all ";
}
appendSql(CLOSE_PARENTHESIS);
} else {
String separator = NO_SEPARATOR;
for (Expression expression : listExpressions) {
appendSql(separator);
emulateTupleComparison(lhsTuple.getExpressions(), SqlTupleContainer.getSqlTuple(expression).getExpressions(), comparisonOperator, true);
separator = " or ";
}
}
return;
}
}
inListPredicate.getTestExpression().accept(this);
if (inListPredicate.isNegated()) {
appendSql(" not");
}
appendSql(" in(");
String separator = NO_SEPARATOR;
int bindValueCount = listExpressions.size();
int bindValueMaxCount = bindValueCount;
final Dialect dialect = getSessionFactory().getJdbcServices().getDialect();
int inExprLimit = dialect.getInExpressionCountLimit();
final boolean inClauseParameterPaddingEnabled = getSessionFactory().getSessionFactoryOptions().inClauseParameterPaddingEnabled() && bindValueCount > 2;
if (inClauseParameterPaddingEnabled) {
// bindValueCount: 1005
// bindValuePaddingCount: 1024
int bindValuePaddingCount = MathHelper.ceilingPowerOfTwo(bindValueCount);
// inExprLimit: 1000
if (inExprLimit > 0) {
if (bindValuePaddingCount > inExprLimit) {
// bindValuePaddingCount: 8
if (bindValueCount < inExprLimit) {
bindValueMaxCount = inExprLimit;
} else {
bindValueMaxCount = MathHelper.ceilingPowerOfTwo(bindValueCount % inExprLimit);
}
} else if (bindValueCount < bindValuePaddingCount) {
bindValueMaxCount = bindValuePaddingCount;
}
} else if (bindValueCount < bindValuePaddingCount) {
bindValueMaxCount = bindValuePaddingCount;
}
}
final Iterator<Expression> iterator = listExpressions.iterator();
int itemNumber = 0;
while (iterator.hasNext() && (inExprLimit == 0 || itemNumber < inExprLimit)) {
final Expression listExpression = itemAccessor.apply(iterator.next());
appendSql(separator);
listExpression.accept(this);
separator = COMA_SEPARATOR;
itemNumber++;
// and just render through the in list expressions as they are without padding/splitting
if (!(listExpression instanceof JdbcParameter || listExpression instanceof SqmParameterInterpretation)) {
inExprLimit = 0;
bindValueMaxCount = bindValueCount;
}
}
if (itemNumber != inExprLimit && bindValueCount == bindValueMaxCount) {
appendSql(CLOSE_PARENTHESIS);
return;
}
if (inExprLimit > 0 && bindValueCount > inExprLimit) {
do {
append(") and ");
inListPredicate.getTestExpression().accept(this);
if (inListPredicate.isNegated()) {
appendSql(" not");
}
appendSql(" in(");
separator = NO_SEPARATOR;
itemNumber = 0;
while (iterator.hasNext() && itemNumber < inExprLimit) {
final Expression listExpression = iterator.next();
appendSql(separator);
itemAccessor.apply(listExpression).accept(this);
separator = COMA_SEPARATOR;
itemNumber++;
}
} while (iterator.hasNext());
}
int i;
if (inExprLimit > 0 && bindValueCount > inExprLimit) {
i = bindValueCount % inExprLimit;
} else {
i = bindValueCount;
}
final Expression lastExpression = itemAccessor.apply(listExpressions.get(listExpressions.size() - 1));
for (; i < bindValueMaxCount; i++) {
appendSql(separator);
lastExpression.accept(this);
separator = COMA_SEPARATOR;
}
appendSql(CLOSE_PARENTHESIS);
}
Aggregations