use of org.hibernate.sql.ast.spi.FromClauseAccess 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() + "` 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.sql.ast.spi.FromClauseAccess in project hibernate-orm by hibernate.
the class ToOneAttributeMapping method createTableGroupJoin.
@Override
public TableGroupJoin createTableGroupJoin(NavigablePath navigablePath, TableGroup lhs, String explicitSourceAlias, SqlAstJoinType requestedJoinType, boolean fetched, boolean addsPredicate, SqlAliasBaseGenerator aliasBaseGenerator, SqlExpressionResolver sqlExpressionResolver, FromClauseAccess fromClauseAccess, SqlAstCreationContext creationContext) {
// This is vital for the map key property check that comes next
assert !(lhs instanceof PluralTableGroup);
final SqlAstJoinType joinType = requireNonNullElse(requestedJoinType, SqlAstJoinType.INNER);
// we check if this attribute is the map key property to reuse the existing index table group
if (!addsPredicate && (joinType == SqlAstJoinType.INNER || joinType == SqlAstJoinType.LEFT)) {
TableGroup parentTableGroup = lhs;
ModelPartContainer parentContainer = lhs.getModelPart();
StringBuilder embeddablePathSb = null;
// Traverse up embeddable table groups until we find a table group for a collection part
while (!(parentContainer instanceof CollectionPart)) {
if (parentContainer instanceof EmbeddableValuedModelPart) {
if (embeddablePathSb == null) {
embeddablePathSb = new StringBuilder();
}
embeddablePathSb.insert(0, parentContainer.getPartName() + ".");
parentTableGroup = fromClauseAccess.findTableGroup(parentTableGroup.getNavigablePath().getParent());
parentContainer = parentTableGroup.getModelPart();
} else {
break;
}
}
if (CollectionPart.Nature.ELEMENT.getName().equals(parentTableGroup.getNavigablePath().getLocalName())) {
final PluralTableGroup pluralTableGroup = (PluralTableGroup) fromClauseAccess.findTableGroup(parentTableGroup.getNavigablePath().getParent());
final String indexPropertyName = pluralTableGroup.getModelPart().getIndexMetadata().getIndexPropertyName();
final String pathName;
if (embeddablePathSb != null) {
pathName = embeddablePathSb.append(getAttributeName()).toString();
} else {
pathName = getAttributeName();
}
if (pathName.equals(indexPropertyName)) {
final TableGroup indexTableGroup = pluralTableGroup.getIndexTableGroup();
// If this is the map key property, we can reuse the index table group
initializeIfNeeded(lhs, requestedJoinType, indexTableGroup);
return new TableGroupJoin(navigablePath, joinType, new MappedByTableGroup(navigablePath, this, indexTableGroup, fetched, pluralTableGroup, (np, tableExpression) -> {
if (!canUseParentTableGroup) {
return false;
}
if (!identifyingColumnsTableExpression.equals(tableExpression)) {
return false;
}
if (navigablePath.equals(np.getParent())) {
return targetKeyPropertyNames.contains(np.getLocalName());
}
final String relativePath = np.relativize(navigablePath);
if (relativePath == null) {
return false;
}
return targetKeyPropertyNames.contains(relativePath);
}), null);
}
}
}
final LazyTableGroup lazyTableGroup = createRootTableGroupJoin(navigablePath, lhs, explicitSourceAlias, requestedJoinType, fetched, null, aliasBaseGenerator, sqlExpressionResolver, fromClauseAccess, creationContext);
final TableGroupJoin join = new TableGroupJoin(navigablePath, joinType, lazyTableGroup, null);
final TableReference lhsTableReference = lhs.resolveTableReference(navigablePath, identifyingColumnsTableExpression);
lazyTableGroup.setTableGroupInitializerCallback((tableGroup) -> join.applyPredicate(foreignKeyDescriptor.generateJoinPredicate(sideNature == ForeignKeyDescriptor.Nature.TARGET ? lhsTableReference : tableGroup.getPrimaryTableReference(), sideNature == ForeignKeyDescriptor.Nature.TARGET ? tableGroup.getPrimaryTableReference() : lhsTableReference, sqlExpressionResolver, creationContext)));
if (hasNotFoundAction()) {
getAssociatedEntityMappingType().applyWhereRestrictions(join::applyPredicate, lazyTableGroup.getTableGroup(), true, null);
}
return join;
}
use of org.hibernate.sql.ast.spi.FromClauseAccess in project hibernate-orm by hibernate.
the class ToOneAttributeMapping method generateFetch.
@Override
public EntityFetch generateFetch(FetchParent fetchParent, NavigablePath fetchablePath, FetchTiming fetchTiming, boolean selected, String resultVariable, DomainResultCreationState creationState) {
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
final FromClauseAccess fromClauseAccess = sqlAstCreationState.getFromClauseAccess();
final TableGroup parentTableGroup = fromClauseAccess.getTableGroup(fetchParent.getNavigablePath());
final NavigablePath parentNavigablePath = fetchablePath.getParent();
assert parentNavigablePath.equals(fetchParent.getNavigablePath()) || fetchParent.getNavigablePath() instanceof TreatedNavigablePath && parentNavigablePath.equals(fetchParent.getNavigablePath().getRealParent());
if ((hasNotFoundAction() || (fetchTiming == FetchTiming.IMMEDIATE && selected))) {
final TableGroup tableGroup = determineTableGroup(fetchablePath, fetchParent, parentTableGroup, resultVariable, fromClauseAccess, creationState);
return withRegisteredAssociationKeys(() -> {
final DomainResult<?> keyResult;
if (notFoundAction != null) {
if (sideNature == ForeignKeyDescriptor.Nature.KEY) {
keyResult = foreignKeyDescriptor.createKeyDomainResult(fetchablePath, parentTableGroup, fetchParent, creationState);
} else {
keyResult = foreignKeyDescriptor.createTargetDomainResult(fetchablePath, parentTableGroup, fetchParent, creationState);
}
} else {
keyResult = null;
}
return new EntityFetchJoinedImpl(fetchParent, this, tableGroup, keyResult, fetchablePath, creationState);
}, creationState);
}
/*
1. No JoinTable
Model:
EntityA{
@ManyToOne
EntityB b
}
EntityB{
@ManyToOne
EntityA a
}
Relational:
ENTITY_A( id )
ENTITY_B( id, entity_a_id)
1.1 EntityA -> EntityB : as keyResult we need ENTITY_B.id
1.2 EntityB -> EntityA : as keyResult we need ENTITY_B.entity_a_id (FK referring column)
2. JoinTable
*/
final ForeignKeyDescriptor.Nature resolvingKeySideOfForeignKey = creationState.getCurrentlyResolvingForeignKeyPart();
final ForeignKeyDescriptor.Nature side;
if (resolvingKeySideOfForeignKey == ForeignKeyDescriptor.Nature.KEY && this.sideNature == ForeignKeyDescriptor.Nature.TARGET) {
// If we are currently resolving the key part of a foreign key we do not want to add joins.
// So if the lhs of this association is the target of the FK, we have to use the KEY part to avoid a join
side = ForeignKeyDescriptor.Nature.KEY;
} else {
side = this.sideNature;
}
final DomainResult<?> keyResult = foreignKeyDescriptor.createDomainResult(fetchablePath, parentTableGroup, side, fetchParent, creationState);
final boolean selectByUniqueKey = isSelectByUniqueKey(side);
if (fetchTiming == FetchTiming.IMMEDIATE) {
return new EntityFetchSelectImpl(fetchParent, this, fetchablePath, keyResult, selectByUniqueKey, creationState);
}
return new EntityDelayedFetchImpl(fetchParent, this, fetchablePath, keyResult, selectByUniqueKey);
}
use of org.hibernate.sql.ast.spi.FromClauseAccess in project hibernate-orm by hibernate.
the class CollectionIdentifierDescriptorImpl method generateFetch.
@Override
public Fetch generateFetch(FetchParent fetchParent, NavigablePath fetchablePath, FetchTiming fetchTiming, boolean selected, String resultVariable, DomainResultCreationState creationState) {
// get the collection TableGroup
final FromClauseAccess fromClauseAccess = creationState.getSqlAstCreationState().getFromClauseAccess();
final TableGroup tableGroup = fromClauseAccess.getTableGroup(fetchablePath.getParent());
final SqlAstCreationState astCreationState = creationState.getSqlAstCreationState();
final SqlAstCreationContext astCreationContext = astCreationState.getCreationContext();
final SessionFactoryImplementor sessionFactory = astCreationContext.getSessionFactory();
final SqlExpressionResolver sqlExpressionResolver = astCreationState.getSqlExpressionResolver();
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(sqlExpressionResolver.resolveSqlExpression(SqlExpressionResolver.createColumnReferenceKey(tableGroup.getPrimaryTableReference(), columnName), p -> new ColumnReference(tableGroup.getPrimaryTableReference().getIdentificationVariable(), columnName, false, null, null, type, sessionFactory)), type.getJavaTypeDescriptor(), fetchParent, sessionFactory.getTypeConfiguration());
return new BasicFetch<>(sqlSelection.getValuesArrayPosition(), fetchParent, fetchablePath, this, null, FetchTiming.IMMEDIATE, creationState);
}
use of org.hibernate.sql.ast.spi.FromClauseAccess in project hibernate-orm by hibernate.
the class ConcreteSqmSelectQueryPlan method buildCacheableSqmInterpretation.
private static CacheableSqmInterpretation buildCacheableSqmInterpretation(SqmSelectStatement<?> sqm, DomainParameterXref domainParameterXref, DomainQueryExecutionContext executionContext) {
final SharedSessionContractImplementor session = executionContext.getSession();
final SessionFactoryImplementor sessionFactory = session.getFactory();
final QueryEngine queryEngine = sessionFactory.getQueryEngine();
final SqmTranslatorFactory sqmTranslatorFactory = queryEngine.getSqmTranslatorFactory();
final SqmTranslator<SelectStatement> sqmConverter = sqmTranslatorFactory.createSelectTranslator(sqm, executionContext.getQueryOptions(), domainParameterXref, executionContext.getQueryParameterBindings(), executionContext.getSession().getLoadQueryInfluencers(), sessionFactory, true);
// tableGroupAccess = sqmConverter.getFromClauseAccess();
final SqmTranslation<SelectStatement> sqmInterpretation = sqmConverter.translate();
final FromClauseAccess tableGroupAccess = sqmConverter.getFromClauseAccess();
final JdbcServices jdbcServices = sessionFactory.getJdbcServices();
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
final SqlAstTranslator<JdbcSelect> selectTranslator = sqlAstTranslatorFactory.buildSelectTranslator(sessionFactory, sqmInterpretation.getSqlAst());
final Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<List<JdbcParameter>>>> jdbcParamsXref = SqmUtil.generateJdbcParamsXref(domainParameterXref, sqmInterpretation::getJdbcParamsBySqmParam);
final JdbcParameterBindings jdbcParameterBindings = SqmUtil.createJdbcParameterBindings(executionContext.getQueryParameterBindings(), domainParameterXref, jdbcParamsXref, session.getFactory().getRuntimeMetamodels().getMappingMetamodel(), tableGroupAccess::findTableGroup, new SqmParameterMappingModelResolutionAccess() {
@Override
@SuppressWarnings("unchecked")
public <T> MappingModelExpressible<T> getResolvedMappingModelType(SqmParameter<T> parameter) {
return (MappingModelExpressible<T>) sqmInterpretation.getSqmParameterMappingModelTypeResolutions().get(parameter);
}
}, session);
final JdbcSelect jdbcSelect = selectTranslator.translate(jdbcParameterBindings, executionContext.getQueryOptions());
return new CacheableSqmInterpretation(sqmInterpretation.getSqlAst(), jdbcSelect, tableGroupAccess, jdbcParamsXref, sqmInterpretation.getSqmParameterMappingModelTypeResolutions(), jdbcParameterBindings);
}
Aggregations