use of org.hibernate.metamodel.mapping.ModelPart in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method consumeAttributeJoin.
private TableGroup consumeAttributeJoin(SqmAttributeJoin<?, ?> sqmJoin, TableGroup lhsTableGroup, TableGroup ownerTableGroup, boolean transitive) {
final SqmPathSource<?> pathSource = sqmJoin.getReferencedPathSource();
final SqmJoinType sqmJoinType = sqmJoin.getSqmJoinType();
final TableGroupJoin joinedTableGroupJoin;
final TableGroup joinedTableGroup;
final NavigablePath sqmJoinNavigablePath = sqmJoin.getNavigablePath();
final ModelPart modelPart = ownerTableGroup.getModelPart().findSubPart(pathSource.getPathName(), SqmMappingModelHelper.resolveExplicitTreatTarget(sqmJoin, this));
if (pathSource instanceof PluralPersistentAttribute) {
assert modelPart instanceof PluralAttributeMapping;
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) modelPart;
if (sqmJoin.isFetched()) {
containsCollectionFetches = true;
}
joinedTableGroupJoin = pluralAttributeMapping.createTableGroupJoin(sqmJoinNavigablePath, ownerTableGroup, sqmJoin.getExplicitAlias(), sqmJoinType.getCorrespondingSqlJoinType(), sqmJoin.isFetched(), sqmJoin.getJoinPredicate() != null, this);
joinedTableGroup = joinedTableGroupJoin.getJoinedGroup();
pluralAttributeMapping.applyBaseRestrictions((predicate) -> {
final PredicateCollector existing = collectionFilterPredicates.get(joinedTableGroup.getNavigablePath());
final PredicateCollector collector;
if (existing == null) {
collector = new PredicateCollector(predicate);
collectionFilterPredicates.put(joinedTableGroup.getNavigablePath(), collector);
} else {
collector = existing;
collector.applyPredicate(predicate);
}
}, joinedTableGroup, true, getLoadQueryInfluencers().getEnabledFilters(), null, this);
} else {
assert modelPart instanceof TableGroupJoinProducer;
joinedTableGroupJoin = ((TableGroupJoinProducer) modelPart).createTableGroupJoin(sqmJoinNavigablePath, ownerTableGroup, sqmJoin.getExplicitAlias(), sqmJoinType.getCorrespondingSqlJoinType(), sqmJoin.isFetched(), sqmJoin.getJoinPredicate() != null, this);
joinedTableGroup = joinedTableGroupJoin.getJoinedGroup();
// Left or inner singular attribute joins without a predicate can be safely optimized away
if (sqmJoin.getJoinPredicate() != null || sqmJoinType != SqmJoinType.INNER && sqmJoinType != SqmJoinType.LEFT) {
joinedTableGroup.getPrimaryTableReference();
}
}
lhsTableGroup.addTableGroupJoin(joinedTableGroupJoin);
getFromClauseIndex().register(sqmJoin, joinedTableGroup);
registerPluralTableGroupParts(joinedTableGroup);
// For joins we also need to register the table groups for the treats
if (joinedTableGroup instanceof PluralTableGroup) {
final PluralTableGroup pluralTableGroup = (PluralTableGroup) joinedTableGroup;
for (SqmFrom<?, ?> sqmTreat : sqmJoin.getSqmTreats()) {
if (pluralTableGroup.getElementTableGroup() != null) {
getFromClauseAccess().registerTableGroup(sqmTreat.getNavigablePath().append(CollectionPart.Nature.ELEMENT.getName()), pluralTableGroup.getElementTableGroup());
}
if (pluralTableGroup.getIndexTableGroup() != null) {
getFromClauseAccess().registerTableGroup(sqmTreat.getNavigablePath().append(CollectionPart.Nature.INDEX.getName()), pluralTableGroup.getIndexTableGroup());
}
}
} else {
for (SqmFrom<?, ?> sqmTreat : sqmJoin.getSqmTreats()) {
getFromClauseAccess().registerTableGroup(sqmTreat.getNavigablePath(), joinedTableGroup);
}
}
// add any additional join restrictions
if (sqmJoin.getJoinPredicate() != null) {
if (sqmJoin.isFetched()) {
QueryLogging.QUERY_MESSAGE_LOGGER.debugf("Join fetch [" + sqmJoinNavigablePath + "] is restricted");
}
final SqmJoin<?, ?> oldJoin = currentlyProcessingJoin;
currentlyProcessingJoin = sqmJoin;
joinedTableGroupJoin.applyPredicate(visitNestedTopLevelPredicate(sqmJoin.getJoinPredicate()));
currentlyProcessingJoin = oldJoin;
}
if (transitive) {
consumeExplicitJoins(sqmJoin, joinedTableGroup);
}
return joinedTableGroup;
}
use of org.hibernate.metamodel.mapping.ModelPart in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method determineValueMapping.
protected MappingModelExpressible<?> determineValueMapping(SqmParameter<?> sqmParameter) {
log.debugf("Determining mapping-model type for SqmParameter : %s", sqmParameter);
final QueryParameterImplementor<?> queryParameter = domainParameterXref.getQueryParameter(sqmParameter);
final QueryParameterBinding<?> binding = domainParameterBindings.getBinding(queryParameter);
BindableType<?> paramType = binding.getBindType();
if (paramType == null) {
paramType = queryParameter.getHibernateType();
if (paramType == null) {
paramType = sqmParameter.getAnticipatedType();
}
}
if (paramType == null) {
final MappingModelExpressible<?> inferredValueMapping = getInferredValueMapping();
if (inferredValueMapping != null) {
return inferredValueMapping;
}
// Default to the Object type
return basicType(Object.class);
} else if (paramType instanceof MappingModelExpressible<?>) {
final MappingModelExpressible<?> paramModelType = (MappingModelExpressible<?>) paramType;
final MappingModelExpressible<?> inferredValueMapping = getInferredValueMapping();
// Prefer the model part type instead of the bind type if possible as the model part type contains size information
if (inferredValueMapping instanceof ModelPart) {
final JdbcMapping paramJdbcMapping = paramModelType.getJdbcMappings().get(0);
final JdbcMapping inferredJdbcMapping = inferredValueMapping.getJdbcMappings().get(0);
// If the bind type has a different JDBC type, we prefer that
if (paramJdbcMapping.getJdbcType() == inferredJdbcMapping.getJdbcType()) {
return inferredValueMapping;
}
}
return paramModelType;
} else if (sqmParameter.getAnticipatedType() == null) {
// this should indicate the condition that the user query did not define an
// explicit type in regard to this parameter. Here we should prefer the
// inferrable type and fallback to resolving the binding type
final MappingModelExpressible<?> inferredValueMapping = getInferredValueMapping();
if (inferredValueMapping != null) {
return inferredValueMapping;
}
} else if (paramType instanceof EntityDomainType) {
// In JPA Criteria, it is possible to define a parameter of an entity type,
// but that should infer the mapping type from context,
// otherwise this would default to binding the PK which might be wrong
final MappingModelExpressible<?> inferredValueMapping = getInferredValueMapping();
if (inferredValueMapping != null) {
return inferredValueMapping;
}
}
final SqmExpressible<?> paramSqmType = paramType.resolveExpressible(creationContext.getSessionFactory());
if (paramSqmType instanceof SqmPath) {
final SqmPath<?> sqmPath = (SqmPath<?>) paramSqmType;
final NavigablePath navigablePath = sqmPath.getNavigablePath();
if (navigablePath.getParent() != null) {
final TableGroup tableGroup = getFromClauseAccess().getTableGroup(navigablePath.getParent());
return tableGroup.getModelPart().findSubPart(navigablePath.getLocalName(), null);
}
return getFromClauseAccess().getTableGroup(navigablePath).getModelPart();
}
if (paramSqmType instanceof BasicValuedMapping) {
return (BasicValuedMapping) paramSqmType;
}
if (paramSqmType instanceof CompositeSqmPathSource || paramSqmType instanceof EmbeddableDomainType<?>) {
// Try to infer the value mapping since the other side apparently is a path source
final MappingModelExpressible<?> inferredValueMapping = getInferredValueMapping();
if (inferredValueMapping != null) {
return inferredValueMapping;
}
throw new NotYetImplementedFor6Exception("Support for embedded-valued parameters not yet implemented");
}
if (paramSqmType instanceof SqmPathSource<?> || paramSqmType instanceof BasicDomainType<?>) {
// Try to infer the value mapping since the other side apparently is a path source
final MappingModelExpressible<?> inferredValueMapping = getInferredValueMapping();
if (inferredValueMapping != null) {
return inferredValueMapping;
}
final BasicType basicTypeForJavaType = getTypeConfiguration().getBasicTypeForJavaType(paramSqmType.getExpressibleJavaType().getJavaTypeClass());
if (basicTypeForJavaType == null) {
if (paramSqmType instanceof EntityDomainType) {
return getIdType((EntityDomainType) paramSqmType);
} else if (paramSqmType instanceof SingularAttribute) {
final Type type = ((SingularAttribute) paramSqmType).getType();
if (type instanceof EntityDomainType) {
return getIdType((EntityDomainType) type);
}
}
}
return basicTypeForJavaType;
}
throw new ConversionException("Could not determine ValueMapping for SqmParameter: " + sqmParameter);
}
use of org.hibernate.metamodel.mapping.ModelPart in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitTableGroup.
private Expression visitTableGroup(TableGroup tableGroup, SqmFrom<?, ?> path) {
final ModelPartContainer modelPart;
final MappingModelExpressible<?> inferredValueMapping = getInferredValueMapping();
// For plain SqmFrom node uses, prefer the mapping type from the context if possible
if (!(inferredValueMapping instanceof ModelPartContainer)) {
modelPart = tableGroup.getModelPart();
} else {
modelPart = (ModelPartContainer) inferredValueMapping;
}
final ModelPart resultModelPart;
final ModelPart interpretationModelPart;
final TableGroup parentGroupToUse;
if (modelPart instanceof ToOneAttributeMapping) {
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) modelPart;
final ModelPart targetPart = toOneAttributeMapping.getForeignKeyDescriptor().getPart(toOneAttributeMapping.getSideNature().inverse());
if (tableGroup.getModelPart().getPartMappingType() == modelPart.getPartMappingType()) {
resultModelPart = targetPart;
} else {
// If the table group is for a different mapping type i.e. an inheritance subtype,
// lookup the target part on that mapping type
resultModelPart = tableGroup.getModelPart().findSubPart(targetPart.getPartName(), null);
}
interpretationModelPart = modelPart;
parentGroupToUse = null;
} else if (modelPart instanceof PluralAttributeMapping) {
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) modelPart;
final CollectionPart elementDescriptor = pluralAttributeMapping.getElementDescriptor();
if (elementDescriptor instanceof EntityCollectionPart) {
// Usually, we need to resolve to the PK for visitTableGroup
final EntityCollectionPart collectionPart = (EntityCollectionPart) elementDescriptor;
final ModelPart collectionTargetPart = collectionPart.getForeignKeyDescriptor().getPart(collectionPart.getSideNature().inverse());
final EntityIdentifierMapping identifierMapping = collectionPart.getEntityMappingType().getIdentifierMapping();
// If the FK points to the PK, we can use the FK part though, if this is not a root
if (collectionTargetPart == identifierMapping && !(path instanceof SqmRoot<?>)) {
resultModelPart = collectionPart.getForeignKeyDescriptor().getPart(collectionPart.getSideNature());
} else {
resultModelPart = identifierMapping;
}
} else {
resultModelPart = elementDescriptor;
}
interpretationModelPart = elementDescriptor;
parentGroupToUse = null;
} else if (modelPart instanceof EntityCollectionPart) {
// Usually, we need to resolve to the PK for visitTableGroup
final EntityCollectionPart collectionPart = (EntityCollectionPart) modelPart;
final ModelPart collectionTargetPart = collectionPart.getForeignKeyDescriptor().getPart(collectionPart.getSideNature().inverse());
final EntityIdentifierMapping identifierMapping = collectionPart.getEntityMappingType().getIdentifierMapping();
// If the FK points to the PK, we can use the FK part though, if this is not a root
if (collectionTargetPart == identifierMapping && !(path instanceof SqmRoot<?>)) {
resultModelPart = collectionPart.getForeignKeyDescriptor().getPart(collectionPart.getSideNature());
} else {
resultModelPart = identifierMapping;
}
interpretationModelPart = modelPart;
parentGroupToUse = findTableGroup(tableGroup.getNavigablePath().getParent());
} else if (modelPart instanceof EntityMappingType) {
resultModelPart = ((EntityMappingType) modelPart).getIdentifierMapping();
interpretationModelPart = modelPart;
// todo: I think this will always be null anyways because EntityMappingType will only be the model part
// of a TableGroup if that is a root TableGroup, so check if we can just switch to null
parentGroupToUse = findTableGroup(tableGroup.getNavigablePath().getParent());
} else {
resultModelPart = modelPart;
interpretationModelPart = modelPart;
parentGroupToUse = null;
}
final NavigablePath navigablePath;
if (interpretationModelPart == modelPart) {
navigablePath = tableGroup.getNavigablePath();
} else {
navigablePath = tableGroup.getNavigablePath().append(interpretationModelPart.getPartName());
}
final Expression result;
if (interpretationModelPart instanceof EntityValuedModelPart) {
final boolean expandToAllColumns;
if (currentClauseStack.getCurrent() == Clause.GROUP) {
// When the table group is known to be fetched i.e. a fetch join
// but also when the from clause is part of the select clause
// we need to expand to all columns, as we also expand this to all columns in the select clause
expandToAllColumns = tableGroup.isFetched() || selectClauseContains(path);
} else {
expandToAllColumns = false;
}
final EntityValuedModelPart mapping = (EntityValuedModelPart) interpretationModelPart;
EntityMappingType mappingType;
if (path instanceof SqmTreatedPath) {
mappingType = creationContext.getSessionFactory().getRuntimeMetamodels().getMappingMetamodel().findEntityDescriptor(((SqmTreatedPath<?, ?>) path).getTreatTarget().getHibernateEntityName());
} else {
mappingType = mapping.getEntityMappingType();
}
result = EntityValuedPathInterpretation.from(navigablePath, parentGroupToUse == null ? tableGroup : parentGroupToUse, expandToAllColumns ? null : resultModelPart, (EntityValuedModelPart) interpretationModelPart, mappingType, this);
} else if (interpretationModelPart instanceof EmbeddableValuedModelPart) {
final EmbeddableValuedModelPart mapping = (EmbeddableValuedModelPart) resultModelPart;
result = new EmbeddableValuedPathInterpretation<>(mapping.toSqlExpression(tableGroup, currentClauseStack.getCurrent(), this, getSqlAstCreationState()), navigablePath, (EmbeddableValuedModelPart) interpretationModelPart, tableGroup);
} else {
assert interpretationModelPart instanceof BasicValuedModelPart;
final BasicValuedModelPart mapping = (BasicValuedModelPart) resultModelPart;
final TableReference tableReference = tableGroup.resolveTableReference(navigablePath.append(resultModelPart.getPartName()), mapping.getContainingTableExpression());
final Expression expression = getSqlExpressionResolver().resolveSqlExpression(createColumnReferenceKey(tableReference, mapping.getSelectionExpression()), sacs -> new ColumnReference(tableReference.getIdentificationVariable(), mapping, getCreationContext().getSessionFactory()));
final ColumnReference columnReference;
if (expression instanceof ColumnReference) {
columnReference = (ColumnReference) expression;
} else if (expression instanceof SqlSelectionExpression) {
final Expression selectedExpression = ((SqlSelectionExpression) expression).getSelection().getExpression();
assert selectedExpression instanceof ColumnReference;
columnReference = (ColumnReference) selectedExpression;
} else {
throw new UnsupportedOperationException("Unsupported basic-valued path expression : " + expression);
}
result = new BasicValuedPathInterpretation<>(columnReference, navigablePath, (BasicValuedModelPart) interpretationModelPart, tableGroup);
}
return withTreatRestriction(result, path);
}
use of org.hibernate.metamodel.mapping.ModelPart in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method createLateralJoinExpression.
protected Expression createLateralJoinExpression(AbstractSqmSpecificPluralPartPath<?> pluralPartPath, boolean index, String functionName) {
prepareReusablePath(pluralPartPath.getLhs(), () -> null);
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) determineValueMapping(pluralPartPath.getPluralDomainPath());
final FromClauseAccess parentFromClauseAccess = getFromClauseAccess();
final TableGroup parentTableGroup = parentFromClauseAccess.findTableGroup(pluralPartPath.getNavigablePath().getParent());
final CollectionPart collectionPart = index ? pluralAttributeMapping.getIndexDescriptor() : pluralAttributeMapping.getElementDescriptor();
final ModelPart modelPart;
if (collectionPart instanceof EntityAssociationMapping) {
modelPart = ((EntityAssociationMapping) collectionPart).getKeyTargetMatchPart();
} else {
modelPart = collectionPart;
}
final int jdbcTypeCount = modelPart.getJdbcTypeCount();
final String pathName = functionName + (index ? "_index" : "_element");
final String identifierVariable = parentTableGroup.getPrimaryTableReference().getIdentificationVariable() + "_" + pathName;
final NavigablePath queryPath = new NavigablePath(parentTableGroup.getNavigablePath(), pathName, identifierVariable);
TableGroup lateralTableGroup = parentFromClauseAccess.findTableGroup(queryPath);
if (lateralTableGroup == null) {
final QuerySpec subQuerySpec = new QuerySpec(false);
pushProcessingState(new SqlAstQueryPartProcessingStateImpl(subQuerySpec, getCurrentProcessingState(), this, currentClauseStack::getCurrent, false));
try {
final TableGroup tableGroup = pluralAttributeMapping.createRootTableGroup(true, pluralPartPath.getNavigablePath(), null, () -> subQuerySpec::applyPredicate, this, creationContext);
pluralAttributeMapping.applyBaseRestrictions(subQuerySpec::applyPredicate, tableGroup, true, getLoadQueryInfluencers().getEnabledFilters(), null, this);
getFromClauseAccess().registerTableGroup(pluralPartPath.getNavigablePath(), tableGroup);
registerPluralTableGroupParts(tableGroup);
subQuerySpec.getFromClause().addRoot(tableGroup);
final List<String> columnNames = new ArrayList<>(jdbcTypeCount);
final List<ColumnReference> resultColumnReferences = new ArrayList<>(jdbcTypeCount);
final NavigablePath navigablePath = pluralPartPath.getNavigablePath();
final Boolean max = functionName.equalsIgnoreCase("max") ? Boolean.TRUE : (functionName.equalsIgnoreCase("min") ? Boolean.FALSE : null);
final AbstractSqmSelfRenderingFunctionDescriptor functionDescriptor = (AbstractSqmSelfRenderingFunctionDescriptor) creationContext.getSessionFactory().getQueryEngine().getSqmFunctionRegistry().findFunctionDescriptor(functionName);
final List<ColumnReference> subQueryColumns = new ArrayList<>(jdbcTypeCount);
modelPart.forEachSelectable((selectionIndex, selectionMapping) -> {
final ColumnReference columnReference = new ColumnReference(tableGroup.resolveTableReference(navigablePath, selectionMapping.getContainingTableExpression()), selectionMapping, creationContext.getSessionFactory());
final String columnName;
if (selectionMapping.isFormula()) {
columnName = "col" + columnNames.size();
} else {
columnName = selectionMapping.getSelectionExpression();
}
columnNames.add(columnName);
subQueryColumns.add(columnReference);
if (max != null) {
subQuerySpec.addSortSpecification(new SortSpecification(columnReference, max ? SortOrder.DESCENDING : SortOrder.ASCENDING));
}
});
if (max != null) {
for (int i = 0; i < subQueryColumns.size(); i++) {
subQuerySpec.getSelectClause().addSqlSelection(new SqlSelectionImpl(i + 1, i, subQueryColumns.get(i)));
resultColumnReferences.add(new ColumnReference(identifierVariable, columnNames.get(i), false, null, null, subQueryColumns.get(i).getJdbcMapping(), creationContext.getSessionFactory()));
}
subQuerySpec.setFetchClauseExpression(new QueryLiteral<>(1, basicType(Integer.class)), FetchClauseType.ROWS_ONLY);
} else {
final List<? extends SqlAstNode> arguments;
if (jdbcTypeCount == 1) {
arguments = subQueryColumns;
} else {
arguments = Collections.singletonList(new SqlTuple(subQueryColumns, modelPart));
}
final Expression expression = new SelfRenderingAggregateFunctionSqlAstExpression(functionDescriptor.getName(), functionDescriptor, arguments, null, (ReturnableType<?>) functionDescriptor.getReturnTypeResolver().resolveFunctionReturnType(() -> null, arguments).getJdbcMapping(), modelPart);
subQuerySpec.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, expression));
resultColumnReferences.add(new ColumnReference(identifierVariable, columnNames.get(0), false, null, null, expression.getExpressionType().getJdbcMappings().get(0), creationContext.getSessionFactory()));
}
subQuerySpec.applyPredicate(pluralAttributeMapping.getKeyDescriptor().generateJoinPredicate(parentFromClauseAccess.findTableGroup(pluralPartPath.getPluralDomainPath().getNavigablePath().getParent()), tableGroup, getSqlExpressionResolver(), creationContext));
final String compatibleTableExpression;
if (modelPart instanceof BasicValuedModelPart) {
compatibleTableExpression = ((BasicValuedModelPart) modelPart).getContainingTableExpression();
} else if (modelPart instanceof EmbeddableValuedModelPart) {
compatibleTableExpression = ((EmbeddableValuedModelPart) modelPart).getContainingTableExpression();
} else {
compatibleTableExpression = null;
}
lateralTableGroup = new QueryPartTableGroup(queryPath, null, subQuerySpec, identifierVariable, columnNames, compatibleTableExpression, true, false, creationContext.getSessionFactory());
if (currentlyProcessingJoin == null) {
parentTableGroup.addTableGroupJoin(new TableGroupJoin(lateralTableGroup.getNavigablePath(), SqlAstJoinType.LEFT, lateralTableGroup));
} else {
// In case this is used in the ON condition, we must prepend this lateral join
final TableGroup targetTableGroup;
if (currentlyProcessingJoin.getLhs() == null) {
targetTableGroup = parentFromClauseAccess.getTableGroup(currentlyProcessingJoin.findRoot().getNavigablePath());
} else {
targetTableGroup = parentFromClauseAccess.getTableGroup(currentlyProcessingJoin.getLhs().getNavigablePath());
}
// Many databases would support modelling this as nested table group join,
// but at least SQL Server doesn't like that, saying that the correlated columns can't be "bound"
// Since there is no dependency on the currentlyProcessingJoin, we can safely prepend this join
targetTableGroup.prependTableGroupJoin(currentlyProcessingJoin.getNavigablePath(), new TableGroupJoin(lateralTableGroup.getNavigablePath(), SqlAstJoinType.LEFT, lateralTableGroup));
}
parentFromClauseAccess.registerTableGroup(lateralTableGroup.getNavigablePath(), lateralTableGroup);
if (jdbcTypeCount == 1) {
return new SelfRenderingFunctionSqlAstExpression(pathName, (sqlAppender, sqlAstArguments, walker) -> {
sqlAstArguments.get(0).accept(walker);
}, resultColumnReferences, (ReturnableType<?>) resultColumnReferences.get(0).getJdbcMapping(), resultColumnReferences.get(0).getJdbcMapping());
} else {
return new SqlTuple(resultColumnReferences, modelPart);
}
} finally {
popProcessingStateStack();
}
}
final QueryPartTableReference tableReference = (QueryPartTableReference) lateralTableGroup.getPrimaryTableReference();
if (jdbcTypeCount == 1) {
final List<SqlSelection> sqlSelections = tableReference.getQueryPart().getFirstQuerySpec().getSelectClause().getSqlSelections();
return new SelfRenderingFunctionSqlAstExpression(pathName, (sqlAppender, sqlAstArguments, walker) -> {
sqlAstArguments.get(0).accept(walker);
}, Collections.singletonList(new ColumnReference(identifierVariable, tableReference.getColumnNames().get(0), false, null, null, sqlSelections.get(0).getExpressionType().getJdbcMappings().get(0), creationContext.getSessionFactory())), (ReturnableType<?>) sqlSelections.get(0).getExpressionType().getJdbcMappings().get(0), sqlSelections.get(0).getExpressionType());
} else {
final List<ColumnReference> resultColumnReferences = new ArrayList<>(jdbcTypeCount);
modelPart.forEachSelectable((selectionIndex, selectionMapping) -> resultColumnReferences.add(new ColumnReference(identifierVariable, tableReference.getColumnNames().get(selectionIndex), false, null, null, selectionMapping.getJdbcMapping(), creationContext.getSessionFactory())));
return new SqlTuple(resultColumnReferences, modelPart);
}
}
use of org.hibernate.metamodel.mapping.ModelPart in project hibernate-orm by hibernate.
the class EntityValuedPathInterpretation method from.
public static <T> EntityValuedPathInterpretation<T> from(NavigablePath navigablePath, TableGroup tableGroup, ModelPart resultModelPart, EntityValuedModelPart mapping, EntityValuedModelPart treatedMapping, SqmToSqlAstConverter sqlAstCreationState) {
final SqlExpressionResolver sqlExprResolver = sqlAstCreationState.getSqlExpressionResolver();
final SessionFactoryImplementor sessionFactory = sqlAstCreationState.getCreationContext().getSessionFactory();
final Expression sqlExpression;
if (resultModelPart == null) {
final EntityMappingType entityMappingType = mapping.getEntityMappingType();
final EntityIdentifierMapping identifierMapping = entityMappingType.getIdentifierMapping();
final EntityDiscriminatorMapping discriminatorMapping = entityMappingType.getDiscriminatorMapping();
final List<Expression> expressions = new ArrayList<>(entityMappingType.getJdbcTypeCount() + identifierMapping.getJdbcTypeCount() + (discriminatorMapping == null ? 0 : 1));
final TableGroup parentTableGroup = tableGroup;
final SelectableConsumer selectableConsumer = (selectionIndex, selectableMapping) -> {
final TableReference tableReference = parentTableGroup.resolveTableReference(navigablePath, selectableMapping.getContainingTableExpression(), false);
expressions.add(sqlExprResolver.resolveSqlExpression(createColumnReferenceKey(tableReference, selectableMapping.getSelectionExpression()), processingState -> new ColumnReference(tableReference, selectableMapping, sessionFactory)));
};
identifierMapping.forEachSelectable(selectableConsumer);
if (discriminatorMapping != null) {
discriminatorMapping.forEachSelectable(selectableConsumer);
}
entityMappingType.forEachSelectable(selectableConsumer);
sqlExpression = new SqlTuple(expressions, entityMappingType);
} else {
if (resultModelPart instanceof BasicValuedModelPart) {
final BasicValuedModelPart basicValuedModelPart = (BasicValuedModelPart) resultModelPart;
final TableReference tableReference = tableGroup.resolveTableReference(navigablePath, basicValuedModelPart.getContainingTableExpression());
sqlExpression = sqlExprResolver.resolveSqlExpression(createColumnReferenceKey(tableReference, basicValuedModelPart.getSelectionExpression()), processingState -> new ColumnReference(tableReference, basicValuedModelPart, sessionFactory));
} else {
final List<Expression> expressions = new ArrayList<>(resultModelPart.getJdbcTypeCount());
resultModelPart.forEachSelectable((selectionIndex, selectableMapping) -> {
final TableReference tableReference = tableGroup.resolveTableReference(navigablePath, selectableMapping.getContainingTableExpression());
expressions.add(sqlExprResolver.resolveSqlExpression(createColumnReferenceKey(tableReference, selectableMapping.getSelectionExpression()), processingState -> new ColumnReference(tableReference, selectableMapping, sessionFactory)));
});
sqlExpression = new SqlTuple(expressions, resultModelPart);
}
}
return new EntityValuedPathInterpretation<>(sqlExpression, navigablePath, tableGroup, treatedMapping);
}
Aggregations