use of org.hibernate.sql.ast.tree.predicate.InListPredicate in project hibernate-orm by hibernate.
the class ExpressionReplacementWalker method visitInListPredicate.
@Override
public void visitInListPredicate(InListPredicate inListPredicate) {
final Expression testExpression = replaceExpression(inListPredicate.getTestExpression());
List<Expression> items = null;
final List<Expression> listExpressions = inListPredicate.getListExpressions();
for (int i = 0; i < listExpressions.size(); i++) {
final Expression listExpression = listExpressions.get(i);
final Expression newListExpression = replaceExpression(listExpression);
if (newListExpression != listExpression) {
if (items == null) {
items = new ArrayList<>(listExpressions);
}
items.set(i, newListExpression);
}
}
if (testExpression != inListPredicate.getTestExpression() || items != null) {
returnedNode = new InListPredicate(testExpression, items == null ? listExpressions : items, inListPredicate.isNegated(), inListPredicate.getExpressionType());
} else {
returnedNode = inListPredicate;
}
}
use of org.hibernate.sql.ast.tree.predicate.InListPredicate in project hibernate-orm by hibernate.
the class LoaderSelectBuilder method applyRestriction.
private void applyRestriction(QuerySpec rootQuerySpec, NavigablePath rootNavigablePath, TableGroup rootTableGroup, ModelPart modelPart, int numberColumns, Consumer<JdbcParameter> jdbcParameterConsumer, LoaderSqlAstCreationState sqlAstCreationState) {
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
final NavigablePath navigablePath = rootNavigablePath.append(modelPart.getNavigableRole().getNavigableName());
if (numberColumns == 1) {
modelPart.forEachSelectable((columnIndex, selection) -> {
final TableReference tableReference = rootTableGroup.resolveTableReference(navigablePath, selection.getContainingTableExpression());
final ColumnReference columnRef = (ColumnReference) sqlExpressionResolver.resolveSqlExpression(createColumnReferenceKey(tableReference, selection.getSelectionExpression()), p -> new ColumnReference(tableReference, selection, creationContext.getSessionFactory()));
if (numberOfKeysToLoad == 1) {
final JdbcParameter jdbcParameter = new JdbcParameterImpl(selection.getJdbcMapping());
jdbcParameterConsumer.accept(jdbcParameter);
rootQuerySpec.applyPredicate(new ComparisonPredicate(columnRef, ComparisonOperator.EQUAL, jdbcParameter));
} else {
final InListPredicate predicate = new InListPredicate(columnRef);
for (int i = 0; i < numberOfKeysToLoad; i++) {
for (int j = 0; j < numberColumns; j++) {
final JdbcParameter jdbcParameter = new JdbcParameterImpl(columnRef.getJdbcMapping());
jdbcParameterConsumer.accept(jdbcParameter);
predicate.addExpression(jdbcParameter);
}
}
rootQuerySpec.applyPredicate(predicate);
}
});
} else {
final List<ColumnReference> columnReferences = new ArrayList<>(numberColumns);
modelPart.forEachSelectable((columnIndex, selection) -> {
final TableReference tableReference = rootTableGroup.resolveTableReference(navigablePath, selection.getContainingTableExpression());
columnReferences.add((ColumnReference) sqlExpressionResolver.resolveSqlExpression(createColumnReferenceKey(tableReference, selection.getSelectionExpression()), p -> new ColumnReference(tableReference, selection, creationContext.getSessionFactory())));
});
final SqlTuple tuple = new SqlTuple(columnReferences, modelPart);
final InListPredicate predicate = new InListPredicate(tuple);
for (int i = 0; i < numberOfKeysToLoad; i++) {
final List<JdbcParameter> tupleParams = new ArrayList<>(numberColumns);
for (int j = 0; j < numberColumns; j++) {
final ColumnReference columnReference = columnReferences.get(j);
final JdbcParameter jdbcParameter = new JdbcParameterImpl(columnReference.getJdbcMapping());
jdbcParameterConsumer.accept(jdbcParameter);
tupleParams.add(jdbcParameter);
}
final SqlTuple paramTuple = new SqlTuple(tupleParams, modelPart);
predicate.addExpression(paramTuple);
}
rootQuerySpec.applyPredicate(predicate);
}
}
use of org.hibernate.sql.ast.tree.predicate.InListPredicate in project hibernate-orm by hibernate.
the class InPredicateRestrictionProducer method produceRestriction.
@Override
public InListPredicate produceRestriction(List<?> matchingIdValues, EntityMappingType entityDescriptor, int valueIndex, ModelPart valueModelPart, TableReference mutatingTableReference, Supplier<Consumer<SelectableConsumer>> columnsToMatchVisitationSupplier, ExecutionContext executionContext) {
assert matchingIdValues != null;
assert !matchingIdValues.isEmpty();
final SessionFactoryImplementor sessionFactory = executionContext.getSession().getFactory();
final EntityIdentifierMapping identifierMapping = entityDescriptor.getIdentifierMapping();
final int idColumnCount = identifierMapping.getJdbcTypeCount();
assert idColumnCount > 0;
final InListPredicate predicate;
if (idColumnCount == 1) {
final BasicValuedModelPart basicIdMapping = (BasicValuedModelPart) identifierMapping;
final String idColumn = basicIdMapping.getSelectionExpression();
final Expression inFixture = new ColumnReference(mutatingTableReference, idColumn, // id columns cannot be formulas and cannot have custom read and write expressions
false, null, null, basicIdMapping.getJdbcMapping(), sessionFactory);
predicate = new InListPredicate(inFixture);
matchingIdValues.forEach(matchingId -> predicate.addExpression(new JdbcLiteral<>(matchingId, basicIdMapping.getJdbcMapping())));
} else {
final List<ColumnReference> columnReferences = new ArrayList<>(idColumnCount);
final List<JdbcMapping> jdbcMappings = new ArrayList<>(idColumnCount);
identifierMapping.forEachSelectable((columnIndex, selection) -> {
columnReferences.add(new ColumnReference(mutatingTableReference, selection, sessionFactory));
jdbcMappings.add(selection.getJdbcMapping());
});
final Expression inFixture = new SqlTuple(columnReferences, identifierMapping);
predicate = new InListPredicate(inFixture);
matchingIdValues.forEach(matchingId -> {
assert matchingId instanceof Object[];
final Object[] matchingIdParts = (Object[]) matchingId;
final List<JdbcLiteral<?>> tupleParts = new ArrayList<>(idColumnCount);
for (int p = 0; p < matchingIdParts.length; p++) {
tupleParts.add(new JdbcLiteral<>(matchingIdParts[p], jdbcMappings.get(p)));
}
predicate.addExpression(new SqlTuple(tupleParts, identifierMapping));
});
}
return predicate;
}
use of org.hibernate.sql.ast.tree.predicate.InListPredicate in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitInListPredicate.
@Override
public Predicate visitInListPredicate(SqmInListPredicate<?> predicate) {
// handling for "expansion"
if (predicate.getListExpressions().size() == 1) {
final SqmExpression<?> sqmExpression = predicate.getListExpressions().get(0);
if (sqmExpression instanceof SqmParameter) {
final SqmParameter<?> sqmParameter = (SqmParameter<?>) sqmExpression;
if (sqmParameter.allowMultiValuedBinding()) {
final Predicate specialCase = processInListWithSingleParameter(predicate, sqmParameter);
if (specialCase != null) {
return specialCase;
}
}
}
}
// otherwise - no special case...
final FromClauseIndex fromClauseIndex = fromClauseIndexStack.getCurrent();
inferrableTypeAccessStack.push(() -> {
for (SqmExpression<?> listExpression : predicate.getListExpressions()) {
final MappingModelExpressible<?> mapping = determineValueMapping(listExpression, fromClauseIndex);
if (mapping != null) {
return mapping;
}
}
return null;
});
final Expression testExpression;
try {
testExpression = (Expression) predicate.getTestExpression().accept(this);
} finally {
inferrableTypeAccessStack.pop();
}
final InListPredicate inPredicate = new InListPredicate(testExpression, predicate.isNegated(), getBooleanType());
inferrableTypeAccessStack.push(() -> determineValueMapping(predicate.getTestExpression(), fromClauseIndex));
try {
for (SqmExpression<?> expression : predicate.getListExpressions()) {
inPredicate.addExpression((Expression) expression.accept(this));
}
} finally {
inferrableTypeAccessStack.pop();
}
return inPredicate;
}
use of org.hibernate.sql.ast.tree.predicate.InListPredicate in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method createTreatTypeRestriction.
private Predicate createTreatTypeRestriction(SqmPath<?> lhs, Set<String> subclassEntityNames) {
final MappingMetamodel domainModel = creationContext.getSessionFactory().getRuntimeMetamodels().getMappingMetamodel();
// Do what visitSelfInterpretingSqmPath does, except for calling preparingReusablePath
// as that would register a type usage for the table group that we don't want here
final DiscriminatorSqmPath discriminatorSqmPath = (DiscriminatorSqmPath) lhs.type();
registerTypeUsage(discriminatorSqmPath);
final Expression typeExpression = discriminatorSqmPath.interpret(this, this, jpaQueryComplianceEnabled);
if (subclassEntityNames.size() == 1) {
return new ComparisonPredicate(typeExpression, ComparisonOperator.EQUAL, new EntityTypeLiteral(domainModel.findEntityDescriptor(subclassEntityNames.iterator().next())));
} else {
final List<Expression> typeLiterals = new ArrayList<>(subclassEntityNames.size());
for (String subclassEntityName : subclassEntityNames) {
typeLiterals.add(new EntityTypeLiteral(domainModel.findEntityDescriptor(subclassEntityName)));
}
return new InListPredicate(typeExpression, typeLiterals);
}
}
Aggregations