use of org.hibernate.sql.ast.tree.expression.SqlTuple in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitTuple.
@Override
public Object visitTuple(SqmTuple<?> sqmTuple) {
final List<SqmExpression<?>> groupedExpressions = sqmTuple.getGroupedExpressions();
final int size = groupedExpressions.size();
final List<Expression> expressions = new ArrayList<>(size);
final MappingModelExpressible<?> mappingModelExpressible = resolveInferredType();
final EmbeddableMappingType embeddableMappingType;
if (mappingModelExpressible instanceof ValueMapping) {
embeddableMappingType = (EmbeddableMappingType) ((ValueMapping) mappingModelExpressible).getMappedType();
} else {
embeddableMappingType = null;
}
if (embeddableMappingType == null) {
try {
inferrableTypeAccessStack.push(() -> null);
for (int i = 0; i < size; i++) {
expressions.add((Expression) groupedExpressions.get(i).accept(this));
}
} finally {
inferrableTypeAccessStack.pop();
}
} else {
for (int i = 0; i < size; i++) {
final AttributeMapping attributeMapping = embeddableMappingType.getAttributeMappings().get(i);
inferrableTypeAccessStack.push(() -> attributeMapping);
try {
expressions.add((Expression) groupedExpressions.get(i).accept(this));
} finally {
inferrableTypeAccessStack.pop();
}
}
}
final MappingModelExpressible<?> valueMapping;
if (mappingModelExpressible != null) {
valueMapping = mappingModelExpressible;
} else {
final SqmExpressible<?> expressible = sqmTuple.getExpressible();
if (expressible instanceof MappingModelExpressible<?>) {
valueMapping = (MappingModelExpressible<?>) expressible;
} else {
valueMapping = null;
}
}
return new SqlTuple(expressions, valueMapping);
}
use of org.hibernate.sql.ast.tree.expression.SqlTuple in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method consumeFromClauseCorrelatedRoot.
protected void consumeFromClauseCorrelatedRoot(SqmRoot<?> sqmRoot) {
log.tracef("Resolving SqmRoot [%s] to TableGroup", sqmRoot);
final FromClauseIndex fromClauseIndex = getFromClauseIndex();
if (fromClauseIndex.isResolved(sqmRoot)) {
log.tracef("Already resolved SqmRoot [%s] to TableGroup", sqmRoot);
}
final QuerySpec currentQuerySpec = currentQuerySpec();
final TableGroup tableGroup;
if (!sqmRoot.isCorrelated()) {
return;
}
final SessionFactoryImplementor sessionFactory = creationContext.getSessionFactory();
if (sqmRoot.containsOnlyInnerJoins()) {
// If we have just inner joins against a correlated root, we can render the joins as references
final SqmFrom<?, ?> from;
// It will always contain just a single correlated join though, which is what is actually correlated
if (sqmRoot instanceof SqmCorrelatedRootJoin<?>) {
assert sqmRoot.getSqmJoins().size() == 1;
assert sqmRoot.getSqmJoins().get(0).isCorrelated();
from = sqmRoot.getSqmJoins().get(0);
} else {
from = sqmRoot;
}
final TableGroup parentTableGroup = fromClauseIndex.findTableGroupOnParents(from.getCorrelationParent().getNavigablePath());
final SqlAliasBase sqlAliasBase = sqlAliasBaseManager.createSqlAliasBase(parentTableGroup.getGroupAlias());
if (parentTableGroup instanceof PluralTableGroup) {
final PluralTableGroup pluralTableGroup = (PluralTableGroup) parentTableGroup;
final CorrelatedPluralTableGroup correlatedPluralTableGroup = new CorrelatedPluralTableGroup(parentTableGroup, sqlAliasBase, currentQuerySpec, predicate -> additionalRestrictions = SqlAstTreeHelper.combinePredicates(additionalRestrictions, predicate), sessionFactory);
final TableGroup elementTableGroup = pluralTableGroup.getElementTableGroup();
if (elementTableGroup != null) {
final TableGroup correlatedElementTableGroup = new CorrelatedTableGroup(elementTableGroup, sqlAliasBase, currentQuerySpec, predicate -> additionalRestrictions = SqlAstTreeHelper.combinePredicates(additionalRestrictions, predicate), sessionFactory);
final TableGroupJoin tableGroupJoin = new TableGroupJoin(elementTableGroup.getNavigablePath(), SqlAstJoinType.INNER, correlatedElementTableGroup);
correlatedPluralTableGroup.registerElementTableGroup(tableGroupJoin);
}
final TableGroup indexTableGroup = pluralTableGroup.getIndexTableGroup();
if (indexTableGroup != null) {
final TableGroup correlatedIndexTableGroup = new CorrelatedTableGroup(indexTableGroup, sqlAliasBase, currentQuerySpec, predicate -> additionalRestrictions = SqlAstTreeHelper.combinePredicates(additionalRestrictions, predicate), sessionFactory);
final TableGroupJoin tableGroupJoin = new TableGroupJoin(indexTableGroup.getNavigablePath(), SqlAstJoinType.INNER, correlatedIndexTableGroup);
correlatedPluralTableGroup.registerIndexTableGroup(tableGroupJoin);
}
tableGroup = correlatedPluralTableGroup;
} else {
tableGroup = new CorrelatedTableGroup(parentTableGroup, sqlAliasBase, currentQuerySpec, predicate -> additionalRestrictions = SqlAstTreeHelper.combinePredicates(additionalRestrictions, predicate), sessionFactory);
}
fromClauseIndex.register(from, tableGroup);
registerPluralTableGroupParts(tableGroup);
log.tracef("Resolved SqmRoot [%s] to correlated TableGroup [%s]", sqmRoot, tableGroup);
consumeExplicitJoins(from, tableGroup);
return;
} else {
final EntityPersister entityDescriptor = resolveEntityPersister(sqmRoot.getReferencedPathSource());
final TableGroup parentTableGroup = fromClauseIndex.findTableGroupOnParents(sqmRoot.getCorrelationParent().getNavigablePath());
// If we have non-inner joins against a correlated root, we must render the root with a correlation predicate
tableGroup = entityDescriptor.createRootTableGroup(true, sqmRoot.getNavigablePath(), sqmRoot.getExplicitAlias(), () -> predicate -> {
}, this, creationContext);
final EntityIdentifierMapping identifierMapping = entityDescriptor.getIdentifierMapping();
final NavigablePath navigablePath = sqmRoot.getNavigablePath().append(identifierMapping.getNavigableRole().getNavigableName());
final int jdbcTypeCount = identifierMapping.getJdbcTypeCount();
if (jdbcTypeCount == 1) {
identifierMapping.forEachSelectable((index, selectable) -> additionalRestrictions = SqlAstTreeHelper.combinePredicates(additionalRestrictions, new ComparisonPredicate(new ColumnReference(parentTableGroup.resolveTableReference(navigablePath, selectable.getContainingTableExpression()), selectable, sessionFactory), ComparisonOperator.EQUAL, new ColumnReference(tableGroup.resolveTableReference(navigablePath, selectable.getContainingTableExpression()), selectable, sessionFactory))));
} else {
final List<Expression> lhs = new ArrayList<>(jdbcTypeCount);
final List<Expression> rhs = new ArrayList<>(jdbcTypeCount);
identifierMapping.forEachSelectable((index, selectable) -> {
lhs.add(new ColumnReference(parentTableGroup.resolveTableReference(navigablePath, selectable.getContainingTableExpression()), selectable, sessionFactory));
rhs.add(new ColumnReference(tableGroup.resolveTableReference(navigablePath, selectable.getContainingTableExpression()), selectable, sessionFactory));
});
additionalRestrictions = SqlAstTreeHelper.combinePredicates(additionalRestrictions, new ComparisonPredicate(new SqlTuple(lhs, identifierMapping), ComparisonOperator.EQUAL, new SqlTuple(rhs, identifierMapping)));
}
}
log.tracef("Resolved SqmRoot [%s] to new TableGroup [%s]", sqmRoot, tableGroup);
fromClauseIndex.register(sqmRoot, tableGroup);
currentQuerySpec.getFromClause().addRoot(tableGroup);
consumeJoins(sqmRoot, fromClauseIndex, tableGroup);
}
use of org.hibernate.sql.ast.tree.expression.SqlTuple in project hibernate-orm by hibernate.
the class DiscriminatedAssociationPathInterpretation method from.
public static <T> DiscriminatedAssociationPathInterpretation<T> from(SqmAnyValuedSimplePath<T> sqmPath, SqmToSqlAstConverter converter) {
final TableGroup tableGroup = converter.getFromClauseAccess().findTableGroup(sqmPath.getLhs().getNavigablePath());
final DiscriminatedAssociationModelPart mapping = (DiscriminatedAssociationModelPart) tableGroup.getModelPart().findSubPart(sqmPath.getReferencedPathSource().getPathName(), null);
final List<Expression> tupleExpressions = new ArrayList<>();
mapping.forEachSelectable((selectionIndex, selectableMapping) -> {
final TableReference tableReference = tableGroup.resolveTableReference(sqmPath.getNavigablePath(), selectableMapping.getContainingTableExpression());
final Expression expression = converter.getSqlExpressionResolver().resolveSqlExpression(SqlExpressionResolver.createColumnReferenceKey(tableReference, selectableMapping.getSelectionExpression()), processingState -> new ColumnReference(tableReference, selectableMapping, converter.getCreationContext().getSessionFactory()));
tupleExpressions.add(expression);
});
return new DiscriminatedAssociationPathInterpretation<T>(sqmPath.getNavigablePath(), mapping, tableGroup, new SqlTuple(tupleExpressions, mapping));
}
use of org.hibernate.sql.ast.tree.expression.SqlTuple in project hibernate-orm by hibernate.
the class SqmParameterInterpretation method createDomainResult.
@Override
public DomainResult<?> createDomainResult(String resultVariable, DomainResultCreationState creationState) {
final Expression resolvedExpression = getResolvedExpression();
if (resolvedExpression instanceof SqlTuple) {
throw new SemanticException("Composite query parameter cannot be used in select");
}
BindableType<?> nodeType = sqmParameter.getNodeType();
if (nodeType == null) {
final QueryParameterBinding<?> binding = queryParameterBindingResolver.apply(queryParameter);
nodeType = binding.getBindType();
}
final SessionFactoryImplementor sessionFactory = creationState.getSqlAstCreationState().getCreationContext().getSessionFactory();
final SqmExpressible<?> sqmExpressible = nodeType.resolveExpressible(sessionFactory);
final SqlSelection sqlSelection = creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(resolvedExpression, sqmExpressible.getExpressibleJavaType(), sessionFactory.getTypeConfiguration());
return new BasicResult<>(sqlSelection.getValuesArrayPosition(), resultVariable, sqmExpressible.getExpressibleJavaType());
}
use of org.hibernate.sql.ast.tree.expression.SqlTuple in project hibernate-orm by hibernate.
the class MappingModelHelper method buildColumnReferenceExpression.
public static Expression buildColumnReferenceExpression(TableGroup tableGroup, ModelPart modelPart, SqlExpressionResolver sqlExpressionResolver, SessionFactoryImplementor sessionFactory) {
final int jdbcTypeCount = modelPart.getJdbcTypeCount();
if (modelPart instanceof EmbeddableValuedModelPart) {
final List<ColumnReference> columnReferences = new ArrayList<>(jdbcTypeCount);
modelPart.forEachSelectable((columnIndex, selection) -> {
final ColumnReference colRef;
final String qualifier;
if (tableGroup == null) {
qualifier = selection.getContainingTableExpression();
} else {
qualifier = tableGroup.resolveTableReference(selection.getContainingTableExpression()).getIdentificationVariable();
}
if (sqlExpressionResolver == null) {
colRef = new ColumnReference(qualifier, selection, sessionFactory);
} else {
colRef = (ColumnReference) sqlExpressionResolver.resolveSqlExpression(createColumnReferenceKey(qualifier, selection.getSelectionExpression()), sqlAstProcessingState -> new ColumnReference(qualifier, selection, sessionFactory));
}
columnReferences.add(colRef);
});
return new SqlTuple(columnReferences, modelPart);
} else {
assert modelPart instanceof BasicValuedModelPart;
final BasicValuedModelPart basicPart = (BasicValuedModelPart) modelPart;
final String qualifier;
if (tableGroup == null) {
qualifier = basicPart.getContainingTableExpression();
} else {
qualifier = tableGroup.resolveTableReference(basicPart.getContainingTableExpression()).getIdentificationVariable();
}
if (sqlExpressionResolver == null) {
return new ColumnReference(qualifier, basicPart, sessionFactory);
} else {
return sqlExpressionResolver.resolveSqlExpression(createColumnReferenceKey(qualifier, basicPart.getSelectionExpression()), sqlAstProcessingState -> new ColumnReference(qualifier, basicPart, sessionFactory));
}
}
}
Aggregations