use of org.hibernate.query.sqm.tree.domain.SqmTreatedPath in project hibernate-orm by hibernate.
the class SqmMappingModelHelper method resolveSqmPath.
private static ModelPart resolveSqmPath(SqmPath<?> sqmPath, MappingMetamodel domainModel, Function<NavigablePath, TableGroup> tableGroupLocator) {
if (sqmPath instanceof SqmTreatedPath) {
final SqmTreatedPath treatedPath = (SqmTreatedPath) sqmPath;
final EntityDomainType treatTargetType = treatedPath.getTreatTarget();
return domainModel.findEntityDescriptor(treatTargetType.getHibernateEntityName());
}
// see if the LHS is treated
if (sqmPath.getLhs() instanceof SqmTreatedPath) {
final SqmTreatedPath treatedPath = (SqmTreatedPath) sqmPath.getLhs();
final EntityDomainType treatTargetType = treatedPath.getTreatTarget();
final EntityPersister container = domainModel.findEntityDescriptor(treatTargetType.getHibernateEntityName());
return container.findSubPart(sqmPath.getNavigablePath().getLocalName(), container);
}
// Plural path parts are not joined and thus also have no table group
if (sqmPath instanceof AbstractSqmSpecificPluralPartPath<?>) {
final TableGroup lhsTableGroup = tableGroupLocator.apply(sqmPath.getLhs().getLhs().getNavigablePath());
final ModelPartContainer pluralPart = (ModelPartContainer) lhsTableGroup.getModelPart().findSubPart(sqmPath.getLhs().getReferencedPathSource().getPathName(), null);
final CollectionPart collectionPart = (CollectionPart) pluralPart.findSubPart(sqmPath.getReferencedPathSource().getPathName(), null);
// as that is the mapping type of the expression
if (collectionPart instanceof EntityCollectionPart) {
return ((EntityCollectionPart) collectionPart).getEntityMappingType();
}
return collectionPart;
}
if (sqmPath.getLhs() == null) {
final EntityDomainType<?> entityDomainType = (EntityDomainType<?>) sqmPath.getReferencedPathSource();
return domainModel.findEntityDescriptor(entityDomainType.getHibernateEntityName());
}
final TableGroup lhsTableGroup = tableGroupLocator.apply(sqmPath.getLhs().getNavigablePath());
final ModelPartContainer modelPart;
if (lhsTableGroup == null) {
modelPart = (ModelPartContainer) resolveSqmPath(sqmPath.getLhs(), domainModel, tableGroupLocator);
} else {
modelPart = lhsTableGroup.getModelPart();
}
return modelPart.findSubPart(sqmPath.getReferencedPathSource().getPathName(), null);
}
use of org.hibernate.query.sqm.tree.domain.SqmTreatedPath in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method findActualTableGroup.
private TableGroup findActualTableGroup(TableGroup lhsTableGroup, SqmPath<?> path) {
final SqmPathSource<?> intermediatePathSource;
final SqmPath<?> lhs;
if (path instanceof SqmTreatedPath<?, ?>) {
lhs = ((SqmTreatedPath<?, ?>) path).getWrappedPath().getLhs();
} else {
lhs = path.getLhs();
}
intermediatePathSource = lhs == null ? null : lhs.getReferencedPathSource().getIntermediatePathSource(path.getReferencedPathSource());
if (intermediatePathSource == null) {
return lhsTableGroup;
}
// The only possible intermediate path source for now is the element path source for plural attributes
assert intermediatePathSource.getPathName().equals(CollectionPart.Nature.ELEMENT.getName());
final PluralTableGroup pluralTableGroup = (PluralTableGroup) lhsTableGroup;
return pluralTableGroup.getElementTableGroup();
}
use of org.hibernate.query.sqm.tree.domain.SqmTreatedPath 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(SqlExpressionResolver.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.query.sqm.tree.domain.SqmTreatedPath in project hibernate-orm by hibernate.
the class BasicValuedPathInterpretation method from.
/**
* Static factory
*/
public static <T> BasicValuedPathInterpretation<T> from(SqmBasicValuedSimplePath<T> sqmPath, SqlAstCreationState sqlAstCreationState, SemanticQueryWalker sqmWalker, boolean jpaQueryComplianceEnabled) {
final FromClauseAccess fromClauseAccess = sqlAstCreationState.getFromClauseAccess();
final TableGroup tableGroup = fromClauseAccess.getTableGroup(sqmPath.getNavigablePath().getParent());
EntityMappingType treatTarget = null;
if (jpaQueryComplianceEnabled) {
if (sqmPath.getLhs() instanceof SqmTreatedPath) {
final EntityDomainType treatTargetDomainType = ((SqmTreatedPath) sqmPath.getLhs()).getTreatTarget();
final MappingMetamodel mappingMetamodel = sqlAstCreationState.getCreationContext().getSessionFactory().getRuntimeMetamodels().getMappingMetamodel();
treatTarget = mappingMetamodel.findEntityDescriptor(treatTargetDomainType.getHibernateEntityName());
} else if (sqmPath.getLhs().getNodeType() instanceof EntityDomainType) {
final EntityDomainType entityDomainType = (EntityDomainType) sqmPath.getLhs().getNodeType();
final MappingMetamodel mappingMetamodel = sqlAstCreationState.getCreationContext().getSessionFactory().getRuntimeMetamodels().getMappingMetamodel();
treatTarget = mappingMetamodel.findEntityDescriptor(entityDomainType.getHibernateEntityName());
}
}
final BasicValuedModelPart mapping = (BasicValuedModelPart) tableGroup.getModelPart().findSubPart(sqmPath.getReferencedPathSource().getPathName(), treatTarget);
if (mapping == null) {
if (jpaQueryComplianceEnabled) {
// to get the better error, see if we got nothing because of treat handling
final ModelPart subPart = tableGroup.getModelPart().findSubPart(sqmPath.getReferencedPathSource().getPathName(), null);
if (subPart != null) {
throw new StrictJpaComplianceViolation(StrictJpaComplianceViolation.Type.IMPLICIT_TREAT);
}
}
throw new SemanticException("`" + sqmPath.getNavigablePath().getFullPath() + "` did not reference a known model part");
}
final TableReference tableReference = tableGroup.resolveTableReference(sqmPath.getNavigablePath(), mapping.getContainingTableExpression());
final Expression expression = sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression(SqlExpressionResolver.createColumnReferenceKey(tableReference, mapping.getSelectionExpression()), sacs -> new ColumnReference(tableReference.getIdentificationVariable(), mapping, sqlAstCreationState.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);
}
return new BasicValuedPathInterpretation<>(columnReference, sqmPath.getNavigablePath(), mapping, tableGroup);
}
use of org.hibernate.query.sqm.tree.domain.SqmTreatedPath in project hibernate-orm by hibernate.
the class EmbeddableValuedPathInterpretation method from.
/**
* Static factory
*/
public static <T> EmbeddableValuedPathInterpretation<T> from(SqmEmbeddedValuedSimplePath<T> sqmPath, SqmToSqlAstConverter converter, SemanticQueryWalker sqmWalker, boolean jpaQueryComplianceEnabled) {
TableGroup tableGroup = converter.getFromClauseAccess().findTableGroup(sqmPath.getLhs().getNavigablePath());
EntityMappingType treatTarget = null;
if (jpaQueryComplianceEnabled) {
final MappingMetamodel mappingMetamodel = converter.getCreationContext().getSessionFactory().getRuntimeMetamodels().getMappingMetamodel();
if (sqmPath.getLhs() instanceof SqmTreatedPath) {
// noinspection rawtypes
final EntityDomainType<?> treatTargetDomainType = ((SqmTreatedPath) sqmPath.getLhs()).getTreatTarget();
treatTarget = mappingMetamodel.findEntityDescriptor(treatTargetDomainType.getHibernateEntityName());
} else if (sqmPath.getLhs().getNodeType() instanceof EntityDomainType) {
// noinspection rawtypes
final EntityDomainType<?> entityDomainType = (EntityDomainType) sqmPath.getLhs().getNodeType();
treatTarget = mappingMetamodel.findEntityDescriptor(entityDomainType.getHibernateEntityName());
}
}
final EmbeddableValuedModelPart mapping = (EmbeddableValuedModelPart) tableGroup.getModelPart().findSubPart(sqmPath.getReferencedPathSource().getPathName(), treatTarget);
return new EmbeddableValuedPathInterpretation<>(mapping.toSqlExpression(tableGroup, converter.getCurrentClauseStack().getCurrent(), converter, converter), sqmPath.getNavigablePath(), mapping, tableGroup);
}
Aggregations